From 488d36d1d12998dafa03ef4c576c8fd92f975d94 Mon Sep 17 00:00:00 2001 From: cschantz Date: Tue, 11 Nov 2025 18:50:48 -0500 Subject: [PATCH] Add automated multi-scanner support and result comparison New Features: - 'All Available Scanners' option in all scan modes (server/user/domain/custom) - Runs ImunifyAV, ClamAV, and Maldet sequentially with progress tracking - Creates consolidated multi-scanner session reports - Shows [1/3], [2/3], [3/3] progress indicators - 3-second wait between scanners to prevent system overload - Session reports saved to logs/malware-scans/multiscan_*.txt - Stores session IDs in reference database for cross-module access - New 'Compare scanner results' option (menu option 6) - View consolidated reports from multiple scanners Workflow: 1. Select any scan scope (server/user/domain/path) 2. Choose 'All Available Scanners' option 3. All installed scanners run automatically one after another 4. Single consolidated report with all results 5. Use option 6 to compare/view latest multi-scanner session Much more automated - no need to run each scanner separately! --- modules/security/malware-scanner.sh | 226 +++++++++++++++++++++++----- 1 file changed, 188 insertions(+), 38 deletions(-) diff --git a/modules/security/malware-scanner.sh b/modules/security/malware-scanner.sh index 9070885..331125c 100755 --- a/modules/security/malware-scanner.sh +++ b/modules/security/malware-scanner.sh @@ -299,6 +299,137 @@ scan_maldet() { echo " maldet -l" } +# Run all available scanners sequentially +run_all_scanners() { + local scan_paths=("$@") + + if [ ${#scan_paths[@]} -eq 0 ]; then + echo -e "${RED}No paths to scan${NC}" + return 1 + fi + + # Create session ID for this multi-scanner run + local session_id="multiscan_$(date +%Y%m%d_%H%M%S)" + local report_file="$SCRIPT_DIR/logs/malware-scans/${session_id}_summary.txt" + mkdir -p "$SCRIPT_DIR/logs/malware-scans" + + echo "" + print_header "Multi-Scanner Session: $session_id" + + echo "Running ${#available_scanners[@]} scanner(s) on ${#scan_paths[@]} path(s)" + echo "Session report: $report_file" + echo "" + + # Initialize report + { + echo "==========================================" + echo "Multi-Scanner Malware Detection Report" + echo "==========================================" + echo "Session ID: $session_id" + echo "Date: $(date)" + echo "Scanners: ${available_scanners[*]}" + echo "Paths: ${#scan_paths[@]}" + echo "" + printf '%s\n' "${scan_paths[@]}" + echo "" + echo "==========================================" + echo "" + } > "$report_file" + + local scanner_num=1 + local total_scanners=${#available_scanners[@]} + + # Run each scanner + for scanner in "${available_scanners[@]}"; do + echo -e "${CYAN}[$scanner_num/$total_scanners] Starting ${scanner^} scan...${NC}" + echo "" + + { + echo "Scanner: ${scanner^}" + echo "Started: $(date)" + echo "---" + } >> "$report_file" + + case "$scanner" in + imunify) + scan_imunify "${scan_paths[@]}" | tee -a "$report_file" + ;; + clamav) + scan_clamav "${scan_paths[@]}" | tee -a "$report_file" + ;; + maldet) + scan_maldet "${scan_paths[@]}" | tee -a "$report_file" + ;; + esac + + echo "" | tee -a "$report_file" + echo "---" >> "$report_file" + echo "" >> "$report_file" + + ((scanner_num++)) + + # Wait a moment between scanners + if [ $scanner_num -le $total_scanners ]; then + echo "" + echo "Waiting 3 seconds before next scanner..." + sleep 3 + echo "" + fi + done + + # Finalize report + { + echo "==========================================" + echo "Multi-Scanner Session Complete" + echo "Completed: $(date)" + echo "==========================================" + } >> "$report_file" + + echo "" + echo -e "${GREEN}✓ All scanners completed${NC}" + echo "" + echo "Session report saved: $report_file" + echo "" + echo "View individual scanner results using option 5 from main menu" + + # Store in reference database + store_reference "malware_multiscan_latest" "$session_id" + store_reference "malware_multiscan_${session_id}" "$report_file" + + echo "" + read -p "Press Enter to continue..." +} + +# Compare results from multiple scanners +compare_scan_results() { + echo "" + print_header "Compare Scanner Results" + + # Get latest multiscan session + local latest_session=$(get_reference "malware_multiscan_latest") + + if [ -z "$latest_session" ]; then + echo "No multi-scanner sessions found." + echo "" + echo "Run a scan with 'All Available Scanners' option first." + read -p "Press Enter to continue..." + return + fi + + local report_file=$(get_reference "malware_multiscan_${latest_session}") + + if [ -f "$report_file" ]; then + echo "Latest multi-scanner session: $latest_session" + echo "" + less "$report_file" + else + echo "Report file not found: $report_file" + fi + + echo "" + read -p "Press Enter to continue..." +} + # Main scan menu show_scan_menu() { while true; do @@ -316,8 +447,10 @@ show_scan_menu() { echo " 3. Scan specific domain" echo " 4. Scan custom path" echo "" + echo "Results & Management:" echo " 5. View scan results" - echo " 6. Scanner settings" + echo " 6. Compare scanner results" + echo " 7. Scanner settings" echo "" echo " 0. Back to main menu" echo "" @@ -330,7 +463,8 @@ show_scan_menu() { 3) scan_domain ;; 4) scan_custom_path ;; 5) view_scan_results ;; - 6) scanner_settings ;; + 6) compare_scan_results ;; + 7) scanner_settings ;; 0) return 0 ;; *) echo -e "${RED}Invalid option${NC}"; sleep 1 ;; esac @@ -362,24 +496,28 @@ scan_entire_server() { echo " $i. ${scanner^}" ((i++)) done + echo " $i. All Available Scanners (run sequentially)" echo "" read -p "Scanner: " scanner_choice - if [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then + # Check for "All Scanners" option + if [ "$scanner_choice" -eq "$i" ]; then + run_all_scanners "${sanitized_docroot[@]}" + elif [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then echo -e "${RED}Invalid choice${NC}" read -p "Press Enter to continue..." return 1 + else + local selected_scanner="${available_scanners[$((scanner_choice-1))]}" + + case "$selected_scanner" in + imunify) scan_imunify "${sanitized_docroot[@]}" ;; + clamav) scan_clamav "${sanitized_docroot[@]}" ;; + maldet) scan_maldet "${sanitized_docroot[@]}" ;; + esac fi - local selected_scanner="${available_scanners[$((scanner_choice-1))]}" - - case "$selected_scanner" in - imunify) scan_imunify "${sanitized_docroot[@]}" ;; - clamav) scan_clamav "${sanitized_docroot[@]}" ;; - maldet) scan_maldet "${sanitized_docroot[@]}" ;; - esac - echo "" read -p "Press Enter to continue..." } @@ -424,24 +562,28 @@ scan_user_account() { echo " $i. ${scanner^}" ((i++)) done + echo " $i. All Available Scanners (run sequentially)" echo "" read -p "Scanner: " scanner_choice - if [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then + # Check for "All Scanners" option + if [ "$scanner_choice" -eq "$i" ]; then + run_all_scanners "${user_paths[@]}" + elif [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then echo -e "${RED}Invalid choice${NC}" read -p "Press Enter to continue..." return 1 + else + local selected_scanner="${available_scanners[$((scanner_choice-1))]}" + + case "$selected_scanner" in + imunify) scan_imunify "${user_paths[@]}" ;; + clamav) scan_clamav "${user_paths[@]}" ;; + maldet) scan_maldet "${user_paths[@]}" ;; + esac fi - local selected_scanner="${available_scanners[$((scanner_choice-1))]}" - - case "$selected_scanner" in - imunify) scan_imunify "${user_paths[@]}" ;; - clamav) scan_clamav "${user_paths[@]}" ;; - maldet) scan_maldet "${user_paths[@]}" ;; - esac - echo "" read -p "Press Enter to continue..." } @@ -481,24 +623,28 @@ scan_domain() { echo " $i. ${scanner^}" ((i++)) done + echo " $i. All Available Scanners (run sequentially)" echo "" read -p "Scanner: " scanner_choice - if [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then + # Check for "All Scanners" option + if [ "$scanner_choice" -eq "$i" ]; then + run_all_scanners "$domain_path" + elif [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then echo -e "${RED}Invalid choice${NC}" read -p "Press Enter to continue..." return 1 + else + local selected_scanner="${available_scanners[$((scanner_choice-1))]}" + + case "$selected_scanner" in + imunify) scan_imunify "$domain_path" ;; + clamav) scan_clamav "$domain_path" ;; + maldet) scan_maldet "$domain_path" ;; + esac fi - local selected_scanner="${available_scanners[$((scanner_choice-1))]}" - - case "$selected_scanner" in - imunify) scan_imunify "$domain_path" ;; - clamav) scan_clamav "$domain_path" ;; - maldet) scan_maldet "$domain_path" ;; - esac - echo "" read -p "Press Enter to continue..." } @@ -525,24 +671,28 @@ scan_custom_path() { echo " $i. ${scanner^}" ((i++)) done + echo " $i. All Available Scanners (run sequentially)" echo "" read -p "Scanner: " scanner_choice - if [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then + # Check for "All Scanners" option + if [ "$scanner_choice" -eq "$i" ]; then + run_all_scanners "$custom_path" + elif [ "$scanner_choice" -lt 1 ] || [ "$scanner_choice" -gt ${#available_scanners[@]} ]; then echo -e "${RED}Invalid choice${NC}" read -p "Press Enter to continue..." return 1 + else + local selected_scanner="${available_scanners[$((scanner_choice-1))]}" + + case "$selected_scanner" in + imunify) scan_imunify "$custom_path" ;; + clamav) scan_clamav "$custom_path" ;; + maldet) scan_maldet "$custom_path" ;; + esac fi - local selected_scanner="${available_scanners[$((scanner_choice-1))]}" - - case "$selected_scanner" in - imunify) scan_imunify "$custom_path" ;; - clamav) scan_clamav "$custom_path" ;; - maldet) scan_maldet "$custom_path" ;; - esac - echo "" read -p "Press Enter to continue..." }