PostgreSQL 18.6 – Hoch – Remote – Dateischreiben – pg_basebackup folgt absolutem tar-Symlink, Überbleibsel von CVE-2026-6475
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · postgres-basebackup-symlink
Klasse: Dateischreiben Reichweite: Remote
PostgreSQL 18.6 (724edf9) - PostgreSQL Global Development Group
CVE-2026-6475 fügte path_is_safe_for_extraction für Tar-Member-Namen hinzu. Absolute Symlink-Ziele umgehen diese Prüfung weiterhin, damit Tablespaces funktionieren. astreamer_file.c ruft dann symlink() auf das Ziel auf und später folgt fopen(..., "wb") diesem. Das Standardformat von pg_basebackup ist plain (-F p). pg_rewind create_target_symlink prüft den Pfad und verlinkt niemals.
Eine feindliche Quelle, die BASE_BACKUP spricht, kann einen absoluten Symlink platzieren und jede Datei überschreiben, die die Backup-UID schreiben kann. Dasselbe Opfermodell wie 6475. Dies ist keine erneute Meldung der Member-Namen-Prüfungen.
| ID | noch keine CVE |
| Klasse | Dateischreiben (absoluter Tar-Symlink-Überrest von CVE-2026-6475) |
| Reichweite | Remote (UI:R Client vs. feindliches PostgreSQL) |
| CWE | CWE-59, CWE-22 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Produkt | PostgreSQL |
| Betroffen | 18.6 Tag REL_18_6 (724edf9bde9d356724ad384a2e196edc3c9f80f7), In-Tree pg_basebackup / pg_rewind |
| Auth | Opfer führt Standard-pg_basebackup -D <dir> gegen eine Angreiferquelle aus |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Wer einen Operator dazu bringen kann, pg_basebackup -D gegen sein PostgreSQL auszuführen (dasselbe UI:R-Modell wie CVE-2026-6475), kann außerhalb von -D schreiben.
| Privileg | Methode / Sink | Im Lab bewiesen oder abgeleitet |
|---|---|---|
Integrität: eine Datei außerhalb von -D schreiben | Feindliches BASE_BACKUP-Tar: typeflag '2'-Member mit sicherem relativen Namen (pg_tblspc/16384) und absolutem Link-Ziel, dann ein reguläres Member unter diesem Namen. extract_link dann create_file_for_extract fopen(..., "wb") ohne O_NOFOLLOW | Im Lab bewiesen. Schrieb POSTGRES-BASEBACKUP-SYMLINK-WITNESS nach /work/oracle/. Dest enthält den Symlink. Kontroll-Tar (ohne Symlink) ließ das Oracle leer und schrieb PG_VERSION nur innerhalb von -D |
Integrität: Shell-RC, authorized_keys, eine systemd-User-Unit oder Crontab überschreiben | Derselbe Sink, jeder Pfad, den die Client-UID schreiben kann | Abgeleitet. Dieses Lab berührt diese Dateien nicht |
| Verfügbarkeit: Client-Konfiguration oder Schlüssel zerstören | Derselbe Schreibvorgang | Abgeleitet. Nicht demonstriert |
| Recon der Client-Festplatte | extract ist Schreiben, nicht Lesen | Geschlossen |
.. oder absolute Member-Namen durchlaufen | path_is_safe_for_extraction | Geschlossen. Das ist CVE-2026-6475 |
| Serverseitiges unpriv. SQL / unauth. Protokoll | 18.6 Standard-Server | Geschlossen. Dieser Überrest betrifft den Client |
| Nur-Tar-Backup | pg_basebackup -F t speichert das Tar ohne Extraktion | Geschlossen |
RCE innerhalb von postgres | nicht dieser Sink | Geschlossen |
pg_rewind hat denselben create_target_symlink / open()-Überrest. Dieses Lab steuert nur pg_basebackup an.
Ich habe postgres/postgres REL_18_6 nach der 18.6-Welle gepinnt (28 CVEs, plus das 18.4/18.2-Set, das bereits auf diesem Tree lag). Zweiundzwanzig Jagden. Standard-Server, unpriv. SQL, unauth. Protokoll: keine auf diesem Niveau. CVE-2026-6475 war das Geschwister, das erneut gelesen werden musste.
Member-Namen werden geprüft. Absolute Symlink-Ziele nicht:
if (!is_absolute_path(linktarget) &&
!path_is_safe_for_extraction(member->linktarget))
{
pg_fatal("link target has unsafe path name: \"%s\"",
member->linktarget);
}
extract_link(mystreamer->filename, linktarget);
create_file_for_extract ist weiterhin fopen(filename, "wb"). Der Kommentar bei astreamer_file.c:351-356 besagt, dass das Mapping angewendet wird, ohne zu prüfen, ob der Link innerhalb von pg_tblspc liegt.
Bereits festgehaltene Irrwege: 6475 als geschlossen zu betrachten und wegzugehen; -D auf ein Live-Datenverzeichnis zu richten; Shell-RC für Theater zu überschreiben. Ein ehrlicher 18.6-Server gibt nur pg_tblspc/<oid>-Symlinks aus und legt Tablespace-Inhalte in einem separaten Archiv ab. Eine bösartige Quelle, die BASE_BACKUP spricht, kann das nachfolgende reguläre Member in dasselbe Tar legen. Das ist der Überrest.
python3 postgres-basebackup-symlink-Abraxas-Labs.py
oder
cd lab
./run.sh
postgres:18.6 als Quell-Image, das einen BASE_BACKUP-Speaker ausführt. Der Client ist In-Tree pg_basebackup aus demselben Tag (pg_basebackup (PostgreSQL) 18.6). Loopback 127.0.0.1:19370. Compose-Projekt postgres-basebackup-symlink. -D nicht auf ein Live-Datenverzeichnis richten.
SUCCESS postgres-basebackup-symlink control-inside=yes oracle-outside=yes dest-is-symlink=yes image=postgres:18.6 how=pg_basebackup POSTGRES-BASEBACKUP-SYMLINK-WITNESS
Absolute Symlink-Ziele als unsicher behandeln, es sei denn, sie werden durch --tablespace-mapping umgeschrieben. Extraktionsdateien mit O_NOFOLLOW / lstat öffnen, damit einem platzierten Link nicht gefolgt werden kann. path_is_safe_for_extraction sowohl auf link als auch auf path beim Rewind anwenden. Ein reguläres Member ablehnen, dessen Pfad durch einen Symlink läuft, der -D verlassen hat.
724edf9bde9d356724ad384a2e196edc3c9f80f7)src/fe_utils/astreamer_file.c · src/fe_utils/astreamer_tar.csrc/bin/pg_rewind/file_ops.cGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.