Add client-facing security report generator
Feature: Generate professional security reports for support tickets
New Function: generate_client_report()
- Creates client-friendly security reports from scan results
- Automatically categorizes detections as real threats vs false positives
- Uses clear, non-technical language suitable for end users
- Includes actionable recommendations
Report Sections:
1. Overall Status - Clean or infected summary
2. Scan Details - Which engines were used
3. Infected Files - Real threats requiring action (if any)
4. Informational Detections - False positives explained
5. Security Observations - Attack patterns detected in logs
6. Ongoing Recommendations - Best practices for security
Smart False Positive Detection:
Automatically identifies likely false positives:
- Log files (*.log, *.gz, *.bz2 in logs directories)
- AWStats data files (/awstats/)
- Temporary text files (/tmp/*.txt)
- Rotated logs (*.log.[0-9]+)
Separates these from real threats so clients understand:
- What's actually dangerous vs informational
- Why log files trigger alerts (recorded attack attempts)
- That their server blocked the attacks successfully
Attack Pattern Analysis:
- Detects attack signatures in ClamAV logs (YARA.*)
- Categorizes attack types (web shells, SQL injection, etc.)
- Explains what the patterns mean in plain language
Integration:
- Added to view_scan_results menu as action option
- Saves report to: scan_dir/results/client_report.txt
- Report is copy/paste ready for support tickets
Example Output:
✅ NO ACTIVE MALWARE DETECTED
Your server is clean. No malicious files were found...
INFORMATIONAL DETECTIONS (No Action Required)
The following files contain records of attack attempts:
• /logs/access.log.gz (r57shell attempts - blocked)
Perfect for:
- Passing scan results to clients
- Support ticket documentation
- Post-incident reporting
- Regular security updates
This commit is contained in:
@@ -2212,6 +2212,27 @@ view_scan_results() {
|
|||||||
|
|
||||||
echo "View full logs:"
|
echo "View full logs:"
|
||||||
echo " tail -f $selected_dir/logs/session.log"
|
echo " tail -f $selected_dir/logs/session.log"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Offer to generate client report
|
||||||
|
echo -e "${CYAN}Actions:${NC}"
|
||||||
|
echo " 1. Generate client-facing security report"
|
||||||
|
echo " 0. Back to menu"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "Select action (or press Enter to continue): " action_choice
|
||||||
|
|
||||||
|
case "$action_choice" in
|
||||||
|
1)
|
||||||
|
generate_client_report "$selected_dir"
|
||||||
|
;;
|
||||||
|
0|"")
|
||||||
|
# Continue
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${RED}Invalid option${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
;;
|
;;
|
||||||
|
|
||||||
0)
|
0)
|
||||||
@@ -2243,6 +2264,224 @@ scanner_settings() {
|
|||||||
read -p "Press Enter to continue..."
|
read -p "Press Enter to continue..."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate client-facing security report
|
||||||
|
generate_client_report() {
|
||||||
|
local scan_dir="$1"
|
||||||
|
|
||||||
|
if [ ! -d "$scan_dir" ]; then
|
||||||
|
echo -e "${RED}Scan directory not found${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local summary_file="$scan_dir/results/summary.txt"
|
||||||
|
local infected_file="$scan_dir/results/infected_files.txt"
|
||||||
|
local clamav_log="$scan_dir/logs/clamav.log"
|
||||||
|
local session_log="$scan_dir/logs/session.log"
|
||||||
|
local report_file="$scan_dir/results/client_report.txt"
|
||||||
|
|
||||||
|
if [ ! -f "$summary_file" ]; then
|
||||||
|
echo -e "${RED}Summary file not found - scan may not be complete${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract scan info
|
||||||
|
local session_name=$(basename "$scan_dir")
|
||||||
|
local scan_date=$(grep "Started:" "$summary_file" | head -1 | sed 's/Started: //')
|
||||||
|
local scan_paths=$(sed -n '/^Paths:/,/^$/p' "$summary_file" | tail -n +2 | grep -v "^$" | tr '\n' ', ' | sed 's/, $//')
|
||||||
|
|
||||||
|
# Count threats
|
||||||
|
local total_threats=0
|
||||||
|
local imunify_count=$(grep -o "ImunifyAV:.*[0-9]* threats" "$summary_file" | grep -o "[0-9]*" || echo "0")
|
||||||
|
local clamav_count=$(grep -o "ClamAV:.*[0-9]* infected" "$summary_file" | grep -o "[0-9]*" || echo "0")
|
||||||
|
local maldet_hits=$(grep -o "Maldet:.*[0-9]* hits" "$summary_file" | grep -o "[0-9]*" || echo "0")
|
||||||
|
|
||||||
|
# Calculate total (only real malware, not rootkit warnings)
|
||||||
|
total_threats=$((imunify_count + clamav_count + maldet_hits))
|
||||||
|
|
||||||
|
# Analyze infected files for false positives
|
||||||
|
local real_threats=()
|
||||||
|
local false_positives=()
|
||||||
|
|
||||||
|
if [ -f "$infected_file" ] && [ -s "$infected_file" ]; then
|
||||||
|
while IFS= read -r file; do
|
||||||
|
# Check if likely false positive (logs, stats, cache)
|
||||||
|
if [[ "$file" =~ /logs?/.*\.(log|gz|bz2)$ ]] || \
|
||||||
|
[[ "$file" =~ /awstats/ ]] || \
|
||||||
|
[[ "$file" =~ /tmp/.*\.txt$ ]] || \
|
||||||
|
[[ "$file" =~ \.log\.[0-9]+$ ]]; then
|
||||||
|
false_positives+=("$file")
|
||||||
|
else
|
||||||
|
real_threats+=("$file")
|
||||||
|
fi
|
||||||
|
done < "$infected_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate report
|
||||||
|
{
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "SECURITY SCAN REPORT"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "Scan Date: $scan_date"
|
||||||
|
echo "Scan Coverage: $scan_paths"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Overall status
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "OVERALL STATUS"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ ${#real_threats[@]} -eq 0 ]; then
|
||||||
|
echo "✅ NO ACTIVE MALWARE DETECTED"
|
||||||
|
echo ""
|
||||||
|
echo "Your server is clean. No malicious files were found in"
|
||||||
|
echo "web-accessible directories or user content areas."
|
||||||
|
else
|
||||||
|
echo "⚠️ MALWARE DETECTED - ACTION REQUIRED"
|
||||||
|
echo ""
|
||||||
|
echo "Found ${#real_threats[@]} infected file(s) that require immediate attention."
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Scan details
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "SCAN DETAILS"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "We performed a comprehensive security scan using multiple"
|
||||||
|
echo "industry-standard malware detection engines:"
|
||||||
|
echo ""
|
||||||
|
echo " • ImunifyAV - Advanced threat detection"
|
||||||
|
echo " • ClamAV - Open-source antivirus engine"
|
||||||
|
echo " • Linux Maldet - Web malware specialist"
|
||||||
|
echo " • Rootkit Hunter - System integrity checker"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Real threats section
|
||||||
|
if [ ${#real_threats[@]} -gt 0 ]; then
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "INFECTED FILES REQUIRING ATTENTION"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for file in "${real_threats[@]}"; do
|
||||||
|
echo "📁 $file"
|
||||||
|
|
||||||
|
# Get detection details from ClamAV log
|
||||||
|
if [ -f "$clamav_log" ]; then
|
||||||
|
local detection=$(grep "$file" "$clamav_log" | grep "FOUND" | sed 's/.*: / /' || echo " Detection: Unknown signature")
|
||||||
|
echo "$detection"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "RECOMMENDED ACTIONS:"
|
||||||
|
echo ""
|
||||||
|
echo "1. Review each file to confirm it is malicious"
|
||||||
|
echo "2. Remove or quarantine infected files immediately"
|
||||||
|
echo "3. Change all passwords (hosting, FTP, database, CMS admin)"
|
||||||
|
echo "4. Review file upload functionality in web applications"
|
||||||
|
echo "5. Update all web applications, plugins, and themes"
|
||||||
|
echo "6. Check access logs for unauthorized access patterns"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# False positives section
|
||||||
|
if [ ${#false_positives[@]} -gt 0 ]; then
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "INFORMATIONAL DETECTIONS (No Action Required)"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "The following files triggered alerts but are likely false"
|
||||||
|
echo "positives. These are log files that contain records of"
|
||||||
|
echo "attack attempts against your server (which were blocked):"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for file in "${false_positives[@]}"; do
|
||||||
|
echo " • $file"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo "These files are safe and contain evidence of your server"
|
||||||
|
echo "correctly blocking malicious requests. No action needed."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Security observations
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "SECURITY OBSERVATIONS"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check for attack patterns in logs
|
||||||
|
if [ -f "$clamav_log" ]; then
|
||||||
|
local attack_signatures=$(grep -o "YARA\.[a-z0-9_]*" "$clamav_log" | sort -u | sed 's/YARA\.//' | head -5)
|
||||||
|
if [ -n "$attack_signatures" ]; then
|
||||||
|
echo "Attack Patterns Detected in Logs:"
|
||||||
|
echo ""
|
||||||
|
echo "$attack_signatures" | while read sig; do
|
||||||
|
case "$sig" in
|
||||||
|
*r57*|*c99*|*shell*)
|
||||||
|
echo " • Web shell upload attempts (${sig})"
|
||||||
|
;;
|
||||||
|
*sql*)
|
||||||
|
echo " • SQL injection attempts (${sig})"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo " • Malicious activity pattern: ${sig}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo "These attack attempts were blocked by your server, but"
|
||||||
|
echo "they indicate your site is being actively targeted."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# General recommendations
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "ONGOING SECURITY RECOMMENDATIONS"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "To maintain server security, we recommend:"
|
||||||
|
echo ""
|
||||||
|
echo " ✓ Run malware scans monthly (or after any security incident)"
|
||||||
|
echo " ✓ Keep all software updated (WordPress, plugins, PHP, etc.)"
|
||||||
|
echo " ✓ Use strong, unique passwords for all accounts"
|
||||||
|
echo " ✓ Enable automatic security updates where possible"
|
||||||
|
echo " ✓ Review file permissions regularly"
|
||||||
|
echo " ✓ Monitor server logs for suspicious activity"
|
||||||
|
echo " ✓ Maintain regular backups (stored off-server)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Footer
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "TECHNICAL DETAILS"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "Scan ID: $session_name"
|
||||||
|
echo "Report Generated: $(date)"
|
||||||
|
echo ""
|
||||||
|
echo "For technical details and full scan logs, please contact"
|
||||||
|
echo "your system administrator."
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
|
||||||
|
} > "$report_file"
|
||||||
|
|
||||||
|
# Display the report
|
||||||
|
echo ""
|
||||||
|
print_header "Client Security Report Generated"
|
||||||
|
echo ""
|
||||||
|
cat "$report_file"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Report saved to:${NC} $report_file"
|
||||||
|
echo ""
|
||||||
|
echo "You can now copy/paste this report into your support ticket."
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
# Main execution
|
# Main execution
|
||||||
main() {
|
main() {
|
||||||
if ! detect_scanners; then
|
if ! detect_scanners; then
|
||||||
|
|||||||
Reference in New Issue
Block a user