
PoC for CVE-2026-2005
PoC-Exploit für einen heap-basierten Pufferüberlauf in der PGP-Sitzungsschlüssel-Parsing des PostgreSQL pgcrypto-Extensions, der zu beliebigem Lesen/Schreiben von Speicher und Privilegieneskalation zum Superuser führt.
Vollständige technische Details finden Sie im Zeroday Cloud Advisory.

Klonen und kompilieren Sie PostgreSQL aus dem anfälligen Commit, damit die Symbol-Offsets der Binärdatei exakt übereinstimmen. Der Exploit ermittelt die ASLR-Basis durch Abgleich von geleckten Pointern mit ELF-Symbol-Offsets – verschiedene Builds oder Versionen haben unterschiedliche Offsets und werden fehlschlagen.
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
Der Exploit läuft in 7 Schritten ab:
Heap-Pointer-Leak – Eine präparierte PGP-Nachricht beschädigt den malloc-Chunk-Header des mdst-Puffers. Wenn PostgreSQL pfree() auf den beschädigten Chunk aufruft, gibt der Allokator eine Fehlermeldung mit der Pointer-Adresse aus, wodurch die Heap-Position von mdst->data preisgegeben wird.
Beliebiges Lesen – Ein zweiter Überlauf überschreibt mdst->data, um auf (leaked_ptr - 0x10000) zu zeigen. Nach der Entschlüsselung gibt mbuf_steal_data() den Inhalt an dieser Adresse als entschlüsselte Ausgabe zurück und gibt so Heap-Speicher preis, der möglicherweise veraltete Code-Pointer enthält.
Pointer-Scan – Der Hex-Dump wird nach 8-Byte-Little-Endian-Werten durchsucht, die wie Code-Adressen aussehen (>= 0x500000000000), aber nicht im Heap-Bereich liegen. Dies sind Kandidaten für PIE (Position Independent Executable)-Pointer.
PIE-Basis-Abstimmung – Jede Kandidatenadresse wird gegen die ELF-Symbol-Offsets der Postgres-Binärdatei getestet. Für jedes Paar (addr - sym_offset), bei dem der Seiten-Offset übereinstimmt, wird eine Stimme abgegeben. Kandidaten mit 10+ Stimmen bleiben erhalten; die kleinste Basis (PIE ist das am niedrigsten gemappte ELF-Segment), sortiert nach Stimmen, ist der beste Kandidat.
PIE-Basis-Validierung – Mithilfe des beliebigen Lese-Primitivs liest der Exploit an der Adresse und vergleicht sie mit der bekannten OID der Sitzung. Eine Übereinstimmung bestätigt die PIE-Basis.
pip install -r requirements.txt)pgcryptoDieser Proof of Concept dient nur zu Bildungs- und Verteidigungsforschungszwecken. Verwenden Sie ihn nur gegen Systeme, die Sie besitzen oder für die Sie ausdrücklich berechtigt sind, Tests durchzuführen.
| Argument | Standard | Beschreibung |
|---|
--binary | (Postgres-Binärdatei) | Pfad zur Postgres-Binärdatei für die Symbolextraktion |
--dbname | postgres | Name der Zieldatenbank |
--host | localhost | PostgreSQL-Host |
--port | 5432 | PostgreSQL-Port |
--user | postgres | Datenbankbenutzer |
--password | (leer) | Datenbankpasswort |
--cmd | whoami | OS-Befehl, der nach der Privilegieneskalation ausgeführt werden soll |
--gdb | (Flag) | GDB über tmux an der Überlaufstelle anhängen |
CurrentUserId(candidate_base + current_user_offset)Beliebiges Schreiben – Der Überlauf beschädigt sowohl msrc- als auch mdst-MBuf-Header. Gefälschte msrc->data/read_pos zeigen auf ein eingebettetes sym-encrypted-Paket, das den verschlüsselten Superuser-OID (10) enthält. Gefälschte mdst->data zeigen auf CurrentUserId - 4 (die -4 berücksichtigt SET_VARSIZE in pgp-pgsql.c:533, das die Ausgabelänge in die ersten 4 Bytes schreibt).
Privilegieneskalation – Mit CurrentUserId, das auf 10 (Bootstrap-Superuser) überschrieben wurde, führt COPY FROM PROGRAM den angegebenen OS-Befehl als Postgres-Systembenutzer aus.