mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-08-14 21:50:21 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
105c62af61 | ||
|
|
a0a477a2bf |
@@ -108,3 +108,4 @@ data/repl_history.txt
|
||||
# Cloned source repos (whitebox/greybox from a git URL)
|
||||
repos/
|
||||
neurosploit-rs/repos/
|
||||
target/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 align="center">🧠 NeuroSploit v3.6.7</h1>
|
||||
<h1 align="center">🧠 NeuroSploit v3.6.8</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/22624?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-22624" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/22624/daily?language=Python" alt="JoasASantos%2FNeuroSploit | Trendshift" width="250" height="55"/></a>
|
||||
@@ -12,7 +12,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/Version-3.6.7-blue?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/Version-3.6.8-blue?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/Harness-Rust%20%7C%20tokio-e6b673?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/License-MIT-green?style=flat-square">
|
||||
<img src="https://img.shields.io/badge/MD%20Agents-435-red?style=flat-square">
|
||||
|
||||
+17
-2
@@ -1,11 +1,26 @@
|
||||
# NeuroSploit v3.6.7 — Release Notes
|
||||
# NeuroSploit v3.6.8 — Release Notes
|
||||
|
||||
**Release Date:** August 2026
|
||||
**Codename:** Chain & Exploit
|
||||
**License:** MIT
|
||||
**Credits:** Joas A Santos & Red Team Leaders
|
||||
|
||||
## Highlights
|
||||
## v3.6.8 — Bugfix: Ollama error handling, empty-evidence validation, single-model warnings
|
||||
|
||||
- **Better Ollama/local provider error messages.** Connection-refused and timeout
|
||||
errors now name the provider, URL, and suggest checking if the server is running.
|
||||
Previously showed raw reqwest errors.
|
||||
- **Empty-evidence findings skip the vote and go straight to `needs-review`.**
|
||||
Findings with no evidence are unverifiable by the adversarial validator (which
|
||||
always rejects "no evidence" per its system prompt). Now they bypass the vote
|
||||
and are flagged for human review instead of being silently dropped.
|
||||
- **Single-model + vote_n=1 warning.** When only one model is configured and
|
||||
vote_n is 1, the pipeline emits a warning that validation is weaker (same model
|
||||
validates its own findings).
|
||||
|
||||
---
|
||||
|
||||
## v3.6.7 Highlights
|
||||
|
||||
- **CVE exploitation pipeline — 4 new agents.** `cve_version_fingerprint` (pin
|
||||
exact versions) → `cve_research_analyst` (map to NVD/GHSA, judge reachability) →
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
# NeuroSploit — Tutorial & User Guide (v3.6.5)
|
||||
# NeuroSploit — Tutorial & User Guide (v3.6.8)
|
||||
|
||||
A complete, hands-on guide to installing, configuring and running NeuroSploit —
|
||||
the autonomous, multi-model penetration-testing harness.
|
||||
@@ -98,7 +98,7 @@ Agents **degrade gracefully**: if `rustscan` is absent they use `nmap`; if neith
|
||||
### Verify
|
||||
|
||||
```bash
|
||||
neurosploit --version # neurosploit 3.6.5
|
||||
neurosploit --version # neurosploit 3.6.8
|
||||
neurosploit agents # {"vulns":241,...,"ai":30,...,"total":430}
|
||||
neurosploit models # all providers & models
|
||||
```
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ function Ok ($m) { Write-Host " + $m" -ForegroundColor Green }
|
||||
function Warn($m){ Write-Host " ! $m" -ForegroundColor Yellow }
|
||||
|
||||
Write-Host ""
|
||||
Write-Host " NeuroSploit installer (Windows) — v3.6.1" -ForegroundColor Cyan
|
||||
Write-Host " NeuroSploit installer (Windows) — v3.6.8" -ForegroundColor Cyan
|
||||
|
||||
# arch → asset arch (only x64 prebuilt today; arm64 falls back to source)
|
||||
$rawArch = $env:PROCESSOR_ARCHITECTURE
|
||||
@@ -29,7 +29,7 @@ $ref = $env:NEUROSPLOIT_REF
|
||||
if (-not $ref) {
|
||||
try { $ref = (Invoke-RestMethod "https://api.github.com/repos/$slug/releases/latest").tag_name } catch { }
|
||||
}
|
||||
if (-not $ref) { $ref = "v3.6.1" }
|
||||
if (-not $ref) { $ref = "v3.6.8" }
|
||||
Say "Release: $ref"
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
||||
|
||||
Generated
+2
-2
@@ -871,7 +871,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neurosploit"
|
||||
version = "3.6.7"
|
||||
version = "3.6.8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -888,7 +888,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "neurosploit-harness"
|
||||
version = "3.6.7"
|
||||
version = "3.6.8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures",
|
||||
|
||||
@@ -3,7 +3,7 @@ members = ["crates/harness", "app"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "3.6.7"
|
||||
version = "3.6.8"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/JoasASantos/NeuroSploit"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! NeuroSploit v3.6.7 — interactive harness + CLI (`run` / `whitebox` / `agents` / `models`).
|
||||
//! NeuroSploit v3.6.8 — interactive harness + CLI (`run` / `whitebox` / `agents` / `models`).
|
||||
|
||||
mod repl;
|
||||
mod tui;
|
||||
@@ -11,8 +11,8 @@ use std::path::{Path, PathBuf};
|
||||
#[command(
|
||||
name = "neurosploit",
|
||||
version,
|
||||
about = "NeuroSploit v3.6.7 — multi-model autonomous pentest harness",
|
||||
long_about = "NeuroSploit v3.6.7 — a Rust multi-model harness that drives a pool of LLMs \
|
||||
about = "NeuroSploit v3.6.8 — multi-model autonomous pentest harness",
|
||||
long_about = "NeuroSploit v3.6.8 — a Rust multi-model harness that drives a pool of LLMs \
|
||||
(API key or local subscription: Claude/Codex/Gemini/Grok) to autonomously test a target. \
|
||||
After recon it INTELLIGENTLY selects only the agents matching the discovered surface, runs \
|
||||
them in parallel, then validates every finding by cross-model voting before reporting.\n\n\
|
||||
@@ -765,7 +765,7 @@ pub(crate) fn spawn_engagement(base: &Path, mut cfg: RunConfig, mcp: bool, mode:
|
||||
println!(" │ ua : {ua}");
|
||||
write_status(&workdir, "running", &format!("\"target\":{:?}", cfg.target));
|
||||
|
||||
println!(" ┌─ NeuroSploit v3.6.7 · by Joas A Santos & Red Team Leaders");
|
||||
println!(" ┌─ NeuroSploit v3.6.8 · by Joas A Santos & Red Team Leaders");
|
||||
println!(" │ run id : {run_id}");
|
||||
println!(" │ target : {}", cfg.target);
|
||||
println!(" │ models : {}", cfg.models.join(", "));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! NeuroSploit v3.6.7 — interactive session (Claude-Code / Codex / Cursor-CLI style).
|
||||
//! NeuroSploit v3.6.8 — interactive session (Claude-Code / Codex / Cursor-CLI style).
|
||||
//!
|
||||
//! Launched when `neurosploit` runs with no subcommand. A persistent REPL with
|
||||
//! real line editing (arrow-key history recall, Ctrl-A/E/K, paste), model
|
||||
@@ -370,7 +370,7 @@ pub async fn repl(base: &Path) -> anyhow::Result<()> {
|
||||
let backends = harness::installed_cli_backends();
|
||||
println!("\x1b[1m");
|
||||
println!(" ███╗ ██╗███████╗██╗ ██╗██████╗ ██████╗");
|
||||
println!(" ████╗ ██║██╔════╝██║ ██║██╔══██╗██╔═══██╗ NeuroSploit v3.6.7");
|
||||
println!(" ████╗ ██║██╔════╝██║ ██║██╔══██╗██╔═══██╗ NeuroSploit v3.6.8");
|
||||
println!(" ██╔██╗ ██║█████╗ ██║ ██║██████╔╝██║ ██║ interactive harness");
|
||||
println!(" ██║╚██╗██║██╔══╝ ██║ ██║██╔══██╗██║ ██║ by Joas A Santos");
|
||||
println!(" ██║ ╚████║███████╗╚██████╔╝██║ ██║╚██████╔╝ & Red Team Leaders");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! NeuroSploit v3.6.7 — TUI "Mission Control" mode.
|
||||
//! NeuroSploit v3.6.8 — TUI "Mission Control" mode.
|
||||
//!
|
||||
//! Concurrent panels that update live while the engagement runs in the
|
||||
//! background, with a composer input that stays active during execution:
|
||||
|
||||
@@ -163,7 +163,20 @@ impl ChatClient {
|
||||
if !key.is_empty() {
|
||||
if azure { req = req.header("api-key", &key); } else { req = req.bearer_auth(&key); }
|
||||
}
|
||||
let resp = req.send().await?;
|
||||
let resp = req.send().await.map_err(|e| {
|
||||
if e.is_connect() {
|
||||
let local = matches!(p.key, "ollama" | "litellm" | "llamacpp");
|
||||
if local {
|
||||
anyhow!("{} connection refused at {} — is the server running? ({})", p.key, url, e)
|
||||
} else {
|
||||
anyhow!("{} connection error: {}", p.key, e)
|
||||
}
|
||||
} else if e.is_timeout() {
|
||||
anyhow!("{} request timed out (120s) for model '{}' — model may be too large for available memory", p.key, m.model)
|
||||
} else {
|
||||
anyhow!("{} request error: {}", p.key, e)
|
||||
}
|
||||
})?;
|
||||
let status = resp.status();
|
||||
let text = resp.text().await.unwrap_or_default();
|
||||
if !status.is_success() {
|
||||
|
||||
@@ -619,6 +619,9 @@ pub async fn run(cfg: RunConfig, lib: &Library, pool: &ModelPool, tx: Sender<Str
|
||||
let transcript = transcript_of(&raw);
|
||||
let candidates = dedup_findings(raw.iter().flat_map(|(_, _, f)| f.clone()).collect());
|
||||
let _ = tx.send(format!("{} candidate finding(s) (deduped) — validating by {}-model vote", candidates.len(), cfg.vote_n)).await;
|
||||
if pool.candidates.len() == 1 && cfg.vote_n <= 1 {
|
||||
let _ = tx.send("⚠ single-model panel with vote_n=1 — validation is weaker (same model validates its own findings). Consider --vote-n 2 or adding a second model for cross-validation.".into()).await;
|
||||
}
|
||||
|
||||
// ---- 4. Validate by N-model voting ---------------------------------
|
||||
let mut findings = validate(candidates, pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
@@ -1148,9 +1151,26 @@ fn heuristic_select(ranked: &[Agent], recon: &str, focus: &str, cap: usize) -> V
|
||||
}
|
||||
|
||||
async fn validate(candidates: Vec<Finding>, pool: &ModelPool, sys: &str, vote_n: usize, tx: &Sender<String>) -> Vec<Finding> {
|
||||
// Fast-track: findings with no evidence are unverifiable — skip the vote
|
||||
// and flag for human review instead of wasting a validator call that will
|
||||
// always reject ("default to rejected when uncertain" + empty evidence).
|
||||
let (have_evidence, no_evidence): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|f| {
|
||||
let e = f.evidence.trim();
|
||||
!e.is_empty() && e != "N/A" && e != "n/a" && e != "none" && e != "-"
|
||||
});
|
||||
let mut flagged: Vec<Finding> = no_evidence.into_iter().map(|mut f| {
|
||||
f.validated = false;
|
||||
f.review_status = "needs-review".into();
|
||||
f.review_reason = "no concrete evidence provided by agent — manual verification required".into();
|
||||
f.votes = "0/0".into();
|
||||
f
|
||||
}).collect();
|
||||
for f in &flagged {
|
||||
let _ = tx.send(format!("vote {} → needs-review (no evidence)", f.title)).await;
|
||||
}
|
||||
// Prefer a model other than the primary (likely finder) to adjudicate.
|
||||
let finder = pool.candidates.first().map(|m| m.label());
|
||||
let validated: Vec<Finding> = stream::iter(candidates)
|
||||
let validated: Vec<Finding> = stream::iter(have_evidence)
|
||||
.map(|mut f| {
|
||||
let txc = tx.clone();
|
||||
let finder = finder.clone();
|
||||
@@ -1184,7 +1204,9 @@ async fn validate(candidates: Vec<Finding>, pool: &ModelPool, sys: &str, vote_n:
|
||||
.collect()
|
||||
.await;
|
||||
// Keep confirmed AND needs-review (human decides); drop only zero-support noise.
|
||||
validated.into_iter().filter(|f| f.validated || f.review_status == "needs-review").collect()
|
||||
// Include no-evidence flagged findings so the human loop sees them.
|
||||
flagged.extend(validated.into_iter().filter(|f| f.validated || f.review_status == "needs-review"));
|
||||
flagged
|
||||
}
|
||||
|
||||
/// Adversarial refutation pass: every confirmed **High/Critical** finding is
|
||||
|
||||
@@ -28,7 +28,7 @@ cat <<'BANNER'
|
||||
|
||||
███╗ ██╗███████╗██╗ ██╗██████╗ ██████╗
|
||||
████╗ ██║██╔════╝██║ ██║██╔══██╗██╔═══██╗ NeuroSploit installer
|
||||
██╔██╗ ██║█████╗ ██║ ██║██████╔╝██║ ██║ v3.6.1 — Rust harness
|
||||
██╔██╗ ██║█████╗ ██║ ██║██████╔╝██║ ██║ v3.6.8 — Rust harness
|
||||
██║╚██╗██║██╔══╝ ██║ ██║██╔══██╗██║ ██║ by Joas A Santos
|
||||
██║ ╚████║███████╗╚██████╔╝██║ ██║╚██████╔╝ & Red Team Leaders
|
||||
╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝
|
||||
@@ -63,7 +63,7 @@ if [ -z "$REF" ]; then
|
||||
REF="$(dl "https://api.github.com/repos/${REPO_SLUG}/releases/latest" /dev/stdout 2>/dev/null \
|
||||
| grep -m1 '"tag_name"' | sed -E 's/.*"tag_name" *: *"([^"]+)".*/\1/' || true)"
|
||||
fi
|
||||
[ -z "$REF" ] && REF="v3.6.1"
|
||||
[ -z "$REF" ] && REF="v3.6.8"
|
||||
say "Release: $REF"
|
||||
|
||||
installed=0
|
||||
|
||||
Reference in New Issue
Block a user