
PoC pour CVE-2026-2005
Exploit PoC pour un dépassement de tampon basé sur le tas dans l'analyse des clés de session PGP de l'extension pgcrypto de PostgreSQL, permettant une lecture/écriture mémoire arbitraire et une élévation de privilèges à superutilisateur.
Pour plus de détails techniques, consultez l'avis de Zeroday Cloud.

Clonez et compilez PostgreSQL à partir du commit vulnérable afin que les décalages de symboles du binaire correspondent exactement. L'exploit résout la base ASLR en faisant correspondre les pointeurs divulgués aux décalages de symboles ELF - différentes compilations ou versions auront des décalages différents et échoueront.
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 se déroule en 7 étapes :
Fuite de pointeur de tas - Un message PGP conçu corrompt l'en-tête du bloc malloc du tampon mdst. Lorsque PostgreSQL appelle pfree() sur le bloc corrompu, l'allocateur émet une erreur contenant l'adresse du pointeur, divulguant l'emplacement de mdst->data dans le tas.
Lecture arbitraire - Un deuxième dépassement écrase mdst->data pour pointer vers (leaked_ptr - 0x10000). Après déchiffrement, mbuf_steal_data() renvoie le contenu à cette adresse comme sortie déchiffrée, vidant la mémoire du tas qui peut contenir des pointeurs de code obsolètes.
Analyse des pointeurs - Le dump hexadécimal est analysé pour rechercher des valeurs de 8 octets en little-endian qui ressemblent à des adresses de code (>= 0x500000000000) mais ne se trouvent pas dans la région du tas. Ce sont des pointeurs PIE (Position Independent Executable) candidats.
Vote pour la base PIE - Chaque adresse candidate est testée par rapport aux décalages de symboles ELF du binaire postgres. Pour chaque paire (addr - sym_offset) où le décalage de page correspond, un vote est émis. Les candidats avec 10 votes ou plus sont conservés ; la base la plus petite (le PIE est le segment ELF mappé le plus bas) triée par votes est le meilleur candidat.
Validation de la base PIE - En utilisant la primitive de lecture arbitraire, l'exploit lit à et le compare à l'OID connu de la session. Une correspondance confirme la base PIE.
pip install -r requirements.txt)pgcrypto activéCette preuve de concept est uniquement destinée à des fins de recherche éducative et défensive. Utilisez-la uniquement contre des systèmes que vous possédez ou pour lesquels vous disposez d'une autorisation explicite de test.
| Argument | Défaut | Description |
|---|
--binary | (binaire postgres) | Chemin vers le binaire postgres pour l'extraction des symboles |
--dbname | postgres | Nom de la base de données cible |
--host | localhost | Hôte PostgreSQL |
--port | 5432 | Port PostgreSQL |
--user | postgres | Utilisateur de la base de données |
--password | (vide) | Mot de passe de la base de données |
--cmd | whoami | Commande système à exécuter après l'élévation de privilèges |
--gdb | (option) | Attacher GDB via tmux au point de dépassement |
CurrentUserId(candidate_base + current_user_offset)Écriture arbitraire - Le dépassement corrompt les en-têtes MBuf msrc et mdst. Les msrc->data/read_pos forgés pointent vers un paquet symétriquement chiffré intégré contenant l'OID superutilisateur (10) chiffré. Le mdst->data forgé pointe vers CurrentUserId - 4 (le -4 tient compte de SET_VARSIZE dans pgp-pgsql.c:533 qui écrit la longueur de sortie dans les 4 premiers octets).
Élévation de privilèges - Avec CurrentUserId écrasé à 10 (superutilisateur bootstrap), COPY FROM PROGRAM exécute la commande système spécifiée en tant qu'utilisateur système postgres.