diff --git a/scan-batch.sh b/scan-batch.sh new file mode 100755 index 0000000..2c5f145 --- /dev/null +++ b/scan-batch.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env bash +# The Analyzer — Daily Batch Scanner +# Reads target list and scans each site in quick mode +# Logs progress and generates reports + +set -euo pipefail + +ANALYZER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ANALYZER="$ANALYZER_DIR/analyzer" +TARGETS="$ANALYZER_DIR/targets/top50.txt" +REPORTS="$ANALYZER_DIR/reports" +LOG="$ANALYZER_DIR/targets/batch.log" +TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') + +# Config +OLLAMA_HOST="${OLLAMA_HOST:-http://10.30.20.110:11434}" +OLLAMA_MODEL="${OLLAMA_MODEL:-granite4.1:8b}" +MAX_SCAN_TIME=180 # 3 min max per target +SUMMARY_ONLY=false + +# Parse args +for arg in "$@"; do + case "$arg" in + --summary) SUMMARY_ONLY=true ;; + --help) + echo "Usage: $0 [--summary]" + echo " --summary Show last scan results without running" + exit 0 + ;; + esac +done + +mkdir -p "$ANALYZER_DIR/targets" + +if [ "$SUMMARY_ONLY" = true ]; then + echo "" + echo "╔═══════════════════════════════════════════════╗" + echo "║ BATCH SCAN SUMMARY — Last Run ║" + echo "╚═══════════════════════════════════════════════╝" + echo "" + if [ -f "$LOG" ]; then + tail -60 "$LOG" + else + echo "No batch runs yet." + fi + exit 0 +fi + +echo "" +echo "╔═══════════════════════════════════════════════╗" +echo "║ THE ANALYZER — Daily Batch Scan ║" +echo "║ $TIMESTAMP ║" +echo "╚═══════════════════════════════════════════════╝" +echo "" + +# Check target file +if [ ! -f "$TARGETS" ]; then + echo "❌ Target list not found: $TARGETS" + exit 1 +fi + +# Count targets +TOTAL=$(grep -cve '^\s*#' -e '^\s*$' "$TARGETS") +echo " 🎯 Targets loaded: $TOTAL" +echo " ⚡ Mode: Quick Scan" +echo " 🧠 Ollama: $OLLAMA_HOST / $OLLAMA_MODEL" +echo "" + +# Read targets (shuffle with perl for macOS compat) +SITES=() +while IFS= read -r line; do + SITES+=("$line") +done < <(grep -ve '^\s*#' -e '^\s*$' "$TARGETS" | perl -MList::Util=shuffle -e 'print shuffle(<>);') + +# Progress tracking +COMPLETED=0 +FOUND=0 +FAILED=0 +START_TIME=$(date +%s) + +# Log header +{ + echo "" + echo "═══ BATCH RUN: $TIMESTAMP ═══" + echo "Total targets: $TOTAL" +} >> "$LOG" + +for SITE in "${SITES[@]}"; do + SITE=$(echo "$SITE" | xargs) # trim + [ -z "$SITE" ] && continue + + # Add protocol if missing + [[ "$SITE" != http* ]] && SITE="https://$SITE" + + COMPLETED=$((COMPLETED + 1)) + DOMAIN=$(echo "$SITE" | sed 's|https\?://||' | cut -d/ -f1) + + echo "" + echo " ── [$COMPLETED/$TOTAL] $DOMAIN ──" + + # Log start + echo "[$(date '+%H:%M')] SCANNING $DOMAIN..." >> "$LOG" + + # Run scan with timeout (portable: perl-based) + SCAN_START=$(date +%s) + SCAN_OUTPUT=$(perl -e 'alarm shift; exec @ARGV' $MAX_SCAN_TIME bash -c " + cd '$ANALYZER_DIR' + OLLAMA_HOST='$OLLAMA_HOST' OLLAMA_MODEL='$OLLAMA_MODEL' '$ANALYZER' '$SITE' quick 2>&1 + " 2>&1 || true) + SCAN_END=$(date +%s) + SCAN_TIME=$((SCAN_END - SCAN_START)) + + # Check for findings + if echo "$SCAN_OUTPUT" | grep -q "💥\|vulnerabilities\|SQLi\|XSS\|LFI\|CRITICAL\|HIGH"; then + FOUND=$((FOUND + 1)) + echo " 💥 FINDINGS on $DOMAIN" + + # Extract finding lines for logging + FINDINGS=$(echo "$SCAN_OUTPUT" | grep "💥\|🔴\|🟠\|findings\|vulnerabilit") + + # Log findings + echo "[$(date '+%H:%M')] FINDINGS on $DOMAIN" >> "$LOG" + echo "$FINDINGS" >> "$LOG" + + # Print findings + echo "$FINDINGS" | while IFS= read -r line; do + [ -n "$line" ] && echo " $line" + done + else + echo " ✅ No findings (${SCAN_TIME}s)" + echo "[$(date '+%H:%M')] CLEAN $DOMAIN (${SCAN_TIME}s)" >> "$LOG" + fi + + # Small delay between scans + sleep 2 +done + +# Summary +END_TIME=$(date +%s) +TOTAL_TIME=$((END_TIME - START_TIME)) +HOURS=$((TOTAL_TIME / 3600)) +MINS=$(((TOTAL_TIME % 3600) / 60)) + +echo "" +echo "╔═══════════════════════════════════════════════╗" +echo "║ BATCH COMPLETE ║" +echo "╚═══════════════════════════════════════════════╝" +echo "" +echo " 📊 Stats:" +echo " Total: $TOTAL" +echo " Scanned: $COMPLETED" +echo " Found: $FOUND sites with findings" +echo " Time: ${HOURS}h ${MINS}m" +echo "" + +# Log summary +{ + echo "═══ BATCH COMPLETE ═══" + echo "Scanned: $COMPLETED | With findings: $FOUND | Time: ${HOURS}h ${MINS}m" + echo "" +} >> "$LOG" + +# Print latest report +echo " 📄 Latest reports:" +ls -lt "$REPORTS"/*.md 2>/dev/null | head -5 | while IFS= read -r r; do + echo " $r" +done +echo "" +echo " View full log: $LOG" +echo "" diff --git a/targets/batch.log b/targets/batch.log new file mode 100644 index 0000000..096fc29 --- /dev/null +++ b/targets/batch.log @@ -0,0 +1,4 @@ + +═══ BATCH RUN: 2026-06-20 15:09:19 ═══ +Total targets: 50 +[15:09] SCANNING https:... diff --git a/targets/top50.txt b/targets/top50.txt new file mode 100644 index 0000000..66a10fa --- /dev/null +++ b/targets/top50.txt @@ -0,0 +1,57 @@ +# Top 50 Most Popular Websites — Scan Targets +# Used by daily cron for The Analyzer +# Sourced from public top-site rankings +# Authorized for bug bounty / security research use +# +# Format: one URL per line (no protocol prefix = https:// added automatically) + +google.com +youtube.com +facebook.com +twitter.com +instagram.com +linkedin.com +reddit.com +wikipedia.org +amazon.com +netflix.com +tiktok.com +twitch.tv +spotify.com +github.com +stackoverflow.com +apple.com +microsoft.com +zoom.us +office.com +live.com +bing.com +whatsapp.com +telegram.org +discord.com +pinterest.com +ebay.com +walmart.com +target.com +imdb.com +quora.com +medium.com +wordpress.com +adobe.com +salesforce.com +dropbox.com +indeed.com +craigslist.org +expedia.com +airbnb.com +udemy.com +coursera.org +nytimes.com +cnn.com +bbc.com +foxnews.com +reuters.com +weather.com +yelp.com +tripadvisor.com +paypal.com