The Analyzer v1.0 — autonomous bug bounty engine with 20 attack vectors and Ollama brain
This commit is contained in:
242
engine/reporter.sh
Executable file
242
engine/reporter.sh
Executable file
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env bash
|
||||
# The Analyzer - Report Generator
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/../lib/utils.sh"
|
||||
|
||||
generate_report() {
|
||||
local target="$1"
|
||||
local report="$2"
|
||||
local findings="$3"
|
||||
|
||||
echo ""
|
||||
print_info "Generating final report..."
|
||||
separator
|
||||
|
||||
if [ -z "$findings" ] || [ "$findings" -eq 0 ]; then
|
||||
append_report "$report" "\n## Results\n\nNo vulnerabilities found during testing.\n"
|
||||
print_ok "No vulnerabilities found"
|
||||
finalize_report "$report" 0 0
|
||||
print_report_summary "$report"
|
||||
return
|
||||
fi
|
||||
|
||||
print_find "$findings vulnerabilities discovered!"
|
||||
|
||||
# Append the findings to report
|
||||
append_report "$report" "\n## Vulnerabilities Found\n\n"
|
||||
|
||||
local count=1
|
||||
for f in "$REPORTS_DIR"/.finding_*.txt; do
|
||||
[ ! -f "$f" ] && continue
|
||||
local finding=$(cat "$f")
|
||||
local severity=$(echo "$finding" | grep "^SEVERITY:" | cut -d: -f2- | xargs)
|
||||
local vector=$(echo "$finding" | grep "^VECTOR:" | cut -d: -f2- | xargs)
|
||||
local detail=$(echo "$finding" | grep "^DETAIL:" | cut -d: -f2- | xargs)
|
||||
local evidence=$(echo "$finding" | grep "^EVIDENCE:" | cut -d: -f2- | xargs)
|
||||
local exploit=$(echo "$finding" | grep "^EXPLOIT:" | cut -d: -f2- | xargs)
|
||||
|
||||
local severity_emoji="🟢"
|
||||
case "$severity" in
|
||||
CRITICAL) severity_emoji="🔴" ;;
|
||||
HIGH) severity_emoji="🟠" ;;
|
||||
MEDIUM) severity_emoji="🟡" ;;
|
||||
LOW) severity_emoji="🔵" ;;
|
||||
*) severity_emoji="⚪" ;;
|
||||
esac
|
||||
|
||||
append_report "$report" "### $count. $vector\n"
|
||||
append_report "$report" "- **Severity:** $severity_emoji $severity\n"
|
||||
append_report "$report" "- **Detail:** $detail\n"
|
||||
[ -n "$evidence" ] && append_report "$report" "- **Evidence:** $evidence\n"
|
||||
[ -n "$exploit" ] && append_report "$report" "- **Exploitation:** $exploit\n"
|
||||
append_report "$report" "\n"
|
||||
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
finalize_report "$report" $((count - 1)) $findings
|
||||
print_report_summary "$report"
|
||||
}
|
||||
|
||||
print_report_summary() {
|
||||
local report="$1"
|
||||
echo ""
|
||||
separator
|
||||
echo -e " ${BRIGHT_GREEN}${ICON_DONE}${NC} ${BOLD}Analysis Complete!${NC}"
|
||||
echo -e " ${CYAN}${ICON_REPORT}${NC} Report: ${BOLD}$report${NC}"
|
||||
|
||||
# Get count
|
||||
local vulns=$(grep -c "### [0-9]" "$report" 2>/dev/null)
|
||||
if [ "$vulns" -gt 0 ]; then
|
||||
echo ""
|
||||
echo -e " ${BRIGHT_RED}${BOLD}⚠ $vulns vulnerabilities found!${NC}"
|
||||
echo ""
|
||||
# List them
|
||||
grep "^### " "$report" | while read line; do
|
||||
sev=$(grep -A1 "$line" "$report" | grep "Severity:" | sed 's/.*\*\*Severity:\*\* //')
|
||||
echo -e " ${BRIGHT_RED}!${NC} $line ($sev)"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_info "HTML version also saved: ${report%.md}.html"
|
||||
}
|
||||
|
||||
# Generate HTML report from markdown
|
||||
html_report() {
|
||||
local md_report="$1"
|
||||
local html_report="${md_report%.md}.html"
|
||||
local domain=$(grep "^**Domain:**" "$md_report" | sed 's/.*\*\*Domain:\*\* //')
|
||||
local date=$(grep "^**Date:**" "$md_report" | sed 's/.*\*\*Date:\*\* //')
|
||||
|
||||
# Count by severity
|
||||
local crit=$(grep -c "🔴" "$md_report" 2>/dev/null || echo 0)
|
||||
local high=$(grep -c "🟠" "$md_report" 2>/dev/null || echo 0)
|
||||
local med=$(grep -c "🟡" "$md_report" 2>/dev/null || echo 0)
|
||||
local low=$(grep -c "🔵" "$md_report" 2>/dev/null || echo 0)
|
||||
|
||||
# Extract findings
|
||||
local findings_html=""
|
||||
local in_finding=false
|
||||
local finding_num=""
|
||||
local finding_title=""
|
||||
local finding_sev=""
|
||||
local finding_detail=""
|
||||
local finding_evidence=""
|
||||
local finding_exploit=""
|
||||
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" =~ ^###\ ([0-9]+)\.\ (.*) ]]; then
|
||||
# Save previous finding
|
||||
if [ -n "$finding_title" ]; then
|
||||
local border_color="border-left: 4px solid #22c55e;"
|
||||
local badge_bg="#22c55e"
|
||||
case "$finding_sev" in
|
||||
*CRITICAL*) border_color="border-left: 4px solid #ef4444;"; badge_bg="#ef4444" ;;
|
||||
*HIGH*) border_color="border-left: 4px solid #f97316;"; badge_bg="#f97316" ;;
|
||||
*MEDIUM*) border_color="border-left: 4px solid #eab308;"; badge_bg="#eab308" ;;
|
||||
*LOW*) border_color="border-left: 4px solid #3b82f6;"; badge_bg="#3b82f6" ;;
|
||||
esac
|
||||
findings_html+="<div class=\"finding\" style=\"background:#1e293b;border-radius:8px;padding:16px;margin-bottom:12px;${border_color}\">"
|
||||
findings_html+="<div class=\"finding-header\" style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;\">"
|
||||
findings_html+="<h3 style=\"margin:0;color:#f1f5f9;font-size:16px;\">${finding_num}. ${finding_title}</h3>"
|
||||
findings_html+="<span class=\"badge\" style=\"background:${badge_bg};color:#fff;padding:2px 10px;border-radius:12px;font-size:12px;font-weight:bold;\">${finding_sev//\*/}</span>"
|
||||
findings_html+="</div>"
|
||||
[ -n "$finding_detail" ] && findings_html+="<p style=\"color:#94a3b8;font-size:14px;margin:4px 0;\">${finding_detail}</p>"
|
||||
[ -n "$finding_evidence" ] && findings_html+="<div style=\"background:#0f172a;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#22d3ee;margin:8px 0;word-break:break-all;\">${finding_evidence}</div>"
|
||||
[ -n "$finding_exploit" ] && findings_html+="<div style=\"background:#0f172a;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#fbbf24;margin:8px 0;\"><strong style=\"color:#f59e0b;\">Exploit:</strong> ${finding_exploit}</div>"
|
||||
findings_html+="</div>"
|
||||
fi
|
||||
|
||||
finding_num="${BASH_REMATCH[1]}"
|
||||
finding_title="${BASH_REMATCH[2]}"
|
||||
finding_sev=""
|
||||
finding_detail=""
|
||||
finding_evidence=""
|
||||
finding_exploit=""
|
||||
in_finding=true
|
||||
elif [[ "$line" =~ \*\*Severity:\*\*\ (.*) ]]; then
|
||||
finding_sev="${BASH_REMATCH[1]}"
|
||||
elif [[ "$line" =~ \*\*Detail:\*\*\ (.*) ]]; then
|
||||
finding_detail="${BASH_REMATCH[1]}"
|
||||
elif [[ "$line" =~ \*\*Evidence:\*\*\ (.*) ]]; then
|
||||
finding_evidence="${BASH_REMATCH[1]}"
|
||||
elif [[ "$line" =~ \*\*Exploitation:\*\*\ (.*) ]]; then
|
||||
finding_exploit="${BASH_REMATCH[1]}"
|
||||
fi
|
||||
done < "$md_report"
|
||||
|
||||
# Last finding
|
||||
if [ -n "$finding_title" ]; then
|
||||
local border_color="border-left: 4px solid #22c55e;"
|
||||
local badge_bg="#22c55e"
|
||||
case "$finding_sev" in
|
||||
*CRITICAL*) border_color="border-left: 4px solid #ef4444;"; badge_bg="#ef4444" ;;
|
||||
*HIGH*) border_color="border-left: 4px solid #f97316;"; badge_bg="#f97316" ;;
|
||||
*MEDIUM*) border_color="border-left: 4px solid #eab308;"; badge_bg="#eab308" ;;
|
||||
*LOW*) border_color="border-left: 4px solid #3b82f6;"; badge_bg="#3b82f6" ;;
|
||||
esac
|
||||
findings_html+="<div class=\"finding\" style=\"background:#1e293b;border-radius:8px;padding:16px;margin-bottom:12px;${border_color}\">"
|
||||
findings_html+="<div class=\"finding-header\" style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;\">"
|
||||
findings_html+="<h3 style=\"margin:0;color:#f1f5f9;font-size:16px;\">${finding_num}. ${finding_title}</h3>"
|
||||
findings_html+="<span class=\"badge\" style=\"background:${badge_bg};color:#fff;padding:2px 10px;border-radius:12px;font-size:12px;font-weight:bold;\">${finding_sev//\*/}</span>"
|
||||
findings_html+="</div>"
|
||||
[ -n "$finding_detail" ] && findings_html+="<p style=\"color:#94a3b8;font-size:14px;margin:4px 0;\">${finding_detail}</p>"
|
||||
[ -n "$finding_evidence" ] && findings_html+="<div style=\"background:#0f172a;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#22d3ee;margin:8px 0;word-break:break-all;\">${finding_evidence}</div>"
|
||||
[ -n "$finding_exploit" ] && findings_html+="<div style=\"background:#0f172a;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#fbbf24;margin:8px 0;\"><strong style=\"color:#f59e0b;\">Exploit:</strong> ${finding_exploit}</div>"
|
||||
findings_html+="</div>"
|
||||
fi
|
||||
|
||||
local total_findings=$((crit + high + med + low))
|
||||
|
||||
cat > "$html_report" << HTML
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Analyzer Report - ${domain}</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0f172a; color: #e2e8f0; line-height: 1.6; }
|
||||
.container { max-width: 800px; margin: 0 auto; padding: 20px; }
|
||||
.header { background: linear-gradient(135deg, #0f172a, #1e293b); padding: 32px; border-radius: 12px; margin-bottom: 24px; text-align: center; border: 1px solid #334155; }
|
||||
.header h1 { font-size: 24px; margin-bottom: 8px; background: linear-gradient(90deg, #f97316, #ef4444); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
||||
.header p { color: #94a3b8; font-size: 14px; }
|
||||
.header .domain { color: #f97316; font-size: 18px; font-weight: bold; -webkit-text-fill-color: #f97316; margin: 8px 0; }
|
||||
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 24px; }
|
||||
.stat-card { background: #1e293b; padding: 16px; border-radius: 8px; text-align: center; border: 1px solid #334155; }
|
||||
.stat-card .number { font-size: 28px; font-weight: bold; }
|
||||
.stat-card .label { font-size: 12px; color: #94a3b8; margin-top: 4px; }
|
||||
.critical .number { color: #ef4444; }
|
||||
.high .number { color: #f97316; }
|
||||
.medium .number { color: #eab308; }
|
||||
.low .number { color: #3b82f6; }
|
||||
.section-title { font-size: 18px; font-weight: bold; margin: 24px 0 12px; color: #f1f5f9; border-bottom: 1px solid #334155; padding-bottom: 8px; }
|
||||
.finding { transition: transform 0.1s; }
|
||||
.finding:hover { transform: translateX(4px); }
|
||||
.footer { text-align: center; padding: 20px; color: #475569; font-size: 12px; margin-top: 32px; border-top: 1px solid #1e293b; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🔍 Analyzer Security Report</h1>
|
||||
<div class="domain">${domain}</div>
|
||||
<p>${date}</p>
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat-card critical">
|
||||
<div class="number">${crit}</div>
|
||||
<div class="label">Critical</div>
|
||||
</div>
|
||||
<div class="stat-card high">
|
||||
<div class="number">${high}</div>
|
||||
<div class="label">High</div>
|
||||
</div>
|
||||
<div class="stat-card medium">
|
||||
<div class="number">${med}</div>
|
||||
<div class="label">Medium</div>
|
||||
</div>
|
||||
<div class="stat-card low">
|
||||
<div class="number">${low}</div>
|
||||
<div class="label">Low</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-title">Findings</div>
|
||||
${findings_html}
|
||||
|
||||
<div class="footer">
|
||||
Generated by The Analyzer v1.0 — Authorized Bug Bounty Use Only<br>
|
||||
Analyst: Drjonesxxx / Indianaholmes
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
||||
echo "$html_report"
|
||||
}
|
||||
Reference in New Issue
Block a user