mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-10-08 00:51:09 +02:00
feat: vulnerability-research mode — hand it a repo, it hunts a novel CVE
New --research mode for whitebox/greybox (REPL /research, web 🔬 checkbox, or auto-detected from natural-language focus/objective in PT/EN). Steers the source review to find a NOVEL, CVE-reportable issue instead of a known one: - WHITEBOX_RESEARCH_DOCTRINE: pin version/commit; research known CVEs/advisories (SECURITY.md, CHANGELOG, GHSA, NVD, git history) to de-duplicate; patch-diff / n-day->0-day variant analysis (incomplete fixes, bypasses of a new check, sibling sinks, reintroductions); strict novelty gate (each finding states novel-why + checked-against); benign PoC + dynamic confirm on greybox. - RunConfig.research + is_research_intent(); injected in run_whitebox and the greybox code-review half. - 6 research skills (code/): known_cve_dedup, patch_diff_variant, attack_surface_map, source_to_sink_taint, logic_authz_flaw, dependency_nday_reachability. - Methodology modeled on a real AppSec-research workflow (no specifics copied). 479 agents, 421 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
ed4105999e
commit
9076d30c59
14 files changed
+412
-11
No files matched your search
@@ -318,6 +318,9 @@ enum Cmd {
|
||||
/// Economy preset for a short, low-cost review (see `run --quick`).
|
||||
#[arg(long)]
|
||||
quick: bool,
|
||||
/// Vulnerability-research mode: hunt a NOVEL, CVE-reportable bug (known-CVE dedup + patch-diff variant analysis).
|
||||
#[arg(long)]
|
||||
research: bool,
|
||||
#[arg(long)]
|
||||
offline: bool,
|
||||
#[arg(long)]
|
||||
@@ -359,6 +362,9 @@ enum Cmd {
|
||||
/// Economy preset for a short, low-cost test (see `run --quick`).
|
||||
#[arg(long)]
|
||||
quick: bool,
|
||||
/// Vulnerability-research mode (see `whitebox --research`).
|
||||
#[arg(long)]
|
||||
research: bool,
|
||||
#[arg(long)]
|
||||
offline: bool,
|
||||
#[arg(long)]
|
||||
@@ -880,7 +886,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let ig = harness::integrations::Integrations::load(&repl::proj_dir());
|
||||
post_integrations(&ig, &url, &out, jira, false, None).await;
|
||||
}
|
||||
Cmd::Whitebox { path, models, max_agents, vote_n, chain_depth, recon, quick, offline, subscription, jira, only, verbose } => {
|
||||
Cmd::Whitebox { path, models, max_agents, vote_n, chain_depth, recon, quick, research, offline, subscription, jira, only, verbose } => {
|
||||
let path = resolve_source(&base, &path)?; // local path OR github URL/owner/repo
|
||||
let mut cfg = RunConfig::new(&path);
|
||||
cfg.max_agents = max_agents;
|
||||
@@ -891,6 +897,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
cfg.subscription = subscription;
|
||||
cfg.verbose = verbose;
|
||||
cfg.pinned = parse_only(&only);
|
||||
cfg.research = research;
|
||||
if quick { apply_quick(&mut cfg); }
|
||||
if !models.is_empty() {
|
||||
cfg.models = models;
|
||||
@@ -900,7 +907,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let ig = harness::integrations::Integrations::load(&repl::proj_dir());
|
||||
post_integrations(&ig, &path, &out, jira, false, None).await;
|
||||
}
|
||||
Cmd::Greybox { repo, url, models, creds, focus, max_agents, vote_n, chain_depth, recon, quick, offline, subscription, mcp, only, verbose } => {
|
||||
Cmd::Greybox { repo, url, models, creds, focus, max_agents, vote_n, chain_depth, recon, quick, research, offline, subscription, mcp, only, verbose } => {
|
||||
let repo = resolve_source(&base, &repo)?; // local path OR github URL/owner/repo
|
||||
let url = if url.starts_with("http") { url } else { format!("https://{url}") };
|
||||
let mut cfg = RunConfig::new(&url);
|
||||
@@ -914,6 +921,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
cfg.verbose = verbose;
|
||||
cfg.instructions = focus;
|
||||
cfg.pinned = parse_only(&only);
|
||||
cfg.research = research;
|
||||
if quick { apply_quick(&mut cfg); }
|
||||
if !models.is_empty() {
|
||||
cfg.models = models;
|
||||
|
||||
@@ -152,7 +152,7 @@ pub(crate) const ACCEPTED: &[&str] = &[
|
||||
"/history", "/idle", "/inscope", "/instructions", "/integration", "/integrations", "/key", "/log",
|
||||
"/logs", "/mcp", "/memory", "/model", "/models", "/objective", "/objectives", "/observe",
|
||||
"/observe-only", "/offline",
|
||||
"/onboard", "/only", "/oos", "/outofscope", "/policy", "/providers", "/proxy", "/quick", "/economy", "/eco", "/q", "/quit", "/recon",
|
||||
"/onboard", "/only", "/oos", "/outofscope", "/policy", "/providers", "/proxy", "/research", "/quick", "/economy", "/eco", "/q", "/quit", "/recon",
|
||||
"/pause", "/repo", "/report", "/results", "/resume", "/retest", "/revalidate", "/run", "/runs",
|
||||
"/scope", "/scope-out", "/show", "/status", "/stop", "/sub", "/subscription", "/target",
|
||||
"/temp-email", "/tempmail", "/theme", "/timeout", "/ua", "/url", "/useragent", "/validate",
|
||||
@@ -163,7 +163,7 @@ pub(crate) const ACCEPTED: &[&str] = &[
|
||||
const COMMANDS: &[&str] = &[
|
||||
"/help", "/onboard", "/show", "/config", "/providers", "/model", "/key", "/sub", "/target",
|
||||
"/repo", "/auth", "/creds", "/focus", "/objective", "/scope-out", "/attach", "/context", "/mcp", "/offline",
|
||||
"/quick", "/economy", "/eco", "/votes", "/chain", "/recon", "/tempmail", "/timeout", "/proxy", "/burp", "/ua", "/agents", "/only", "/theme", "/clear", "/run", "/stop", "/pause", "/continue", "/runs", "/results", "/report",
|
||||
"/research", "/quick", "/economy", "/eco", "/votes", "/chain", "/recon", "/tempmail", "/timeout", "/proxy", "/burp", "/ua", "/agents", "/only", "/theme", "/clear", "/run", "/stop", "/pause", "/continue", "/runs", "/results", "/report",
|
||||
"/status", "/logs", "/diff", "/retest", "/validate", "/finding", "/expand", "/integrations",
|
||||
"/memory", "/forget", "/graph", "/inscope", "/observe", "/guardrail", "/policy",
|
||||
"/capability", "/audit", "/quit",
|
||||
@@ -268,6 +268,7 @@ struct Session {
|
||||
max_agents: usize,
|
||||
chain_depth: usize,
|
||||
recon_intensity: usize,
|
||||
research: bool,
|
||||
/// Opt-in disposable email (mail.tm) for register flows needing a confirmation code.
|
||||
temp_email: bool,
|
||||
/// Idle guardrail: stop a run if no NEW finding lands in this many seconds
|
||||
@@ -320,6 +321,7 @@ impl Default for Session {
|
||||
max_agents: 0,
|
||||
chain_depth: 2,
|
||||
recon_intensity: 3,
|
||||
research: false,
|
||||
temp_email: false,
|
||||
idle_secs: 300, // 5-minute idle guardrail by default
|
||||
proxy: None,
|
||||
@@ -846,6 +848,13 @@ pub async fn repl(base: &Path, auth: SessionAuth) -> anyhow::Result<()> {
|
||||
if arg.is_empty() { println!(" recon intensity: {} ({}) — set with /recon <1-4> [1 quick · 2 standard · 3 deep · 4 exhaustive]", s.recon_intensity, lvl(s.recon_intensity)); }
|
||||
else { s.recon_intensity = arg.parse::<usize>().unwrap_or(s.recon_intensity).clamp(1, 4); println!(" recon intensity: {} ({}) — more rounds, more enumeration, auto-installs tools", s.recon_intensity, lvl(s.recon_intensity)); }
|
||||
}
|
||||
"/research" => {
|
||||
match arg.trim() {
|
||||
"on" | "true" | "1" => { s.research = true; println!(" \x1b[1;36m🔬 research mode ON\x1b[0m — whitebox/greybox will hunt a NOVEL, CVE-reportable bug (known-CVE dedup + patch-diff variant analysis)"); }
|
||||
"off" | "false" | "0" => { s.research = false; println!(" research mode off"); }
|
||||
_ => println!(" research mode: {} — /research on|off (for whitebox/greybox: find a new CVE, not a known one)", if s.research { "\x1b[36mon\x1b[0m" } else { "\x1b[2moff\x1b[0m" }),
|
||||
}
|
||||
}
|
||||
"/quick" | "/economy" | "/eco" => {
|
||||
// Economy preset for a short, low-cost test — the single switch
|
||||
// for "fast and cheap" instead of tuning each knob. The big
|
||||
@@ -1471,6 +1480,7 @@ async fn run(base: &Path, s: &Session, history: &mut Vec<RunRecord>) {
|
||||
cfg.vote_n = s.vote_n;
|
||||
cfg.chain_depth = s.chain_depth;
|
||||
cfg.recon_intensity = s.recon_intensity;
|
||||
cfg.research = s.research;
|
||||
cfg.temp_email = s.temp_email;
|
||||
cfg.proxy = s.proxy.clone();
|
||||
cfg.user_agent = s.user_agent.clone();
|
||||
@@ -1560,6 +1570,7 @@ async fn start_background(base: &Path, s: &Session, reader: &mut Reader,
|
||||
cfg.vote_n = s.vote_n;
|
||||
cfg.chain_depth = s.chain_depth;
|
||||
cfg.recon_intensity = s.recon_intensity;
|
||||
cfg.research = s.research;
|
||||
cfg.temp_email = s.temp_email;
|
||||
cfg.proxy = s.proxy.clone();
|
||||
cfg.user_agent = s.user_agent.clone();
|
||||
@@ -2236,6 +2247,7 @@ fn help() {
|
||||
h("/votes <n>", "number of validator votes per finding");
|
||||
h("/chain <n>", "attack-chain depth (post-exploitation pivots; 0 = off)");
|
||||
h("/recon <1-4>", "recon intensity: 1 quick · 2 standard · 3 deep · 4 exhaustive (installs tools)");
|
||||
h("/research", "whitebox/greybox: hunt a NOVEL, CVE-reportable bug (known-CVE dedup + patch-diff variant analysis)");
|
||||
h("/quick", "economy preset: short, low-cost run (1 voter · 1 chain round · light recon · ≤6 agents)");
|
||||
h("/tempmail on|off", "opt-in disposable inbox (mail.tm) to read a register confirmation code");
|
||||
h("/timeout <min>", "idle guardrail: stop if no new finding in <min> (0 = off)");
|
||||
|
||||
Reference in new issue
Block a user