v2.2.0 — Full arsenal expansion: 16 new security modules
Add WiFi Audit, API Fuzzer, Cloud Scanner, Threat Intel, Log Correlator,
Steganography, Anti-Forensics, BLE Scanner, Forensics, RFID/NFC, Malware
Sandbox, Password Toolkit, Web Scanner, Report Engine, Net Mapper, and
C2 Framework. Each module includes CLI interface, Flask routes, and web
UI template. Also includes Go DNS server source + binary, IP Capture
service, SYN Flood, Gone Fishing mail server, and hack hijack modules
from v2.0 work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 05:16:31 -08:00
{% extends "base.html" %}
{% block title %}Reports — AUTARCH{% endblock %}
{% block content %}
< div class = "page-header" >
< h1 > Reporting Engine< / h1 >
< p class = "text-muted" > Pentest report builder with findings, CVSS scoring, and export< / p >
< / div >
< div class = "tabs" >
< button class = "tab active" onclick = "switchTab('reports')" > Reports< / button >
< button class = "tab" onclick = "switchTab('editor')" > Editor< / button >
< button class = "tab" onclick = "switchTab('templates')" > Finding Templates< / button >
< / div >
<!-- Reports List -->
< div id = "tab-reports" class = "tab-content active" >
< div style = "display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem" >
< h3 > Reports< / h3 >
< button class = "btn btn-primary" onclick = "showCreateReport()" > New Report< / button >
< / div >
< div id = "create-form" class = "card" style = "display:none;margin-bottom:1rem;max-width:600px" >
< h4 > Create Report< / h4 >
< div class = "form-group" > < label > Title< / label > < input type = "text" id = "cr-title" class = "form-control" placeholder = "Penetration Test Report" > < / div >
< div class = "form-group" > < label > Client< / label > < input type = "text" id = "cr-client" class = "form-control" placeholder = "Client name" > < / div >
< div class = "form-group" > < label > Scope< / label > < textarea id = "cr-scope" class = "form-control" rows = "2" placeholder = "Target systems and IP ranges" > < / textarea > < / div >
< button class = "btn btn-primary" onclick = "createReport()" > Create< / button >
< / div >
< div id = "reports-list" > < / div >
< / div >
<!-- Editor -->
< div id = "tab-editor" class = "tab-content" style = "display:none" >
< div id = "editor-empty" class = "card" style = "text-align:center;color:var(--text-muted)" > Select a report from the Reports tab< / div >
< div id = "editor" style = "display:none" >
< div class = "card" >
< div style = "display:flex;justify-content:space-between;align-items:center" >
< h3 id = "ed-title" style = "margin:0" > < / h3 >
< div style = "display:flex;gap:0.5rem" >
< select id = "ed-status" class = "form-control" style = "width:auto" onchange = "updateReportField('status',this.value)" >
< option value = "draft" > Draft< / option >
< option value = "review" > Review< / option >
< option value = "final" > Final< / option >
< / select >
< button class = "btn btn-sm" onclick = "exportReport('html')" > Export HTML< / button >
< button class = "btn btn-sm" onclick = "exportReport('markdown')" > Export MD< / button >
< button class = "btn btn-sm" onclick = "exportReport('json')" > Export JSON< / button >
< / div >
< / div >
< div class = "form-group" style = "margin-top:1rem" > < label > Executive Summary< / label >
< textarea id = "ed-summary" class = "form-control" rows = "3" onblur = "updateReportField('executive_summary',this.value)" > < / textarea > < / div >
< / div >
<!-- Severity Summary -->
< div id = "sev-summary" style = "display:flex;gap:0.75rem;margin:1rem 0" > < / div >
<!-- Findings -->
< div style = "display:flex;justify-content:space-between;align-items:center;margin:1rem 0" >
< h3 > Findings< / h3 >
< div style = "display:flex;gap:0.5rem" >
< button class = "btn btn-primary btn-sm" onclick = "showAddFinding()" > Add Finding< / button >
< button class = "btn btn-sm" onclick = "showTemplateSelector()" > From Template< / button >
< / div >
< / div >
< div id = "findings-list" > < / div >
<!-- Add finding form -->
< div id = "add-finding-form" class = "card" style = "display:none;margin-top:1rem" >
< h4 > Add Finding< / h4 >
< div class = "form-group" > < label > Title< / label > < input type = "text" id = "af-title" class = "form-control" > < / div >
< div style = "display:grid;grid-template-columns:1fr 1fr;gap:0.5rem" >
< div class = "form-group" > < label > Severity< / label >
< select id = "af-severity" class = "form-control" >
< option value = "critical" > Critical< / option > < option value = "high" > High< / option >
< option value = "medium" selected > Medium< / option > < option value = "low" > Low< / option > < option value = "info" > Info< / option >
< / select > < / div >
< div class = "form-group" > < label > CVSS Score< / label > < input type = "number" id = "af-cvss" class = "form-control" value = "5.0" min = "0" max = "10" step = "0.1" > < / div >
< / div >
< div class = "form-group" > < label > Description< / label > < textarea id = "af-desc" class = "form-control" rows = "2" > < / textarea > < / div >
< div class = "form-group" > < label > Impact< / label > < textarea id = "af-impact" class = "form-control" rows = "2" > < / textarea > < / div >
< div class = "form-group" > < label > Remediation< / label > < textarea id = "af-remediation" class = "form-control" rows = "2" > < / textarea > < / div >
< button class = "btn btn-primary" onclick = "addFinding()" > Add< / button >
< button class = "btn" onclick = "document.getElementById('add-finding-form').style.display='none'" > Cancel< / button >
< / div >
< / div >
< / div >
<!-- Templates -->
< div id = "tab-templates" class = "tab-content" style = "display:none" >
< h3 > Finding Templates< / h3 >
< div id = "templates-list" > < / div >
< / div >
< style >
.sev-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:0.75rem;font-weight:700;color:#fff}
.sev-critical{background:#dc2626}.sev-high{background:#ef4444}.sev-medium{background:#f59e0b}.sev-low{background:#22c55e}.sev-info{background:#6366f1}
.sev-box{border:2px solid;border-radius:8px;padding:0.5rem 1rem;text-align:center;min-width:70px}
.finding-card{border:1px solid var(--border);border-radius:var(--radius);padding:1rem;margin-bottom:0.75rem}
.finding-card h4{margin:0 0 0.5rem}
< / style >
< script >
let currentReportId=null;
function switchTab(name){
document.querySelectorAll('.tab').forEach((t,i)=>t.classList.toggle('active',['reports','editor','templates'][i]===name));
document.querySelectorAll('.tab-content').forEach(c=>c.style.display='none');
Add Port Scanner, fix Hack Hijack SSE, fix debug console, fix tab layout bugs
- Add advanced Port Scanner with live SSE output, nmap integration, result export
- Add Port Scanner to sidebar nav and register blueprint
- Fix Hack Hijack scan: replace polling with SSE streaming, add live output box
and real-time port discovery table; add port_found_cb/status_cb to module
- Fix debug console: capture print()/stdout/stderr via _PrintCapture wrapper,
install handler at startup (not just on toggle), fix SSE stream history replay
- Add missing CSS: .card, .tabs, .btn-sm, .form-control, --primary, --surface
- Fix tab switching bug: style.display='' falls back to CSS display:none;
use explicit 'block' in hack_hijack, c2_framework, net_mapper, password_toolkit,
report_engine, social_eng, webapp_scanner
- Fix defense/linux layout: rewrite with card-based layout, remove slow
load_modules() call on every page request
- Fix sms_forge missing run() function warning on startup
- Fix port scanner JS: </style> was used instead of </script> closing tag
- Port scanner advanced options: remove collapsible toggle, show as always-visible bar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 18:09:49 -07:00
document.getElementById('tab-'+name).style.display='block';
v2.2.0 — Full arsenal expansion: 16 new security modules
Add WiFi Audit, API Fuzzer, Cloud Scanner, Threat Intel, Log Correlator,
Steganography, Anti-Forensics, BLE Scanner, Forensics, RFID/NFC, Malware
Sandbox, Password Toolkit, Web Scanner, Report Engine, Net Mapper, and
C2 Framework. Each module includes CLI interface, Flask routes, and web
UI template. Also includes Go DNS server source + binary, IP Capture
service, SYN Flood, Gone Fishing mail server, and hack hijack modules
from v2.0 work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 05:16:31 -08:00
if(name==='reports') loadReports();
if(name==='templates') loadTemplates();
}
function loadReports(){
fetch('/reports/list').then(r=>r.json()).then(d=>{
const div=document.getElementById('reports-list');
const reps=d.reports||[];
if(!reps.length){div.innerHTML='< div class = "card" style = "text-align:center;color:var(--text-muted)" > No reports yet< / div > ';return}
div.innerHTML=reps.map(r=>`< div class = "card" style = "margin-bottom:0.5rem;cursor:pointer" onclick = "openReport('${r.id}')" >
< div style = "display:flex;justify-content:space-between;align-items:center" >
< div > < strong > ${esc(r.title)}< / strong > < span style = "color:var(--text-muted);font-size:0.8rem" > ${esc(r.client)}< / span > < / div >
< div style = "display:flex;align-items:center;gap:0.75rem" >
< span style = "font-size:0.8rem" > ${r.findings_count} findings< / span >
< span class = "sev-badge sev-${r.status==='final'?'info':r.status==='review'?'medium':'low'}" > ${r.status}< / span >
< button class = "btn btn-sm" style = "color:var(--danger)" onclick = "event.stopPropagation();deleteReport('${r.id}')" > Delete< / button >
< / div >
< / div > < / div > `).join('');
});
}
function showCreateReport(){document.getElementById('create-form').style.display=document.getElementById('create-form').style.display==='none'?'':'none'}
function createReport(){
const payload={title:document.getElementById('cr-title').value||'Untitled',
client:document.getElementById('cr-client').value,scope:document.getElementById('cr-scope').value};
fetch('/reports/create',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)})
.then(r=>r.json()).then(d=>{
if(d.ok){document.getElementById('create-form').style.display='none';loadReports();openReport(d.report.id)}
});
}
function deleteReport(id){
if(!confirm('Delete this report?')) return;
fetch('/reports/'+id,{method:'DELETE'}).then(r=>r.json()).then(()=>loadReports());
}
function openReport(id){
currentReportId=id;
fetch('/reports/'+id).then(r=>r.json()).then(d=>{
if(!d.ok) return;
const r=d.report;
document.getElementById('editor-empty').style.display='none';
document.getElementById('editor').style.display='';
document.getElementById('ed-title').textContent=r.title;
document.getElementById('ed-summary').value=r.executive_summary||'';
document.getElementById('ed-status').value=r.status||'draft';
renderFindings(r.findings||[]);
switchTab('editor');
});
}
function updateReportField(field,value){
if(!currentReportId) return;
const data={};data[field]=value;
fetch('/reports/'+currentReportId,{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify(data)});
}
function renderFindings(findings){
const sevOrder={critical:0,high:1,medium:2,low:3,info:4};
findings.sort((a,b)=>(sevOrder[a.severity]||5)-(sevOrder[b.severity]||5));
// Summary
const counts={};findings.forEach(f=>{counts[f.severity]=(counts[f.severity]||0)+1});
const colors={critical:'#dc2626',high:'#ef4444',medium:'#f59e0b',low:'#22c55e',info:'#6366f1'};
document.getElementById('sev-summary').innerHTML=['critical','high','medium','low','info'].map(s=>
`< div class = "sev-box" style = "border-color:${colors[s]}" > < strong style = "color:${colors[s]};font-size:1.2rem" > ${counts[s]||0}< / strong > < br > < span style = "font-size:0.7rem" > ${s.toUpperCase()}< / span > < / div > `).join('');
// List
document.getElementById('findings-list').innerHTML=findings.map((f,i)=>
`< div class = "finding-card" > < div style = "display:flex;justify-content:space-between;align-items:start" >
< div > < h4 > ${i+1}. ${esc(f.title)}< / h4 >
< span class = "sev-badge sev-${f.severity}" > ${f.severity.toUpperCase()}< / span >
< span style = "font-size:0.8rem;margin-left:0.5rem" > CVSS: ${f.cvss||'N/A'}< / span > < / div >
< button class = "btn btn-sm" style = "color:var(--danger)" onclick = "deleteFinding('${f.id}')" > Remove< / button >
< / div >
< p style = "font-size:0.85rem;margin:0.5rem 0" > ${esc(f.description||'')}< / p >
${f.impact?'< div style = "font-size:0.8rem" > < strong > Impact:< / strong > '+esc(f.impact)+'< / div > ':''}
${f.remediation?'< div style = "font-size:0.8rem" > < strong > Remediation:< / strong > '+esc(f.remediation)+'< / div > ':''}
< / div > `).join('');
}
function showAddFinding(){document.getElementById('add-finding-form').style.display=''}
function showTemplateSelector(){
fetch('/reports/templates').then(r=>r.json()).then(d=>{
const templates=d.templates||[];
const sel=prompt('Enter template #:\n'+templates.map((t,i)=>`${i+1}. [${t.severity.toUpperCase()}] ${t.title}`).join('\n'));
if(!sel) return;
const idx=parseInt(sel)-1;
if(idx>=0& & idx< templates.length ) {
const t={...templates[idx]};delete t.id;
fetch('/reports/'+currentReportId+'/findings',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(t)})
.then(r=>r.json()).then(()=>openReport(currentReportId));
}
});
}
function addFinding(){
const data={title:document.getElementById('af-title').value,
severity:document.getElementById('af-severity').value,
cvss:+document.getElementById('af-cvss').value,
description:document.getElementById('af-desc').value,
impact:document.getElementById('af-impact').value,
remediation:document.getElementById('af-remediation').value};
fetch('/reports/'+currentReportId+'/findings',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(data)})
.then(r=>r.json()).then(d=>{
if(d.ok){document.getElementById('add-finding-form').style.display='none';openReport(currentReportId)}
});
}
function deleteFinding(fid){
if(!confirm('Remove this finding?')) return;
fetch('/reports/'+currentReportId+'/findings/'+fid,{method:'DELETE'})
.then(r=>r.json()).then(()=>openReport(currentReportId));
}
function exportReport(fmt){
if(!currentReportId) return;
window.open('/reports/'+currentReportId+'/export/'+fmt,'_blank');
}
function loadTemplates(){
fetch('/reports/templates').then(r=>r.json()).then(d=>{
document.getElementById('templates-list').innerHTML=(d.templates||[]).map(t=>
`< div class = "card" style = "margin-bottom:0.5rem" >
< div style = "display:flex;justify-content:space-between;align-items:center" >
< div > < span class = "sev-badge sev-${t.severity}" > ${t.severity.toUpperCase()}< / span >
< strong style = "margin-left:0.5rem" > ${esc(t.title)}< / strong >
< span style = "color:var(--text-muted);font-size:0.8rem;margin-left:0.5rem" > CVSS ${t.cvss}< / span > < / div >
< / div >
< p style = "font-size:0.8rem;margin:0.3rem 0;color:var(--text-secondary)" > ${esc(t.description)}< / p >
< div style = "font-size:0.75rem;color:var(--text-muted)" > ${(t.references||[]).join(', ')}< / div >
< / div > `).join('');
});
}
loadReports();
function esc(s){return s?String(s).replace(/&/g,'& ').replace(/< /g,'< ').replace(/>/g,'> ').replace(/"/g,'" '):''}
< / script >
{% endblock %}