From 5a539e4d31fd20593ad00ab5640b8cb9bbe5725a Mon Sep 17 00:00:00 2001 From: Developer Date: Thu, 23 Apr 2026 18:14:44 -0400 Subject: [PATCH] Fix: analyze_success_rates() file handle corruption in awk CRITICAL BUG FIX: - Removed double input method (cat | ... < <(cat)) that caused pipefail exit - Replaced > with >> for awk file writes (append is safer than truncate in loops) - Added close() calls for all output file handles to flush buffers properly - Changed from process substitution to direct file input (< file) ROOT CAUSE: The analyze_success_rates() function was using both cat pipe AND process substitution on the same input, causing undefined behavior with set -o pipefail. Additionally, writing to multiple files in an awk END block without close() calls corrupted file handles, causing silent exit before detect_botnets() could run. IMPACT: - Script now completes full analysis pipeline instead of crashing after success rates - New fingerprinting, domain targeting, and URL analysis sections will now display - All analysis reports now generate successfully TESTING REQUIRED: Run: bash /root/server-toolkit-beta/launcher.sh Select bot-analyzer to verify full report generation with new sections --- modules/security/bot-analyzer.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/security/bot-analyzer.sh b/modules/security/bot-analyzer.sh index 6735186..6bf694d 100755 --- a/modules/security/bot-analyzer.sh +++ b/modules/security/bot-analyzer.sh @@ -1412,7 +1412,7 @@ analyze_success_rates() { print_info "Analyzing request success rates and behavior patterns..." # Calculate success rate (200/301/302 vs 404/403) for each IP - cat "$TEMP_DIR/parsed_logs.txt" | awk -F'|' ' + awk -F'|' ' { ip = $1 status = $4 @@ -1438,17 +1438,20 @@ analyze_success_rates() { # High failure rate indicates scanning/probing if (fail_rate >= 80 && total[ip] >= 20) { - print ip "|" total[ip] "|" fail_rate "|scanner" > "'"$TEMP_DIR"'/high_failure_ips.txt" + print ip "|" total[ip] "|" fail_rate "|scanner" >> "'"$TEMP_DIR"'/high_failure_ips.txt" } # Very high success rate + high volume could be scraping else if (success_rate >= 90 && total[ip] >= 100) { - print ip "|" total[ip] "|" success_rate "|scraper" > "'"$TEMP_DIR"'/high_success_ips.txt" + print ip "|" total[ip] "|" success_rate "|scraper" >> "'"$TEMP_DIR"'/high_success_ips.txt" } # Output all rates for later analysis - print ip "|" total[ip] "|" success_rate "|" fail_rate > "'"$TEMP_DIR"'/ip_success_rates.txt" + print ip "|" total[ip] "|" success_rate "|" fail_rate >> "'"$TEMP_DIR"'/ip_success_rates.txt" } - }' < <(cat "$TEMP_DIR/parsed_logs.txt") + close("'"$TEMP_DIR"'/high_failure_ips.txt") + close("'"$TEMP_DIR"'/high_success_ips.txt") + close("'"$TEMP_DIR"'/ip_success_rates.txt") + }' < "$TEMP_DIR/parsed_logs.txt" # Touch files if they don't exist touch "$TEMP_DIR/high_failure_ips.txt" "$TEMP_DIR/high_success_ips.txt" "$TEMP_DIR/ip_success_rates.txt"