Compare commits
6 Commits
cf362c2adf
...
43a94884e4
| Author | SHA1 | Date | |
|---|---|---|---|
| 43a94884e4 | |||
| da02dcfd61 | |||
| baf058d1dc | |||
| 1c3f12744b | |||
| 55dc21f6e5 | |||
| b0873bbf13 |
@@ -1036,7 +1036,7 @@ detect_threats() {
|
||||
|
||||
# Breakdown by attack type
|
||||
for attack_type in sqli xss path_traversal rce_upload info_disclosure login_bruteforce; do
|
||||
grep -F "|$attack_type" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | grep -F "|$attack_type$" | \
|
||||
grep -F "|$attack_type|" "$TEMP_DIR/attack_vectors_raw.txt" 2>/dev/null | \
|
||||
awk -F'|' '{print $1"|"$2"|"$3"|"$4}' | \
|
||||
sort | uniq -c | sort -rn > "$TEMP_DIR/${attack_type}_attempts.txt" || true
|
||||
done
|
||||
@@ -1219,6 +1219,7 @@ calculate_bot_fingerprint() {
|
||||
awk -F'|' -v tmpdir="$TEMP_DIR" '
|
||||
BEGIN {
|
||||
# Initialize tracking arrays
|
||||
fingerprint_file = tmpdir "/bot_fingerprints.txt"
|
||||
}
|
||||
{
|
||||
ip = $1
|
||||
@@ -1306,10 +1307,10 @@ calculate_bot_fingerprint() {
|
||||
|
||||
# Output fingerprint for high-confidence bots (score >= 60)
|
||||
if (score >= 60) {
|
||||
printf "%s|%d|%d\n", ip, score, signal_count > tmpdir "/bot_fingerprints.txt"
|
||||
printf "%s|%d|%d\n", ip, score, signal_count > fingerprint_file
|
||||
}
|
||||
}
|
||||
close(tmpdir "/bot_fingerprints.txt")
|
||||
close(fingerprint_file)
|
||||
}
|
||||
' < "$TEMP_DIR/parsed_logs.txt" 2>/dev/null || true
|
||||
|
||||
@@ -1356,7 +1357,7 @@ analyze_domain_targeting_percentage() {
|
||||
# Also create per-domain attack type breakdown
|
||||
# Format: domain|attack_type|ip|count
|
||||
if [ -f "$TEMP_DIR/attack_vectors_raw.txt" ]; then
|
||||
awk -F'|' '
|
||||
awk -F'|' -v tmpdir="$TEMP_DIR" '
|
||||
{
|
||||
ip = $1
|
||||
domain = $2
|
||||
@@ -1368,7 +1369,6 @@ analyze_domain_targeting_percentage() {
|
||||
}
|
||||
END {
|
||||
for (domain in attack_data) {
|
||||
domain_file = tmpdir "/domain_attacks_" domain ".txt"
|
||||
for (attack_type in attack_data[domain]) {
|
||||
total = attack_totals[domain][attack_type]
|
||||
for (ip in attack_data[domain][attack_type]) {
|
||||
@@ -1378,7 +1378,7 @@ analyze_domain_targeting_percentage() {
|
||||
}
|
||||
}
|
||||
}
|
||||
' -v tmpdir="$TEMP_DIR" < "$TEMP_DIR/attack_vectors_raw.txt"
|
||||
' < "$TEMP_DIR/attack_vectors_raw.txt"
|
||||
fi
|
||||
|
||||
print_success "Domain attack pattern analysis complete"
|
||||
@@ -1608,11 +1608,9 @@ is_excluded_ip() {
|
||||
return 0 # True - should be excluded
|
||||
fi
|
||||
|
||||
# Check if it's the server's own IP
|
||||
if [ -f "$TEMP_DIR/server_ips.txt" ]; then
|
||||
if grep -qFx "$ip" "$TEMP_DIR/server_ips.txt" 2>/dev/null; then
|
||||
return 0 # True - should be excluded
|
||||
fi
|
||||
# Check if it's the server's own IP (using pre-loaded array for speed)
|
||||
if [ -n "${server_ips_array[$ip]}" ]; then
|
||||
return 0 # True - should be excluded
|
||||
fi
|
||||
|
||||
return 1 # False - should not be excluded
|
||||
@@ -1656,45 +1654,62 @@ analyze_time_series() {
|
||||
calculate_threat_scores() {
|
||||
print_info "Calculating threat scores..."
|
||||
|
||||
# Pre-count requests per IP (MUCH faster than grepping for each IP)
|
||||
# Pre-load server IPs for fast exclusion checking (avoids grep in loop)
|
||||
declare -A server_ips_array
|
||||
if [ -f "$TEMP_DIR/server_ips.txt" ]; then
|
||||
while read -r ip; do
|
||||
[ -n "$ip" ] && server_ips_array["$ip"]=1
|
||||
done < "$TEMP_DIR/server_ips.txt"
|
||||
fi
|
||||
|
||||
# Pre-count requests per IP using mapfile (faster than while-read on large files)
|
||||
declare -A ip_request_counts
|
||||
while IFS='|' read -r ip rest; do
|
||||
mapfile -t parsed_lines < "$TEMP_DIR/parsed_logs.txt"
|
||||
for line in "${parsed_lines[@]}"; do
|
||||
ip="${line%%|*}"
|
||||
((ip_request_counts["$ip"]++))
|
||||
done < "$TEMP_DIR/parsed_logs.txt"
|
||||
done
|
||||
|
||||
# Build hash tables from threat files for O(1) lookups
|
||||
# OPTIMIZATION: Use awk instead of echo|awk|cut in loops (10x faster)
|
||||
declare -A threat_ips_sqli threat_ips_xss threat_ips_path threat_ips_rce threat_ips_login
|
||||
declare -A threat_ips_suspicious threat_ips_ddos threat_admin_count threat_404_count
|
||||
|
||||
# Parse each threat file and build hash tables (optimized with awk)
|
||||
[ -f "$TEMP_DIR/sqli_attempts.txt" ] && while read -r ip; do
|
||||
threat_ips_sqli["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/sqli_attempts.txt" | cut -d'|' -f1)
|
||||
# Parse each threat file and build hash tables (using mapfile to avoid subshells)
|
||||
if [ -f "$TEMP_DIR/sqli_attempts.txt" ]; then
|
||||
mapfile -t sqli_ips < <(awk '{print $2}' "$TEMP_DIR/sqli_attempts.txt" | cut -d'|' -f1)
|
||||
for ip in "${sqli_ips[@]}"; do threat_ips_sqli["$ip"]=1; done
|
||||
fi
|
||||
|
||||
[ -f "$TEMP_DIR/xss_attempts.txt" ] && while read -r ip; do
|
||||
threat_ips_xss["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/xss_attempts.txt" | cut -d'|' -f1)
|
||||
if [ -f "$TEMP_DIR/xss_attempts.txt" ]; then
|
||||
mapfile -t xss_ips < <(awk '{print $2}' "$TEMP_DIR/xss_attempts.txt" | cut -d'|' -f1)
|
||||
for ip in "${xss_ips[@]}"; do threat_ips_xss["$ip"]=1; done
|
||||
fi
|
||||
|
||||
[ -f "$TEMP_DIR/path_traversal_attempts.txt" ] && while read -r ip; do
|
||||
threat_ips_path["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/path_traversal_attempts.txt" | cut -d'|' -f1)
|
||||
if [ -f "$TEMP_DIR/path_traversal_attempts.txt" ]; then
|
||||
mapfile -t path_ips < <(awk '{print $2}' "$TEMP_DIR/path_traversal_attempts.txt" | cut -d'|' -f1)
|
||||
for ip in "${path_ips[@]}"; do threat_ips_path["$ip"]=1; done
|
||||
fi
|
||||
|
||||
[ -f "$TEMP_DIR/rce_upload_attempts.txt" ] && while read -r ip; do
|
||||
threat_ips_rce["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/rce_upload_attempts.txt" | cut -d'|' -f1)
|
||||
if [ -f "$TEMP_DIR/rce_upload_attempts.txt" ]; then
|
||||
mapfile -t rce_ips < <(awk '{print $2}' "$TEMP_DIR/rce_upload_attempts.txt" | cut -d'|' -f1)
|
||||
for ip in "${rce_ips[@]}"; do threat_ips_rce["$ip"]=1; done
|
||||
fi
|
||||
|
||||
[ -f "$TEMP_DIR/login_bruteforce_attempts.txt" ] && while read -r ip; do
|
||||
threat_ips_login["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/login_bruteforce_attempts.txt" | cut -d'|' -f1)
|
||||
if [ -f "$TEMP_DIR/login_bruteforce_attempts.txt" ]; then
|
||||
mapfile -t login_ips < <(awk '{print $2}' "$TEMP_DIR/login_bruteforce_attempts.txt" | cut -d'|' -f1)
|
||||
for ip in "${login_ips[@]}"; do threat_ips_login["$ip"]=1; done
|
||||
fi
|
||||
|
||||
[ -f "$TEMP_DIR/suspicious_ua.txt" ] && while read -r ip; do
|
||||
threat_ips_suspicious["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/suspicious_ua.txt" | cut -d'|' -f1)
|
||||
if [ -f "$TEMP_DIR/suspicious_ua.txt" ]; then
|
||||
mapfile -t susp_ips < <(awk '{print $2}' "$TEMP_DIR/suspicious_ua.txt" | cut -d'|' -f1)
|
||||
for ip in "${susp_ips[@]}"; do threat_ips_suspicious["$ip"]=1; done
|
||||
fi
|
||||
|
||||
[ -f "$TEMP_DIR/rapid_fire_ips.txt" ] && while read -r ip; do
|
||||
threat_ips_ddos["$ip"]=1
|
||||
done < <(awk '{print $2}' "$TEMP_DIR/rapid_fire_ips.txt")
|
||||
if [ -f "$TEMP_DIR/rapid_fire_ips.txt" ]; then
|
||||
mapfile -t ddos_ips < <(awk '{print $2}' "$TEMP_DIR/rapid_fire_ips.txt")
|
||||
for ip in "${ddos_ips[@]}"; do threat_ips_ddos["$ip"]=1; done
|
||||
fi
|
||||
|
||||
# Parse count-based threat files
|
||||
[ -f "$TEMP_DIR/admin_probes.txt" ] && while read -r count ip; do
|
||||
|
||||
Reference in New Issue
Block a user