diff --git a/tools/analyze-historical-attacks.sh b/tools/analyze-historical-attacks.sh index e113935..2071709 100755 --- a/tools/analyze-historical-attacks.sh +++ b/tools/analyze-historical-attacks.sh @@ -26,6 +26,9 @@ source "$SCRIPT_DIR/lib/http-attack-analyzer.sh" 2>/dev/null || { exit 1 } +# Try to source IP reputation library (optional) +source "$SCRIPT_DIR/lib/ip-reputation.sh" 2>/dev/null + # Colors RED='\033[0;31m' YELLOW='\033[1;33m' @@ -148,6 +151,9 @@ MEDIUM_ATTACKS=0 declare -A ATTACK_TYPES declare -A TOP_ATTACKERS declare -A SIGNATURE_HITS +declare -A IP_ATTACK_DETAILS # Store detailed attack info per IP +declare -A IP_ATTACK_COUNT # Count attacks per IP +declare -A IP_SAMPLE_URLS # Sample URLs per IP # Progress indicator show_progress() { @@ -231,22 +237,36 @@ uri="${temp#*||}" ATTACK_TYPES["$type"]=$((${ATTACK_TYPES[$type]:-0} + 1)) done - # Track top attackers + # Track top attackers (cumulative score) TOP_ATTACKERS["$ip"]=$((${TOP_ATTACKERS[$ip]:-0} + threat_score)) + # Track attack count per IP + IP_ATTACK_COUNT["$ip"]=$((${IP_ATTACK_COUNT[$ip]:-0} + 1)) + + # Store attack type details per IP + current_types="${IP_ATTACK_DETAILS[$ip]}" + if [ -z "$current_types" ]; then + IP_ATTACK_DETAILS["$ip"]="$attack_types" + else + IP_ATTACK_DETAILS["$ip"]="$current_types,$attack_types" + fi + + # Store sample URL (keep first 3) + current_urls="${IP_SAMPLE_URLS[$ip]}" + url_count=$(echo "$current_urls" | grep -o "||" | wc -l) + if [ "$url_count" -lt 3 ]; then + if [ -z "$current_urls" ]; then + IP_SAMPLE_URLS["$ip"]="${uri:0:100}" + else + IP_SAMPLE_URLS["$ip"]="$current_urls||${uri:0:100}" + fi + fi + # Track signatures IFS=',' read -ra sigs <<< "$signatures" for sig in "${sigs[@]}"; do SIGNATURE_HITS["$sig"]=$((${SIGNATURE_HITS[$sig]:-0} + 1)) done - - # Log if verbose or critical - if [ "$VERBOSE" -eq 1 ] || [ "$threat_score" -ge 85 ]; then - echo "" >> "$OUTPUT_FILE" - echo "[Score: $threat_score] $ip → $attack_types" >> "$OUTPUT_FILE" - echo " URI: ${uri:0:150}" >> "$OUTPUT_FILE" - echo " Signatures: $signatures" >> "$OUTPUT_FILE" - fi fi done < <($CAT_CMD "$log_file" 2>/dev/null) @@ -254,6 +274,83 @@ uri="${temp#*||}" done echo "" >> "$OUTPUT_FILE" + echo "================================================================================ +" >> "$OUTPUT_FILE" + echo "ATTACKING IPs - DETAILED BREAKDOWN" >> "$OUTPUT_FILE" + echo "================================================================================ +" >> "$OUTPUT_FILE" + echo "" >> "$OUTPUT_FILE" + + # Sort IPs by cumulative threat score and display + # Create sorted list first to avoid subshell issues + sorted_ips=$(for ip in "${!TOP_ATTACKERS[@]}"; do + echo "${TOP_ATTACKERS[$ip]}:$ip" + done | sort -t: -k1 -nr | head -50) + + ip_count=0 + while IFS=: read -r cumulative_score ip; do + ip_count=$((ip_count + 1)) + + attack_count="${IP_ATTACK_COUNT[$ip]:-0}" + all_attack_types="${IP_ATTACK_DETAILS[$ip]}" + sample_urls="${IP_SAMPLE_URLS[$ip]}" + + # Count occurrences of each attack type + declare -A type_counts + IFS=',' read -ra attacks <<< "$all_attack_types" + for attack in "${attacks[@]}"; do + [ -n "$attack" ] && type_counts["$attack"]=$((${type_counts[$attack]:-0} + 1)) + done + + # Format attack summary + attack_summary="" + for type in "${!type_counts[@]}"; do + if [ -z "$attack_summary" ]; then + attack_summary="$type(${type_counts[$type]})" + else + attack_summary="$attack_summary, $type(${type_counts[$type]})" + fi + done + unset type_counts + + # Determine threat level + avg_score=$((cumulative_score / attack_count)) + if [ "$avg_score" -ge 85 ]; then + level="CRITICAL" + elif [ "$avg_score" -ge 70 ]; then + level="HIGH" + else + level="MEDIUM" + fi + + # Print IP summary + echo "[$ip_count] $ip" >> "$OUTPUT_FILE" + printf " Attacks: %d | Avg Score: %d | Threat Level: %s\n" "$attack_count" "$avg_score" "$level" >> "$OUTPUT_FILE" + echo " Attack Types: $attack_summary" >> "$OUTPUT_FILE" + + # Get reputation (if available) + if type get_threat_intelligence &>/dev/null; then + threat_intel=$(get_threat_intelligence "$ip" 2>/dev/null) + if [ -n "$threat_intel" ]; then + IFS='|' read -r abuse_conf abuse_rpts country isp geo timing whitelisted <<< "$threat_intel" + if [ "${abuse_conf:-0}" -gt 0 ]; then + printf " Reputation: AbuseIPDB %d%% confidence (%d reports) | %s\n" "${abuse_conf:-0}" "${abuse_rpts:-0}" "${country:-Unknown}" >> "$OUTPUT_FILE" + fi + fi + fi + + # Show sample URLs + if [ -n "$sample_urls" ]; then + echo " Sample Targets:" >> "$OUTPUT_FILE" + IFS='||' read -ra urls <<< "$sample_urls" + for url in "${urls[@]}"; do + echo " - $url" >> "$OUTPUT_FILE" + done + fi + + echo "" >> "$OUTPUT_FILE" + done <<< "$sorted_ips" + echo "================================================================================ " >> "$OUTPUT_FILE" echo "SUMMARY STATISTICS" >> "$OUTPUT_FILE" @@ -262,6 +359,9 @@ uri="${temp#*||}" echo "" >> "$OUTPUT_FILE" echo "Total lines processed: $TOTAL_LINES" >> "$OUTPUT_FILE" echo "Total attacks detected: $TOTAL_ATTACKS" >> "$OUTPUT_FILE" + echo "Unique attacking IPs: ${#TOP_ATTACKERS[@]}" >> "$OUTPUT_FILE" + echo "" >> "$OUTPUT_FILE" + echo "Attack Severity:" >> "$OUTPUT_FILE" echo " - Critical (≥85): $CRITICAL_ATTACKS" >> "$OUTPUT_FILE" echo " - High (70-84): $HIGH_ATTACKS" >> "$OUTPUT_FILE" echo " - Medium (50-69): $MEDIUM_ATTACKS" >> "$OUTPUT_FILE" @@ -271,29 +371,11 @@ uri="${temp#*||}" echo "Top Attack Types:" >> "$OUTPUT_FILE" for type in "${!ATTACK_TYPES[@]}"; do echo "$type:${ATTACK_TYPES[$type]}" - done | sort -t: -k2 -nr | head -15 | while IFS=: read -r type count; do + done | sort -t: -k2 -nr | head -10 | while IFS=: read -r type count; do printf " %-20s %5d attacks\n" "$type" "$count" >> "$OUTPUT_FILE" done echo "" >> "$OUTPUT_FILE" - # Top Attackers - echo "Top 20 Attacking IPs (by cumulative threat score):" >> "$OUTPUT_FILE" - for ip in "${!TOP_ATTACKERS[@]}"; do - echo "$ip:${TOP_ATTACKERS[$ip]}" - done | sort -t: -k2 -nr | head -20 | while IFS=: read -r ip score; do - printf " %-15s Score: %5d\n" "$ip" "$score" >> "$OUTPUT_FILE" - done - echo "" >> "$OUTPUT_FILE" - - # Top Signatures - echo "Top 20 Triggered Signatures:" >> "$OUTPUT_FILE" - for sig in "${!SIGNATURE_HITS[@]}"; do - echo "$sig:${SIGNATURE_HITS[$sig]}" - done | sort -t: -k2 -nr | head -20 | while IFS=: read -r sig count; do - printf " %-30s %5d hits\n" "$sig" "$count" >> "$OUTPUT_FILE" - done - echo "" >> "$OUTPUT_FILE" - echo "================================================================================ " >> "$OUTPUT_FILE" echo "END OF REPORT" >> "$OUTPUT_FILE"