
Proof-of-Concept-Exploit für CVE-2026-14669, eine Heap-Pufferüberlauf-Schwachstelle in der to_char()-Zeitzonenabkürzung von PostgreSQL, die durch Informationsleck und ROP-Kette RCE ermöglicht; enthält Docker-Lab und automatisiertes PoC.
Die PostgreSQL-Funktion to_char() weist bei der Verarbeitung der Zeitzonenformatierung eine Heap-Pufferüberlauf-Schwachstelle auf. Ein Angreifer kann durch das Setzen einer überlangen POSIX-Zeitzonenabkürzung einen Out-of-Bounds-Schreibzugriff auf einen festen 25-Byte-Puffer auslösen und in Kombination mit einem Informationsleck und einer ROP-Kette eine Remote-Code-Ausführung erreichen.
to_char(timestamptz) von PostgreSQL| PostgreSQL-Serie | Betroffene Versionen |
|---|---|
| 18.x | 18.0 – 18.5 |
| 17.x | 17.0 – 17.10 |
| 16.x | 16.0 – 16.14 |
| 15.x | 15.0 – 15.18 |
| 14.x | 14.0 – 14.23 |
Der Verarbeitungspfad DCH_TZ / DCH_tz in formatting.c verwendet einen festen 25-Byte-Stack-Puffer zum Speichern von Zeitzonenabkürzungen, ohne die Eingabelänge zu prüfen. Überschreitet die Zeitzonenabkürzung 24 Byte, schreibt strcpy() außerhalb der Grenzen in den Heap-Speicher.
Auslösepfad:
SET TIME ZONE '<超长缩写>+00';
SELECT to_char(now()::timestamptz, 'TZ');
↓
DCH_to_char() → DCH_from_char_action()
↓
strcpy(buf, tmtcTzn(...)) ← 堆溢出
Das PoC von V12 Security umfasst drei Phasen:
Durch den Heap-Überlauf werden benachbarte Heap-Objekte beschädigt, und die PIE-Basis sowie Heap-Zeiger werden geleakt, um ASLR zu umgehen.
Mithilfe von Large Objects oder bytea-Feldern wird eine Kette aus ROP-Gadgets auf dem Heap angeordnet.
Ein zweiter Überlauf überschreibt Funktionszeiger auf dem Heap und springt zur ROP-Kette, um beliebige Befehle (mit den Rechten des postgres-Benutzers) auszuführen.
poc.py - Vollständiges Exploit-Skript (210 Zeilen, für PostgreSQL 19beta1)requirements.txt - Python-Abhängigkeiten (psycopg, pwntools)docker-compose.yml - Testumgebung für die Schwachstelledocker-compose up -d
Warten, bis der Container vollständig gestartet ist (Health-Check erfolgreich):
docker logs pg-tzlab
pip install -r requirements.txt
python3 poc.py
Standardmäßig wird eine Verbindung zu 127.0.0.1:55432 hergestellt, Benutzername postgres, Passwort postgres.
Nach erfolgreicher Ausnutzung ist die Ausgabe der Befehlsausführung in den Container-Logs sichtbar:
docker logs pg-tzlab | grep PWNED
Bearbeiten Sie die Konstanten in poc.py:
HOST, PORT - ZieladresseDEFAULT_COMMAND - der auszuführende Befehl⚠️ Wichtig: Dieses PoC enthält hartcodierte Offset-Adressen für einen bestimmten Build (Docker-Image postgres:19beta1, sha256:a6bdd01...). Für andere Versionen müssen die Gadgets neu lokalisiert werden.
SET TIME ZONE-Anweisungen (> 50 Zeichen) überwachen⚠️ Dieses PoC dient ausschließlich der Sicherheitsforschung, der Schwachstellenverifizierung und defensiven Tests.
Durch die Verwendung dieses PoC erklären Sie sich damit einverstanden, die lokalen Gesetze und Vorschriften sowie die Autorisierungsgrenzen des Zielsystems einzuhalten.