
PoC per CVE-2026-2005
Exploit PoC per un buffer overflow basato su heap nel parsing delle chiavi di sessione PGP dell'estensione pgcrypto di PostgreSQL, che porta a lettura/scrittura arbitraria della memoria e escalation dei privilegi a superuser.
Per tutti i dettagli tecnici, consulta l'advisory di Zeroday Cloud.

Clona e compila PostgreSQL dal commit vulnerabile in modo che gli offset dei simboli del binario corrispondano esattamente. L'exploit risolve la base ASLR confrontando i puntatori ottenuti tramite leak con gli offset dei simboli ELF: build o versioni diverse avranno offset diversi e falliranno.
git clone https://github.com/postgres/postgres.git
cd postgres
git checkout 4b324845ba5d24682b9b3708a769f00d160afbd7
./configure \
--prefix="$HOME/projects/pg/pgsql" \
--with-libxml \
--with-libxslt \
--enable-debug \
--with-ssl=openssl
make -j$(nproc)
make install-world-bin
pip install -r requirements.txt
python poc.py \
--binary "$HOME/projects/pg/pgsql/bin/postgres" \
--dbname test-db \
--host 127.0.0.1 \
--port 5432 \
--user test-user \
--password secret \
--cmd id
L'exploit procede in 7 fasi:
Heap pointer leak - Un messaggio PGP appositamente costruito corrompe l'header della chunk malloc del buffer mdst. Quando PostgreSQL chiama pfree() sulla chunk corrotta, l'allocatore emette un errore contenente l'indirizzo del puntatore, rivelando la posizione nell'heap di mdst->data.
Lettura arbitraria - Un secondo overflow sovrascrive mdst->data per farlo puntare a (leaked_ptr - 0x10000). Dopo la decrittazione, mbuf_steal_data() restituisce il contenuto di quell'indirizzo come output decrittato, scaricando memoria heap che può contenere puntatori a codice obsoleti.
Scansione dei puntatori - L'hex dump viene scansionato per valori little-endian a 8 byte che sembrano indirizzi di codice (>= 0x500000000000) ma non si trovano nella regione heap. Questi sono potenziali puntatori PIE (Position Independent Executable).
Votazione per la base PIE - Ogni indirizzo candidato viene testato contro gli offset dei simboli ELF del binario di postgres. Per ogni coppia (addr - sym_offset) in cui l'offset di pagina corrisponde, viene espresso un voto. I candidati con 10 o più voti vengono mantenuti; la base più piccola (il PIE è il segmento ELF mappato all'indirizzo più basso) ordinata per voti è il candidato principale.
Validazione della base PIE - Utilizzando la primitiva di lettura arbitraria, l'exploit legge in e lo confronta con l'OID noto della sessione. Una corrispondenza conferma la base PIE.
pip install -r requirements.txt)pgcrypto abilitatoQuesto Proof of Concept è destinato esclusivamente a scopi educativi e di ricerca difensiva. Utilizzalo solo su sistemi di tua proprietà o per i quali hai esplicita autorizzazione a testare.
| Argomento | Predefinito | Descrizione |
|---|
--binary | (binario di postgres) | Percorso del binario di postgres per l'estrazione dei simboli |
--dbname | postgres | Nome del database di destinazione |
--host | localhost | Host di PostgreSQL |
--port | 5432 | Porta di PostgreSQL |
--user | postgres | Utente del database |
--password | (vuoto) | Password del database |
--cmd | whoami | Comando di sistema da eseguire dopo l'escalation dei privilegi |
--gdb | (flag) | Collega GDB tramite tmux al punto dell'overflow |
CurrentUserId(candidate_base + current_user_offset)Scrittura arbitraria - L'overflow corrompe sia gli header MBuf di msrc che di mdst. I valori falsificati msrc->data/read_pos puntano a un pacchetto sym-encrypted incorporato contenente l'OID del superuser cifrato (10). Il valore falsificato mdst->data punta a CurrentUserId - 4 (il -4 tiene conto di SET_VARSIZE in pgp-pgsql.c:533 che scrive la lunghezza dell'output nei primi 4 byte).
Escalation dei privilegi - Con CurrentUserId sovrascritto a 10 (superuser di bootstrap), COPY FROM PROGRAM esegue il comando di sistema specificato come utente di sistema postgres.