Quella degli AI pentest tools è una categoria esplosa nel 2026.
Recenti censimenti contano decine di progetti open source che promettono pentest autonomo, di creare documentazione di qualità e segnalare vulnerabilità, nonostante un benchmark di Aprile parla di poche prove a sostegno di queste promesse (https://appsecsanta.com/research/ai-pentesting-agents-2026), (https://escape.tech/blog/benchmarking-agentic-ai-pentesting-tools/)) .
Volevo testare i più popolari su Github, quindi ho scaricato tre tool e li ho indirizzati verso lo stesso target con un'istruzione identica verificando a mano tutto quello che producono
il target è OWASP Juice Shop 20.2 di Bjoern Kimminich, una web app ecommerce finta con decine di vulnerabilità note, ospitata in un container Docker locale da resettare a zero prima di ogni tool.
docker run -d -p 3000:3000 --name juiceshop bkimminich/juice-shop
Prompt identico, con richiesta esplicita di exploitation e di PoC (Proof of concept) funzionanti su quattro cose: CORS, hash MD5 nel JWT, directory listing su /ftp/, lista utenti da /api/Users
Nota di rete: host.docker.internal punta al gateway 172.17.0.1 non al container. corretto con l'indirizzo giusto dall'interno di un sandbox Docker 172.17.0.2:3000.
Premesse e presupposti per ciò che segue: ho usato solo modelli gratuiti e recenti
Non è il massimo di ciò che questi tool possono fare, ma è come rendono con la configurazione che sceglierebbe chiunque voglia testarli prima di portarli in produzione.
Inoltre, un modello di fascia alta maschera i difetti dell'architettura: se il ragionamento è abbastanza buono da non allucinare, il livello di validazione non viene mai messo alla prova e sembra funzionare anche quando non fa niente
Con un modello debole invece le allucinazioni arrivano davvero, e si vede se il tool le intercetta con un double check o le certifica.
È uno stress test della struttura di controllo: la domanda non è "quanto è bravo l'LLM", ma è "quanto regge il tool quando l'LLM sbaglia". Su un ingaggio vero l'LLM sbaglia comunque, prima o poi
Inoltre, ho utilizzato toolkit con logiche e popolarità completamente diverse tra loro per coprire ogni casistica.
Strix
Strix è un tool CLI basato su più agenti AI orchestrati. Lo punti su un target e fa ricognizione, sfruttamento e validazione, con proof of concept veri e non solo segnalazioni teoriche.
Gira in Docker e usa un LLM esterno (obbligatorio passare un'API key) come motore di ragionamento quindi il modello lo scegli e paghi tu. Il progetto su Git ha licenza Apache 2.0, 59.7k stelle, uno sviluppo attivo e community
il toolkit interno include Caido come proxy HTTP, ffuf, katana, un browser pilotabile e un sandbox Python per scrivere exploit.
curl -sSL https://strix.ai/install | bash
Quali LLM funzionano davvero
Strix dichiara "serve una API key da un qualsiasi provider supportato". In pratica però, su cinque provider testati ne funziona uno in media. questa parte mi ha portato via più tempo di tutto il resto messo insieme.
| Provider | Modello | Esito |
|---|---|---|
| Ollama locale | qwen3:8b | funziona ma impraticabile, ~44 min al primo tool-call |
| Gemini | qualsiasi | 404 costante, bug aperto contro Strix |
| Groq | qualsiasi | JSON schema invalido su un tool interno |
| Cerebras | qualsiasi | payment required nonostante il free tier pubblicizzato |
| OpenRouter | minimax-m3:free | funziona |
Su Ollama locale il primo scan restava fermo: il modello rispondeva a parole invece di invocare i tool. ho provato ad isolare il problema con una chiamata secca a /api/chat con un tool finto:
"tool_calls":[{"id":"call_wv1vaobc","function":{"name":"get_weather",...
Il tool calling funziona perfettamente. non è il modello ma è il carico di contesto agentico di Strix che lo fa collassare.
OLLAMA_CONTEXT_LENGTH vuoto, di default è a 2048 token, mentre il system prompt di Strix ne usa molti di più. alzato a 16384 l'agente si è sbloccato.
Costo: circa 44 minuti di CPU solo per arrivare al primo tool-call. Su hardware consumer senza GPU un 8B locale rende Strix completamente impraticabile per tempi, prima ancora di poter valutare la qualità dei risultati.
Su Groq l'errore è più interessante:
litellm.BadRequestError: GroqException - invalid JSON schema for tool
view_agent_graph, tools[24].function.parameters: 'required' present but
'properties' is missing
Groq applica una validazione JSON schema più stretta degli altri provider e uno dei tool interni di Strix ha lo schema malformato. Stesso errore anche con groq/compound che è il modello che Groq consiglia per il tool use. non è il modello ma è la validazione lato provider dato che tutti i modelli Groq condividono la stessa API.
Groq è strutturalmente incompatibile con Strix in questo momento.
Bug trovati nel tool
~/.strix/cli-config.json si autosvuota e torna a {"env": {}} senza motivo apparente.
README dice che la configurazione viene salvata lì e non serve reinserirla ad ogni run ma non lo trovo vero. Workaround stabile: passare tutto via export nella shell prima di ogni comando e non fidarsi mai del file.
--resume non riparte pulito. si aggancia a un container di Docker già morto con 0 PID invece di crearne uno nuovo. creare sempre un target nuovo da zero.
I PoC generati scrivono tutti su /workspace/recon/ path che esiste solo dentro al container. Fuori crashano con PermissionError e due dei quattro ignorano anche il flag --target e usano l'IP hardcoded
L'agente sporca il target senza chiederlo. Nel secondo run da solo ha cancellato l'utente admin e ne ha creato uno nuovo con role=admin per dimostrare il bypass. Lo ha annotato nel proprio ragionamento e ha proseguito.
Su Juice Shop non è un dettaglio importante, su un ingaggio reale in produzione è un problema grosso
Run 1, sola ricognizione
34 minuti e 6.5M token in input di cui 6.3M cache, 28.3K output (pessimo rapporto) e costo zero. exploitation esplicitamente vietata all''agente.
A fine run la UI dice "0 vulnerabilità". Significa che la fase di exploitation non è mai partita, non che il tool non abbia trovato niente.
Leggendo il transcript, l'agente ha scoperto in autonomia che il target non era raggiungibile su host.docker.internal
Ha diagnosticato passo per passo con curl, scan del range 172.17.0.0/16, ha trovato il target su 172.17.0.2 e ha scritto una entry in /etc/hosts .
un Troubleshooting di rete autonomo, e nessuno gliel'aveva chiesto.
Il rapporto token è critico. 6.5M in input contro 28.3K in output e con il 97% in cache
Con un modello free costa zero ed è tollerabile, con un modello a pagamento quel numero decide se il tool ha senso o no.
Run 2, exploitation attiva
34 minuti 22secondi di scan effettivo, 260 richieste con 11.8M token input, 98.7K output, costo zero, 10 agenti totali .
La differenza rispetto al run 1 è nella pianificazione. il run 1 aveva spawnato un singolo sub agente generico
Il run 2 ne ha spawnati nove e tutti specializzati: recon, validatori dedicati per CORS, JWT, FTP e lista utenti, più tre agenti che scrivono solo i report dei rispettivi findings
Risultato: 4 finding validati.
| CVSS | Finding |
|---|---|
| 9.8 | JWT alg=none authentication bypass |
| 9.4 | JWT payload espone l'hash MD5 non salato |
| 7.5 | /ftp/ directory listing con bypass null-byte |
| 4.3 | wildcard CORS |
alg=none è il finding migliore, ed è quello che il run 1 non aveva visto: la ricognizione da sola non ci arriva, serve provare a creare un token e mandarlo.
L'esposizione della lista utenti non compare come finding a sé perché Strix la riporta come conseguenza dell'alg=none, non come vulnerabilità indipendente
Verifica dei PoC
Inizio a controllare le segnalazioni del tool. ho ripreso gli script fuori dal container e li ho lanciati su un Juice Shop resettato da zero.
docker cp <container>:/workspace ~/strix-run2
docker rm -f juiceshop && docker run -d --name juiceshop -p 3000:3000 bkimminich/juice-shop
jwt_poc.py funziona, con riserva:
[+] admin@juice-sh.op hash=0192023a7bbd73250516f069df18b500 cracked='admin123' (MATCH)
[+] jim@juice-sh.op hash=e541ca7ecf72b8d1286474fc613e5e45 cracked='ncc-1701' (MATCH)
[-] bender@juice-sh.op: HTTP 401 Invalid email or password
[-] bjoern.kimminich@gmail.com: HTTP 401 Invalid email or password
Due credenziali su quattro sono inventate: l'agente le ha messe nella lista come se le conoscesse. Le due valide crackano al primo colpo
ftp_poc.py funziona ma crasha subito fuori dal container per il path hardcoded. Creata la directory a mano, gira, e recupera tutti e sei i file bloccati:
BYPASS package-lock.json.bak 200 750353 B
BYPASS package.json.bak 200 4263 B
BYPASS encrypt.pyc 200 573 B
BYPASS suspicious_errors.yml 200 723 B
BYPASS coupons_2013.md.bak 200 131 B
BYPASS eastere.gg 200 324 B
users_poc.py funziona: 23 utenti, 8 admin, 4 deluxeToken in chiaro, un ruolo "accounting" non documentato.
Il PoC dell'alg=none, cioè il finding critico più grave, non è su disco per ragioni sconosciute. Lo script esiste solo dentro al PDF del report che genera.
L'ho ricostruito da lì e rilanciato:
GET /api/Users -> 200
record esposti: 23
admin: ['admin@juice-sh.op', 'bjoern.kimminich@gmail.com', ...]
POST /api/Users -> 201
creato: attacker-test@evil.com role = admin
Funziona: token con firma vuota, lettura completa del database utenti e creazione di un account admin da anonimo. Ma il fatto che il PoC del finding più severo non finisca su disco è un difetto.
Verdetto su Strix
Il reasoning agentico regge: debug di rete autonomo , correzione di strategia in corsa, scoperta indipendente del bypass null-byte, pianificazione che migliora tra il primo e il secondo run. La maggior parte dei PoC gira davvero
Quello che non regge è il contorno: compatibilità provider da indovinare per tentativi , config che si svuota,resume rotto, path hardcoded, il Poc del finding più critico che non finisce su disco, e un agente che modifica lo stato del target senza chiedere
Il gap non è nell'intelligenza dell'agente ma nel packaging
PentAGI
PentAGI è un sistema a più agenti AI per pentest, il più stellato della sua tipologia (15.5k stelle). Scritto in Go con un frontend React, licenza MIT.
Non è un CLI bensì è uno stack di quattro container che gira con Docker compose, presente anche interfaccia web, database Postgres per la memoria semantica e un container Kali dove l'agente esegue davvero i comandi.
Quattro sotto agenti coordinati da un orchestratore: Searcher (ricerca e operazioni OSINT), Coder (script e payload), Installer (dipendenze e ambiente), Pentester ( offensive).
PentAGI quindi non è un programma solo ma quattro pezzi che devono girare insieme. Il file docker-compose.yml li descrive tutti, e con un comando li avvii tutti già collegati tra loro invece di lanciarli a mano uno per uno
mkdir -p ~/pentagi && cd ~/pentagi
curl -fsSL -O https://raw.githubusercontent.com/vxcontrol/pentagi/master/docker-compose.yml
curl -fsSL -o .env https://raw.githubusercontent.com/vxcontrol/pentagi/master/.env.example
docker compose up -d
Configurazione degli LLM e tre errori concettuali
Il tool si contraddice. La documentazione dice di mettere le credenziali nel .env, con un blocco LLM_SERVER_* dedicato ai provider custom. ma non funziona
failed to create embedder 'openai'
missing the OpenAI API key, set it in the OPENAI_API_KEY environment variable
Il blocco/parametro LLM_SERVER_* viene ignorato. La 2.1.0 vuole i provider configurati dalla UI, non dal file. Ma la UI non ha campi per URL e chiave: chiede solo il nome del modello, tredici volte, uno per ogni tipo di agente .
URL e chiave restano nel .env, sotto nomi diversi da quelli documentati.
Secondo errore, con Type impostato su custom:
400: custom/minimax/minimax-m3:free is not a valid model ID
Il tipo provider custom antepone custom/ al nome del modello e OpenRouter non lo riconosce, e non è rimuovibile.
Soluzione: Type openai, che non aggiunge prefissi, puntando OPEN_AI_SERVER_URL a OpenRouter.
Terzo errore il più costoso:
402: Provider returned error
Il pulsante Test del provider lancia 24 chiamate di verifica per ognuno dei 13 tipi di agente. Su un account OpenRouter senza crediti caricati il limite giornaliero dei modelli :free è 50 richieste: il test le brucia tutte prima ancora di iniziare il pentest.
Alla creazione del primo flow scarica poi l'immagine Kali, circa 2GB, durante i quali la UI mostra "failed to fetch" per timeout della richiesta GraphQL mentre il download prosegue in background
Run
18 minuti di run, 78 tool call, 959.3K token bruciati (892.7K in, 66.6K out, 534.6K cache. dati MIGLIORI ), 1 task principale e 3 subtask.
Il costo di $1.18 mostrato in dashboard non è reale: sono i prezzi di default lasciati nella configurazione del provider ma il mio modello è gratuito
il breakdown per tipo di agente è la cosa che Strix non dà: primary_agent 98.1K token, refiner 75.6K, generator 11.1K, reflector 2.9K. Si vede precisamente dove va il budget.
Come lavora e quanto è diverso
La prima differenza salta subito all'occhio. PentAGI ha fatto otto ricerche su DuckDuckGo prima di toccare il target, ha costruito un catalogo di vulnerabilità note da writeup pubblici e fonti credibili, lo ha salvato nel vector store, e solo dopo ha generato il piano.
Strix era andato dritto sull'host provando in tempo reale TUTTO senza cercare niente. Trarremo dopo le conclusioni di questi due approcci
La seconda è la revisione del piano. Dopo il primo subtask lo ha riscritto due volte, motivando ogni modifica:
Rimosso Subtask 7 (re-test CORS null-origin) perchè "alto costo, basso valore" che è oro.
i test live hanno già confermato vulnerabilità ACAO*senza ACAC su più endpoint e più origin, un ulteriore test non cambierebbe il verdetto.
Taglia lavoro inutile invece di eseguire il piano alla lettera
La terza: Strix ha spawnato nove agenti che lavorano insieme, PentAGI ha un flusso lineare di subtask con dipendenze esplicite. Entrambi arrivano in fondo, PentAGI in meno della metà del tempo
Risultati
3 finding confermati, 2 dichiarati non riproducibili.
| Severità | Finding |
|---|---|
| High | credenziali admin di default + MD5 non salato nel JWT |
| High | /api/Users espone 24 utenti a qualsiasi utente autenticato |
| Medium | directory listing su /ftp/ con KeePass DB e manifest dipendenze |
| Info | /api/Users non autenticato: restituisce 401, non riproducibile |
| Info | CORS credenziale: wildcard senza ACAC, non sfruttabile |
La parte importante è quella Info, ed è il motivo per cui questo confronto ha senso.
La differenza rispetto ai 23 record visti da Strix è l'account attacker-test@evil.com, creato dal mio test manuale dell'alg=none prima di questo run e correttamente identificato da PentAGI come residuo.
PentAGI ha smontato un finding di Strix
Strix aveva riportato il CORS come vulnerabilità con PoC funzionante e CVSS 4.3. Il suo cors_poc.py gira con httpx e la catena completa funziona: login cross-origin, JWT rubato, 23 utenti esfiltrati.
PentAGI ha testato la stessa cosa e ha concluso che Access-Control-Allow-Credentials è assente su ogni endpoint, quindi si applica il default del browser (false) e i cookie non vengono allegati automaticamente: i browser rifiutano correttamente credentials:'include' contro un ACAO wildcard. Nessun SOP bypass. no vulnerabilità
Ha ragione PentAGI. httpx e curl ignorano completamente la same-origin policy: un PoC scritto con quelli dimostra che il server risponde, non che un browser lascerebbe passare l'attacco
Quello di Strix è un falso positivo mascherato da prova funzionante, anche se ha fondo di verità
pentAGI ha anche cercato online "la variante null-origin con iframe sandboxed", tecnica nota per bypassare i wildcard ACAO, l'ha provata sul target, ha verificato che questa build non è vulnerabile nemmeno a quella, e ha declassato il finding a informational invece di gonfiarlo.
MA ha mancato il finding più grave!
L'alg=none non compare da nessuna parte nel run PentAGI. Il CVSS 9.8 di Strix, il bypass completo dell'autenticazione con un token dalla firma vuota, non è stato nemmeno cercato.
PentAGI si è fermato a "senza Bearer restituisce 401, quindi non è unauth" e ha riclassificato il finding come esposizione autenticata. Corretto ma incompleto: non ha provato a forgiare un token, e forgiando si entra da anonimo. Nel report lo scrive pure, nella sezione out of scope: "nessuna debolezza alg:none osservata". Non osservata perché non ha guardato
Deliverable
nessun PoC standalone.
PentAGI produce un file REPORT.md (13KB, 214 righe, 10 sezioni metodiche) con blocchi curl copiabili dentro. Funzionano, ma sono comandi da incollare, non file .py che lanci.
In compenso l'evidenza raccolta è MOLTO più granulare: 57 artefatti sotto /tmp/loot, con la matrice completa dei metodi di autenticazione testati (cookie da solo, bearer da solo, entrambi, nessuno, su endpoint lista e su singolo utente).
docker cp $(docker ps --format "" | grep terminal):/tmp/loot ~/pentagi-loot
Il report ha CWE e OWASP mappati per ogni finding, una sezione che collega i problemi tra loro (JWT stateless senza cookie HttpOnly significa che una XSS vale un account takeover completo), e soprattutto una sezione "out of scope / not pursued" che dichiara esplicitamente cosa non è stato fatto e perché. Strix non ce l'ha.
Dettaglio che dice molto sull'onestà del tool: i quattro deluxeToken da 64 caratteri hex trovati nel dump utenti non li ha nemmeno provati a crackare, e ha scritto un file di triage separato per spiegare perché sono token di entitlement server-side e non hash di password.
Verdetto su PentAGI
Più veloce, più economico in token, e soprattutto Più onesto dato che dichiara non riproducibile quello che non riesce a riprodurre invece di gonfiare il report. Ha anche smontato un falso positivo che Strix aveva certificato come vulnerabilità con PoC.
Ma è anche meno aggressivo. si ferma al primo 401 e non prova a forzarlo. Il finding più grave del target gli è sfuggito completamente purtroppo
Sebbene i costi siano ridotti il setup è molto più pesante: quattro container, un database grosso, una UI con tredici campi da riempire a mano, errori di configurazione consecutivi, e 2GB di immagine Kali da scaricare e mantenere. Strix è un curl e via.
NeuroSploit
NeuroSploit è un Harness(orchestrazione) scritto in Rust per pentest autonomo.
è CLI pura, nessuna interfaccia web e soprattutto nessun database collegato. Lo compili una volta e hai un binario. Più emergente per la sua semplicità ha guadagnato 1.4k stelle, licenza MIT.
La premessa è molto diversa dagli altri due: carica 435 agenti più piccoli specializzati, dopo la ricognizione seleziona solo quelli che corrispondono alla superficie trovata, li lancia IN PARALLELO, e valida ogni finding con voto incrociato tra modelli più "tool receipt grounding", cioè "la pretesa di scartare le affermazioni non supportate da un output di comando reale"
Supporta 16 provider e sei modalità: run (black-box), whitebox, greybox, host, aitest, skills.
git clone https://github.com/CyberSecurityUP/NeuroSploit.git ~/neurosploit
cd ~/neurosploit/neurosploit-rs && cargo build --release
Il cargo dei repository apt è troppo vecchio e fallisce con lock file version 4 requires -Znext-lockfile-bump. Serve rustup ufficiale, che ho setuppato dopo
Primo tentativo con minimax-m3, lo stesso modello usato con i precedenti tool
Selezione agenti: 86 su 435 totali, corretta e sensata finchè non si dimostra un disastro= su 86 agenti, praticamente tutti restituiscono zero finding parsabili in json :
[extract_findings] agent auth_bypass: JSON parse failed: expected value at
line 1 column 2; slice head: "[>[<tool_call>\n<tool>exec</tool>..."
· agent cors_misconfig returned text but 0 parseable findings
(model may have produced malformed JSON)
Il lavoro l'agente lo faceva davvero dato che nei log si legge information_disclosure che conferma l'hash MD5 su /api/Users. Ma minimax non emette JSON nel formato preciso che il parser pretende, anche se differenze sono minime e tutto viene buttato via
è la stessa incompatibilità strutturale di Groq con Strix. La differenza è che Groq falliva subito con un errore chiaro , mentre NeuroSploit macina venti minuti e consegna zero: la directory di output resta vuota, niente evidence, niente pocs.
Due soli finding sopravvissuti, ed erano entrambi tutto tranne findings : "nessuna command injection trovata" e un open redirect con confidence 0.3 il cui testo dice espressamente che non è sfruttabile.
Secondo tentativo con nemotron-3-super-120b
Cambiando modello (trovandone uno valido discretamente in fretta), il tool si comporta come promesso
Selezione stretta (12 agenti), esecuzione pulita, una solida catena di attacco costruita e voto di validazione attivo
✓ validated vote CORS misconfiguration with wildcard origin → CONFIRMED (1/1)
· rejected vote Exposed JWT secret key allows forging → rejected (0/1)
· rejected vote JWT token exposes MD5 password hash → rejected (0/1)
· grounding gate: demoted 1/9 ungrounded claim(s) (no tool receipt)
hygiene: 'cors-misconfig' affects 2 assets — consolidate into ONE finding
Risultato: 9 findings validati, 4 High, 4 Medium, 1 Low, report HTML con attack graph e kill chain divisa per fase .
Sulla carta è il deliverable più curato dei tre
Verificando le evidenze
La run crolla
-L'hash admin nel finding CORS è b592d3f3fzzyfyfyfyfyfyfyfyfyfyfyfy. Contiene lettere che in esadecimale non esistono. L'hash vero, quello che ho crackato a mano, è 0192023a7bbd73250516f069df18b500.
-Il JWT nella stessa evidenza ha firma -Qq0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X e nel payload l'email admin.juice-shop.com, che su Juice Shop non esiste. È un token inventato, non catturato
-Il finding High "Environment Variable Exposure" mostra un file .env con ADMIN_PASSWORD=admin123 e SECRET_KEY_BANKACCOUNT=1234567890. Juice Shop non ha un file .env.
-Il package.json compare in due finding diversi con contenuti incompatibili: versione 12.10.0 con express 4.18.2 in uno, versione 12.0.0 con express 4.16.4 nell'altro. Il mio Juice Shop è la 20.2.0.
-Il directory listing mostra due file, package.json e README.md. Il listing vero ne ha undici più la sottodirectory quarantine, verificato con entrambi gli altri tool.
-Il finding High più grave, arbitrary file read via traversal su /etc/passwd, l'ho provato a mano:
$ curl -s -i "http://localhost:3000/ftp/../../../../etc/passwd" | head -20
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 9393
<!--
~ Copyright (c) 2014-2026 Bjoern Kimminich & the OWASP Juice Shop contributors.
ma è la homepage Angular di 9393 byte... Il report dichiarava text/plain, 1394 byte e il contenuto di /etc/passwd riga per riga.
L'IDOR su /api/Users/3, stesso trattamento:
$ curl -s "http://localhost:3000/api/Users/3" | head -5
<title>UnauthorizedError: No Authorization header was found</title>
- Il report lo dava per confermato con confidence 0.90.
Bilancio grave: 9 finding plausibili, zero verificati come reali
Perché è successo
Juice Shop risponde HTTP 200 a tutto di default, anche ai 404, ed è una cosa comune in una webapp non un caso particolare. L'agente ha visto il 200, ha dedotto che il traversal aveva funzionato, e invece di leggere il corpo della risposta ha scritto il contenuto che si aspettava di trovare. Stesso meccanismo per il .env, per il package.json, per l'hash.
il sistema di validazione non l'ha intercettato. Anzi: ha marcato "confirmed" sette finding su nove interamente inventati, con CWE mappati, evidenze HTTP formattate riga per riga e confidence 0.90
I due marcati "needs-review" sono gli unici dove il grounding gate ha funzionato, segnalando l'assenza di una tool receipt. Entrambi erano falsi. Quindi il gate ha prodotto due veri positivi su nove allucinazioni, lasciandone passare ben sette.
Il voto incrociato ha respinto due claim, tra cui "JWT esposto contiene hash MD5", che era l'unica cosa vera di tutto il run. Ha rifiutato il finding corretto e confermato quelli inventati
nota metodologica sul voto: era configurato vote_n=3 ma con un solo modello nel pool. Tre voti dello stesso modello sulla stessa allucinazione non sono validazione, sono conferma di sé. Con più modelli diversi il risultato potrebbe cambiare, ma il default della CLI con un solo --model produce esattamente questo, e la UI lo presenta come "multi-model adversarial validation" nel testo di ogni singolo finding.
Si può dare la colpa al modello di llm? in parte sì.
Che un modello gratuito allucini contenuti plausibili è prevedibile, e con un modello di frontiera a pagamento probabilmente il risultato sarebbe stato migliore
Ma questa è un'attenuante perchè , pur producendo errori e almeno un falso positivo, gli altri due tool non hanno generato un report composto quasi interamente da evidenze inventate
Il livello che ha lasciato passare le allucinazioni si chiama "multi-model adversarial validation" ed esiste esattamente per intercettare questi casi
Verdetto su NeuroSploit
L'architettura è la più ambiziosa dei tre, e da riga di comando è il più pulito da usare in assoluto: un binario, niente container né database
Ed è anche il più pericoloso, per lo stesso motivo per cui è il migliore sulla carta: il report è credibile. Formattato bene, con CWE corretti, evidenze che sembrano dump HTTP reali, severity motivate e un badge "confirmed" verde accanto a roba che non esiste. Strix produce script che puoi lanciare e vedere fallire. PentAGI dichiara quello che non riesce a riprodurre. NeuroSploit riempie i buchi con testo plausibile e ci mette sopra un timbro di validazione.
La sensibilità al modello è probabilmente cos'ha penalizzato il tool dato che è estrema: con minimax produce zero, con nemotron produce nove finding falsi. Ma come discuterò nelle conclusioni, è anche il tool meno pesante dei tre e gli altri due non hanno avuto vantaggi in più, bensì hanno utilizzato gli stessi modelli "deboli" per il metro di giudizio attuale
la documentazione elenca sedici provider e non dice quali reggano il formato di output richiesto.
Confronto
| Strix | PentAGI | NeuroSploit | |
|---|---|---|---|
| Forma | CLI + dashboard locale | 4 container + web UI | binario singolo |
| Setup | un curl | ~2h, tre errori di config | compilazione, rustup |
| Durata run | 34m | 18m | 20m |
| Token | 11.8M | 959K | n/d |
| Finding dichiarati | 4 | 3 + 2 info | 9 |
| Finding veri, verificati a mano | 3 su 4 | 3 su 3 | 0 su 9 |
| Falsi positivi | 1 (CORS) | 0 | 9 |
| PoC eseguibili | sì, 4 file .py |
no, solo curl nel report | no |
| Modifica il target | sì, senza chiedere | no | no |
| Sensibilità al modello | alta | media | estrema |
Il finding critico del target, l'alg=none che permette a un anonimo di leggere il database utenti e creare account admin, l'ha trovato solo Strix. PentAGI non l'ha cercato, NeuroSploit era allucinato
Considerazioni, e cosa mi porto a casa
Il numero che conta non è quanti finding produce un tool ma quanti ne produce di veri e dimostrabili. Su questa metrica la classifica si ribalta rispetto a quella che leggeresti guardando i report:
PentAGI 3 su 3, 2 ipotesi
Strix 3 su 4
NeuroSploit 0
Anche prendendo i tool più ambiziosi e stellati, il risultato è discreto e incompleto. La verifica manuale non è mai stato e non è ancora un passaggio opzionale
Senza avrei pubblicato nove vulnerabilità inesistenti con CVSS e CWE al seguito.
La compatibilità dei provider LLM è la variabile più sottovalutata dell'intera categoria. Tutti e tre dichiarano di supportare "qualsiasi provider". In pratica lo stesso modello che fa funzionare uno ne rompe un altro, e non è documentato da nessuna parte. lo scopri bruciando le tue ore di lavoro.
Inoltre:
Juice Shop espone l'elenco delle proprie vulnerabilità intenzionali su /api/Challenges:
curl -s http://localhost:3000/api/Challenges | python3 -c "import sys,json; print(len(json.load(sys.stdin)['data']))"
116
Sono ben 116. I tre tool insieme ne hanno toccate 5 e su un target progettato apposta per essere trovato, con le soluzioni pubblicate ovunque online.
Nessuno dei tre lo porterei su un target di produzione così com'è. Su staging, con qualcuno che rilegge e riverifica ogni PoC prima che finisca in un report, Strix e PentAGI hanno senso
Non concludo che l'AI pentesting sia impossibile: non ho testato i tool di fascia alta a pagamento, e sarebbe una generalizzazione affrettata.
La mia conclusione è più stretta. Allo stato attuale i migliori tool open source, con modelli gratuiti, coprono una frazione minima di un target costruito apposta per essere vulnerabile, e offrono poche garanzie: tra le promesse dei README e ciò che esce davvero dai run c'è una distanza enorme.