
PoC para CVE-2026-2005
PoC del exploit para un desbordamiento de búfer basado en montón en el análisis de claves de sesión PGP de la extensión pgcrypto de PostgreSQL, que conduce a lectura/escritura arbitraria de memoria y escalada de privilegios a superusuario.
Para obtener todos los detalles técnicos, consulte el aviso de Zeroday Cloud.

Clone y compile PostgreSQL desde el commit vulnerable para que los desplazamientos de símbolos del binario coincidan exactamente. El exploit resuelve la base de ASLR comparando punteros filtrados con los desplazamientos de símbolos ELF; otras compilaciones o versiones tendrán desplazamientos diferentes y fallarán.
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
El exploit avanza en 7 etapas:
Fuga de puntero de montón - Un mensaje PGP manipulado corrompe el encabezado del chunk de malloc del búfer mdst. Cuando PostgreSQL llama a pfree() sobre el chunk corrupto, el asignador emite un error que contiene la dirección del puntero, filtrando la ubicación en el montón de mdst->data.
Lectura arbitraria - Un segundo desbordamiento sobrescribe mdst->data para que apunte a (puntero_filtrado - 0x10000). Tras el descifrado, mbuf_steal_data() devuelve el contenido de esa dirección como salida descifrada, volcando memoria del montón que puede contener punteros de código obsoletos.
Escaneo de punteros - El volcado hexadecimal se examina en busca de valores little-endian de 8 bytes que parezcan direcciones de código (>= 0x500000000000) pero que no estén en la región del montón. Estos son posibles punteros PIE (Ejecutable Independiente de Posición).
Votación de la base PIE - Cada dirección candidata se prueba contra los desplazamientos de símbolos ELF del binario de postgres. Por cada par (dirección - desplazamiento_símbolo) en el que coincida el desplazamiento de página, se emite un voto. Se conservan los candidatos con 10 o más votos; la base más pequeña (el PIE es el segmento ELF mapeado más bajo) ordenada por votos es el candidato principal.
pip install -r requirements.txt)pgcrypto habilitadoEsta prueba de concepto tiene fines exclusivamente educativos y de investigación defensiva. Úsela únicamente contra sistemas de su propiedad o para los que tenga autorización explícita de prueba.
| Argumento | Valor predeterminado | Descripción |
|---|
--binary | (binario de postgres) | Ruta al binario de postgres para la extracción de símbolos |
--dbname | postgres | Nombre de la base de datos objetivo |
--host | localhost | Host de PostgreSQL |
--port | 5432 | Puerto de PostgreSQL |
--user | postgres | Usuario de la base de datos |
--password | (vacío) | Contraseña de la base de datos |
--cmd | whoami | Comando del sistema operativo a ejecutar tras la escalada de privilegios |
--gdb | (indicador) | Adjunta GDB mediante tmux en el punto del desbordamiento |
Validación de la base PIE - Usando la primitiva de lectura arbitraria, el exploit lee CurrentUserId en (base_candidata + desplazamiento_current_user) y lo compara con el OID conocido de la sesión. Una coincidencia confirma la base PIE.
Escritura arbitraria - El desbordamiento corrompe tanto los encabezados MBuf de msrc como de mdst. Los msrc->data/read_pos falsificados apuntan a un paquete simétrico cifrado incrustado que contiene el OID de superusuario cifrado (10). El mdst->data falsificado apunta a CurrentUserId - 4 (el -4 compensa SET_VARSIZE en pgp-pgsql.c:533, que escribe la longitud de salida en los primeros 4 bytes).
Escalada de privilegios - Con CurrentUserId sobrescrito a 10 (superusuario de arranque), COPY FROM PROGRAM ejecuta el comando del sistema operativo especificado como el usuario del sistema postgres.