mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-08-25 19:02:43 +02:00
Wizard's Asset step now opens with a required 'Engagement name' field (validated before advancing or launching). The name isn't a harness/CLI concept, so it's persisted server-side as runId -> name in .neurosploit/web-engagement-names.json (keyed off the CLI's own run id, captured from its 'run id : ns-...' log line) so the sidebar, live run header, and run detail can label a run by name instead of the raw target/run-id, surviving a server restart. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129WdYHccPsH27k5GGuwijd
318 lines
16 KiB
HTML
318 lines
16 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>NeuroSploit v4.0.0 — Console</title>
|
||
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🧠</text></svg>">
|
||
<link rel="stylesheet" href="/style.css" />
|
||
</head>
|
||
<body>
|
||
|
||
<div class="app">
|
||
|
||
<!-- ============ SIDEBAR ============ -->
|
||
<aside class="sidebar" id="sidebar">
|
||
<div class="sb-top">
|
||
<div class="brand"><span class="mark">NS</span> NeuroSploit</div>
|
||
<button class="icon-btn" id="btnThemeToggle" title="Toggle light / dark theme">☾</button>
|
||
</div>
|
||
|
||
<button class="sb-new" id="btnNewEngagement">+ New engagement</button>
|
||
|
||
<div class="sb-groups" id="sbGroups"><!-- populated by app.js --></div>
|
||
|
||
<div class="sb-bottom">
|
||
<span class="sb-version" id="sbVersion">v4.0.0</span>
|
||
<div class="sb-bottom-actions">
|
||
<button class="icon-btn" id="btnOpenAuth" title="Auth & API keys">🔑</button>
|
||
<button class="icon-btn" id="btnOpenRepl" title="Open REPL">❭_</button>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- ============ MAIN ============ -->
|
||
<main class="main">
|
||
|
||
<!-- ============ WIZARD (new engagement) ============ -->
|
||
<section class="wizard" id="wizardView">
|
||
<header class="topbar">
|
||
<div>
|
||
<div class="topbar-title">New engagement</div>
|
||
<div class="topbar-sub">Asset → Scope & Auth → Leads → Model & Run → Review</div>
|
||
</div>
|
||
<div class="topbar-spacer"></div>
|
||
<button class="btn" id="btnOpenAuth2">🔑 Auth & Keys</button>
|
||
</header>
|
||
|
||
<nav class="stepper" id="stepper">
|
||
<button class="step-tab active" data-step="0"><span class="n">1</span> Asset</button>
|
||
<button class="step-tab" data-step="1"><span class="n">2</span> Scope & Auth</button>
|
||
<button class="step-tab" data-step="2"><span class="n">3</span> Leads</button>
|
||
<button class="step-tab" data-step="3"><span class="n">4</span> Model & Run</button>
|
||
<button class="step-tab" data-step="4"><span class="n">5</span> Review</button>
|
||
</nav>
|
||
|
||
<div class="wizard-body">
|
||
|
||
<!-- Step 1 — Asset -->
|
||
<div class="wizard-panel" data-panel="0">
|
||
<div class="field-group">
|
||
<label class="field-label">Engagement name</label>
|
||
<input id="fieldName" type="text" placeholder="e.g. Keystone – Digital Banking" />
|
||
<div class="field-help">Identifies this engagement in the sidebar and run history — required.</div>
|
||
</div>
|
||
<div>
|
||
<div class="section-title">What are you testing?</div>
|
||
<div class="section-desc">Pick the engagement type — this decides which CLI subcommand runs underneath.</div>
|
||
</div>
|
||
<div class="mode-tiles" id="modeTiles">
|
||
<button class="mode-tile" data-mode="run"><span class="t">Black-box</span><span class="d">URL only — recon-driven</span></button>
|
||
<button class="mode-tile" data-mode="whitebox"><span class="t">White-box</span><span class="d">Source repo — SAST agents</span></button>
|
||
<button class="mode-tile" data-mode="greybox"><span class="t">Grey-box</span><span class="d">URL + source together</span></button>
|
||
<button class="mode-tile" data-mode="host"><span class="t">Host / Infra</span><span class="d">IP — Linux/Windows/AD</span></button>
|
||
<button class="mode-tile" data-mode="aitest"><span class="t">AI / LLM</span><span class="d">Live AI agent or MCP endpoint</span></button>
|
||
</div>
|
||
|
||
<div class="field-group" id="fieldTargetGroup">
|
||
<label class="field-label" id="targetLabel">Target URL</label>
|
||
<input id="fieldTarget" type="text" placeholder="https://target.example.com" />
|
||
<div class="field-help" id="targetHelp">The application, host, or endpoint to test.</div>
|
||
</div>
|
||
<div class="field-group" id="fieldRepoGroup" hidden>
|
||
<label class="field-label">Source repo</label>
|
||
<input id="fieldRepo" type="text" placeholder="owner/repo, a GitHub URL, or a local path" />
|
||
<div class="field-help">Cloned automatically if it's a GitHub URL or owner/repo shorthand.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 2 — Scope & Auth -->
|
||
<div class="wizard-panel" data-panel="1" hidden>
|
||
<div>
|
||
<div class="section-title">Objective & focus</div>
|
||
<div class="section-desc">Steers what the agents prioritise and what counts as impact.</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<label class="field-label">Objective</label>
|
||
<textarea id="fieldObjective" placeholder="e.g. Pre-launch review of the checkout flow — prove any path to unauthorized order access."></textarea>
|
||
</div>
|
||
<div class="field-group">
|
||
<label class="field-label">Focus</label>
|
||
<textarea id="fieldFocus" placeholder="e.g. Prioritize the paths most likely to cause data leakage."></textarea>
|
||
</div>
|
||
<div class="field-group">
|
||
<label class="field-label">Out of scope</label>
|
||
<textarea id="fieldOutOfScope" placeholder="Hosts, paths, or techniques the agents must not touch."></textarea>
|
||
</div>
|
||
<div>
|
||
<div class="section-title">Authentication</div>
|
||
<div class="section-desc">Test as a logged-in user. Configured in the <button class="btn btn-sm" id="btnOpenAuth3" style="display:inline">🔑 Auth & Keys</button> menu.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 3 — Leads -->
|
||
<div class="wizard-panel" data-panel="2" hidden style="max-width: none;">
|
||
<div>
|
||
<div class="section-title">Set the action plan</div>
|
||
<div class="section-desc">Toggle specific leads to test, or leave everything off to let recon-driven auto-selection choose.</div>
|
||
</div>
|
||
<div class="lead-toolbar">
|
||
<div class="search-wrap">
|
||
<span class="search-icon">⌕</span>
|
||
<input id="leadSearch" type="text" placeholder="Search lead" />
|
||
</div>
|
||
<div class="chips">
|
||
<button class="chip chip-active" data-filter="all">All <span id="chipAll">0</span></button>
|
||
<button class="chip" data-filter="selected">Selected <span id="chipSelected">0</span></button>
|
||
<button class="chip" data-filter="excluded">Excluded <span id="chipExcluded">0</span></button>
|
||
</div>
|
||
<div class="topbar-spacer"></div>
|
||
<button class="btn btn-sm" id="btnCustomLead">+ Custom lead</button>
|
||
</div>
|
||
<div class="custom-leads" id="customLeadsList"></div>
|
||
<div class="categories" id="categories"><!-- populated --></div>
|
||
</div>
|
||
|
||
<!-- Step 4 — Model & Run -->
|
||
<div class="wizard-panel" data-panel="3" hidden>
|
||
<div>
|
||
<div class="section-title">Model</div>
|
||
<div class="section-desc">Pick a provider and model from the harness's live catalog.</div>
|
||
</div>
|
||
<div class="field-row">
|
||
<div class="field-group">
|
||
<label class="field-label">Provider</label>
|
||
<select id="fieldProvider"></select>
|
||
</div>
|
||
<div class="field-group">
|
||
<label class="field-label">Model</label>
|
||
<select id="fieldModelSelect"></select>
|
||
</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<label class="field-label">Auth mode</label>
|
||
<div class="auth-mode-toggle" id="authModeToggle">
|
||
<button data-mode="api" class="selected">API key</button>
|
||
<button data-mode="subscription">Subscription (local CLI login)</button>
|
||
</div>
|
||
<div class="field-help" id="authModeHelp">Uses the API key set in Auth & Keys for this provider.</div>
|
||
</div>
|
||
<div class="check-row"><input type="checkbox" id="fieldMcp" /> <label for="fieldMcp">Playwright MCP (browser tool access, subscription backends only)</label></div>
|
||
|
||
<div>
|
||
<div class="section-title">Run settings</div>
|
||
</div>
|
||
<div class="field-row">
|
||
<div class="field-group"><label class="field-label">Votes</label><input class="narrow" id="fieldVotes" type="number" min="1" max="9" value="3" /></div>
|
||
<div class="field-group"><label class="field-label">Chain depth</label><input class="narrow" id="fieldChain" type="number" min="0" max="5" value="2" /></div>
|
||
<div class="field-group"><label class="field-label">Recon intensity</label>
|
||
<select class="narrow" id="fieldRecon">
|
||
<option value="1">1 · quick</option>
|
||
<option value="2">2 · standard</option>
|
||
<option value="3" selected>3 · deep</option>
|
||
<option value="4">4 · exhaustive</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 5 — Review -->
|
||
<div class="wizard-panel" data-panel="4" hidden>
|
||
<div>
|
||
<div class="section-title">Review</div>
|
||
<div class="section-desc">Confirm before launching — this spawns the real CLI harness.</div>
|
||
</div>
|
||
<div class="review-grid" id="reviewGrid"></div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<footer class="wizard-footer">
|
||
<div class="summary-line" id="wizardSummary"></div>
|
||
<div style="display:flex; gap:8px;">
|
||
<button class="btn" id="btnStepBack">← Back</button>
|
||
<button class="btn btn-primary" id="btnStepNext">Next →</button>
|
||
<button class="btn btn-primary" id="btnLaunch" hidden>Start Exploitation →</button>
|
||
</div>
|
||
</footer>
|
||
</section>
|
||
|
||
<!-- ============ LIVE RUN ============ -->
|
||
<section class="runpage" id="liveView" hidden>
|
||
<header class="run-head">
|
||
<div>
|
||
<div class="run-target" id="liveTarget">—</div>
|
||
<div class="run-meta" id="liveTargetSub" style="font-family: var(--mono);"></div>
|
||
<div class="run-meta"><span class="phase-dot" id="phaseDot"></span><span id="livePhase">starting</span></div>
|
||
</div>
|
||
<div class="run-actions">
|
||
<a class="btn" id="btnOpenReport" target="_blank" hidden>Open report</a>
|
||
<button class="btn btn-danger" id="btnStopRun">Stop</button>
|
||
<button class="btn" id="btnBackToBoard">← New engagement</button>
|
||
</div>
|
||
</header>
|
||
<div class="progress-wrap">
|
||
<div class="progress-bar"><div class="progress-fill" id="progressFill"></div></div>
|
||
<div class="progress-label" id="progressLabel">0 / 0 agents</div>
|
||
</div>
|
||
<nav class="run-tabs">
|
||
<button class="run-tab active" data-tab="findings">Findings <span id="liveFindingsCount">0</span></button>
|
||
<button class="run-tab" data-tab="attackpath">Generative Attack Path Chaining</button>
|
||
<button class="run-tab" data-tab="log">Activity log</button>
|
||
</nav>
|
||
<div class="run-body">
|
||
<div class="run-tab-panel" data-tabpanel="findings"><table class="data-table" id="liveFindingsTable"><thead><tr><th>Severity</th><th>Title</th><th>Endpoint</th><th>CWE</th><th>Agent</th><th>Conf.</th></tr></thead><tbody></tbody></table><div class="empty-state" id="liveFindingsEmpty">No validated findings yet.</div></div>
|
||
<div class="run-tab-panel" data-tabpanel="attackpath" hidden><div id="liveAttackPath"></div></div>
|
||
<div class="run-tab-panel" data-tabpanel="log" hidden><div class="log-panel" id="logList" style="height: 100%;"></div></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ============ RUN DETAIL (past run) ============ -->
|
||
<section class="runpage" id="detailView" hidden>
|
||
<header class="run-head">
|
||
<div>
|
||
<div class="run-target" id="detailTarget">—</div>
|
||
<div class="run-meta" id="detailTargetSub" style="font-family: var(--mono);"></div>
|
||
<div class="run-meta"><span class="phase-dot static" id="detailDot"></span><span id="detailState">—</span></div>
|
||
</div>
|
||
<div class="run-actions">
|
||
<a class="btn" id="detailOpenReport" target="_blank" hidden>Open report</a>
|
||
<button class="btn" id="btnDetailBack">← New engagement</button>
|
||
</div>
|
||
</header>
|
||
<nav class="run-tabs">
|
||
<button class="run-tab active" data-tab="findings">Findings <span id="detailFindingsCount">0</span></button>
|
||
<button class="run-tab" data-tab="attackpath">Generative Attack Path Chaining</button>
|
||
</nav>
|
||
<div class="run-body">
|
||
<div class="run-tab-panel" data-tabpanel="findings"><table class="data-table" id="detailFindingsTable"><thead><tr><th>Severity</th><th>Title</th><th>Endpoint</th><th>CWE</th><th>Agent</th><th>Conf.</th></tr></thead><tbody></tbody></table><div class="empty-state" id="detailFindingsEmpty">No validated findings.</div></div>
|
||
<div class="run-tab-panel" data-tabpanel="attackpath" hidden><div id="detailAttackPath"></div></div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
</div>
|
||
|
||
<!-- ============ AUTH & KEYS MODAL ============ -->
|
||
<div class="modal-overlay" id="authModal" hidden>
|
||
<div class="modal">
|
||
<div class="modal-head">
|
||
<div class="title">Auth & Keys</div>
|
||
<button class="icon-btn" id="btnCloseAuth">✕</button>
|
||
</div>
|
||
<div class="modal-tabs">
|
||
<button class="modal-tab active" data-mtab="target">Target auth</button>
|
||
<button class="modal-tab" data-mtab="keys">API keys</button>
|
||
<button class="modal-tab" data-mtab="creds">Creds file</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="modal-panel" data-mpanel="target">
|
||
<div class="field-group">
|
||
<label class="field-label">Auth header</label>
|
||
<input id="authHeader" type="text" placeholder="Authorization: Bearer <token> or Cookie: session=..." />
|
||
<div class="field-help">Used so agents test as a logged-in user. Kept only for this session, sent to the CLI as an ephemeral creds file.</div>
|
||
</div>
|
||
<div class="field-group">
|
||
<label class="field-label">Named roles (multi-identity access-control testing)</label>
|
||
<div class="role-list" id="roleList"></div>
|
||
<button class="btn btn-sm" id="btnAddRole" style="align-self:flex-start;">+ Add role</button>
|
||
<div class="field-help">Two or more roles enable IDOR/BOLA/BFLA cross-role testing.</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-panel" data-mpanel="keys" hidden>
|
||
<div class="field-help" style="margin-bottom:12px;">Keys are kept in this server process's memory only — never written to disk. Cleared on restart.</div>
|
||
<div id="providerKeyList"></div>
|
||
</div>
|
||
<div class="modal-panel" data-mpanel="creds" hidden>
|
||
<div class="field-group">
|
||
<label class="field-label">creds.yaml path (overrides target auth above)</label>
|
||
<input id="credsPath" type="text" placeholder="creds.yaml" />
|
||
<div class="field-help">An explicit file on disk — see neurosploit-rs/creds.example.yaml for the schema (jwt/header/cookie/login/roles/ssh/windows/cloud).</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ REPL DRAWER ============ -->
|
||
<div class="repl-drawer" id="replDrawer" hidden>
|
||
<div class="repl-head">
|
||
<span>NeuroSploit CLI harness — REPL</span>
|
||
<div>
|
||
<button class="icon-btn" id="btnReplRestart" title="Restart session">⟲</button>
|
||
<button class="icon-btn" id="btnReplClose" title="Close">✕</button>
|
||
</div>
|
||
</div>
|
||
<div class="repl-output" id="replOutput"></div>
|
||
<div class="repl-input-row">
|
||
<span class="repl-prompt">❭</span>
|
||
<input id="replInput" type="text" autocomplete="off" spellcheck="false" placeholder="/help · /run · /status · or describe it in plain language" />
|
||
</div>
|
||
</div>
|
||
|
||
<button class="fab" id="fabRepl" title="Open REPL">❭_</button>
|
||
|
||
<script src="/app.js"></script>
|
||
</body>
|
||
</html>
|