#!/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 ""