Fix historical analyzer: division by zero + empty report output

Bug Reports from User:
1. "line 162: count * 100 / total: division by 0"
2. Empty report - no IP details displayed, only headers

Root Causes:

Issue 1: Division by Zero (line 162)
- show_progress() called with total="unknown"
- Attempted: count * 100 / "unknown" → division error
- Happened when processing logs of unknown size

Issue 2: Empty Report Output
- ALL echo statements used >> "$OUTPUT_FILE" inside { } block
- The { } > "$OUTPUT_FILE" already redirects EVERYTHING to file
- Using >> INSIDE redirected block caused output to go nowhere
- Result: Only headers written, no IP data

Example of broken code (lines 280-390):
{
    echo "Header"  # Goes to file 
    echo "Data" >> "$OUTPUT_FILE"  #  WRONG! Tries to append while already redirected
} > "$OUTPUT_FILE"

Fixes Applied:

1. show_progress() function (lines 159-168):
   Before:
     percent=$((count * 100 / total))  # Crashes if total="unknown"

   After:
     if [ "$total" = "unknown" ] || [ "$total" -eq 0 ]; then
         echo "Processing: $count lines..."  # No percentage
     else
         percent=$((count * 100 / total))   # Safe
     fi

2. Removed ALL >> "$OUTPUT_FILE" inside output block:
   - Used sed to remove 32 instances
   - Now all echo statements write to stdout
   - The { } > "$OUTPUT_FILE" captures everything correctly

Testing:
Before:
  - Division by zero error 
  - Empty report (no IP details) 

After:
  - No division errors 
  - Full report with IP details 
  - Syntax validated 

Impact:
- Report now displays complete IP analysis
- Shows attack types, sample URLs, reputation
- No more math errors during processing
This commit is contained in:
cschantz
2025-12-13 02:58:46 -05:00
parent ecde6dfe0c
commit b1437e1651
+40 -36
View File
@@ -157,10 +157,14 @@ declare -A IP_SAMPLE_URLS # Sample URLs per IP
# Progress indicator # Progress indicator
show_progress() { show_progress() {
count=$1 count=$1
total=$2 total=$2
percent=$((count * 100 / total)) if [ "$total" = "unknown" ] || [ "$total" -eq 0 ] 2>/dev/null; then
echo -ne "\r${BLUE}[*]${NC} Processing: $count/$total lines ($percent%) " echo -ne "\r${BLUE}[*]${NC} Processing: $count lines... "
else
percent=$((count * 100 / total))
echo -ne "\r${BLUE}[*]${NC} Processing: $count/$total lines ($percent%) "
fi
} }
# Start analysis # Start analysis
@@ -273,16 +277,16 @@ uri="${temp#*||}"
fi fi
done < <($CAT_CMD "$log_file" 2>/dev/null) done < <($CAT_CMD "$log_file" 2>/dev/null)
echo " → Found $file_attacks attacks" >> "$OUTPUT_FILE" echo " → Found $file_attacks attacks"
done done
echo "" >> "$OUTPUT_FILE" echo ""
echo "================================================================================ echo "================================================================================
" >> "$OUTPUT_FILE" "
echo "ATTACKING IPs - DETAILED BREAKDOWN" >> "$OUTPUT_FILE" echo "ATTACKING IPs - DETAILED BREAKDOWN"
echo "================================================================================ echo "================================================================================
" >> "$OUTPUT_FILE" "
echo "" >> "$OUTPUT_FILE" echo ""
# Sort IPs by cumulative threat score and display # Sort IPs by cumulative threat score and display
# Create sorted list first to avoid subshell issues # Create sorted list first to avoid subshell issues
@@ -327,9 +331,9 @@ uri="${temp#*||}"
fi fi
# Print IP summary # Print IP summary
echo "[$ip_count] $ip" >> "$OUTPUT_FILE" echo "[$ip_count] $ip"
printf " Attacks: %d | Avg Score: %d | Threat Level: %s\n" "$attack_count" "$avg_score" "$level" >> "$OUTPUT_FILE" printf " Attacks: %d | Avg Score: %d | Threat Level: %s\n" "$attack_count" "$avg_score" "$level"
echo " Attack Types: $attack_summary" >> "$OUTPUT_FILE" echo " Attack Types: $attack_summary"
# Get reputation (if available) # Get reputation (if available)
if type get_threat_intelligence &>/dev/null; then if type get_threat_intelligence &>/dev/null; then
@@ -337,53 +341,53 @@ uri="${temp#*||}"
if [ -n "$threat_intel" ]; then if [ -n "$threat_intel" ]; then
IFS='|' read -r abuse_conf abuse_rpts country isp geo timing whitelisted <<< "$threat_intel" IFS='|' read -r abuse_conf abuse_rpts country isp geo timing whitelisted <<< "$threat_intel"
if [ "${abuse_conf:-0}" -gt 0 ]; then 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" printf " Reputation: AbuseIPDB %d%% confidence (%d reports) | %s\n" "${abuse_conf:-0}" "${abuse_rpts:-0}" "${country:-Unknown}"
fi fi
fi fi
fi fi
# Show sample URLs # Show sample URLs
if [ -n "$sample_urls" ]; then if [ -n "$sample_urls" ]; then
echo " Sample Targets:" >> "$OUTPUT_FILE" echo " Sample Targets:"
IFS='||' read -ra urls <<< "$sample_urls" IFS='||' read -ra urls <<< "$sample_urls"
for url in "${urls[@]}"; do for url in "${urls[@]}"; do
echo " - $url" >> "$OUTPUT_FILE" echo " - $url"
done done
fi fi
echo "" >> "$OUTPUT_FILE" echo ""
done <<< "$sorted_ips" done <<< "$sorted_ips"
echo "================================================================================ echo "================================================================================
" >> "$OUTPUT_FILE" "
echo "SUMMARY STATISTICS" >> "$OUTPUT_FILE" echo "SUMMARY STATISTICS"
echo "================================================================================ echo "================================================================================
" >> "$OUTPUT_FILE" "
echo "" >> "$OUTPUT_FILE" echo ""
echo "Total lines processed: $TOTAL_LINES" >> "$OUTPUT_FILE" echo "Total lines processed: $TOTAL_LINES"
echo "Total attacks detected: $TOTAL_ATTACKS" >> "$OUTPUT_FILE" echo "Total attacks detected: $TOTAL_ATTACKS"
echo "Unique attacking IPs: ${#TOP_ATTACKERS[@]}" >> "$OUTPUT_FILE" echo "Unique attacking IPs: ${#TOP_ATTACKERS[@]}"
echo "" >> "$OUTPUT_FILE" echo ""
echo "Attack Severity:" >> "$OUTPUT_FILE" echo "Attack Severity:"
echo " - Critical (≥85): $CRITICAL_ATTACKS" >> "$OUTPUT_FILE" echo " - Critical (≥85): $CRITICAL_ATTACKS"
echo " - High (70-84): $HIGH_ATTACKS" >> "$OUTPUT_FILE" echo " - High (70-84): $HIGH_ATTACKS"
echo " - Medium (50-69): $MEDIUM_ATTACKS" >> "$OUTPUT_FILE" echo " - Medium (50-69): $MEDIUM_ATTACKS"
echo "" >> "$OUTPUT_FILE" echo ""
# Top Attack Types # Top Attack Types
echo "Top Attack Types:" >> "$OUTPUT_FILE" echo "Top Attack Types:"
for type in "${!ATTACK_TYPES[@]}"; do for type in "${!ATTACK_TYPES[@]}"; do
echo "$type:${ATTACK_TYPES[$type]}" echo "$type:${ATTACK_TYPES[$type]}"
done | sort -t: -k2 -nr | head -10 | 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" printf " %-20s %5d attacks\n" "$type" "$count"
done done
echo "" >> "$OUTPUT_FILE" echo ""
echo "================================================================================ echo "================================================================================
" >> "$OUTPUT_FILE" "
echo "END OF REPORT" >> "$OUTPUT_FILE" echo "END OF REPORT"
echo "================================================================================ echo "================================================================================
" >> "$OUTPUT_FILE" "
} > "$OUTPUT_FILE" } > "$OUTPUT_FILE"