
Demostración reproducible basada en Docker de la escalada de privilegios de PostgreSQL CVE-2018-1058 mediante ruta de búsqueda no controlada, con comparación de entornos vulnerable y parcheado.
Este repositorio contiene el informe final y los artefactos de reproducibilidad para:
CVE-2018-1058: Escalada de Privilegios en PostgreSQL mediante una Ruta de Búsqueda No Controlada
El objetivo es demostrar el fallo de confianza en la ruta de búsqueda detrás de CVE-2018-1058 utilizando un entorno Docker local seguro.
La demo no reproduce la ruta de ejecución histórica exacta de pg_dump. En su lugar, reproduce la misma causa raíz descrita en la guía de PostgreSQL: un esquema escribible por un atacante contiene un objeto similar, y otra sesión resuelve un nombre no calificado hacia ese objeto.
.
├── report.pdf
├── docker-compose.yml
├── README.md
└── scripts/
├── init.sql
├── init_safe.sql
├── exploit.sql
├── victim_query.sql
├── verify_qualify.sql
└── fix.sql
El informe final es report.pdf. Incluye el análisis escrito y las capturas de pantalla correspondientes a las salidas esperadas a continuación.
No se requiere Dockerfile. El proyecto utiliza imágenes oficiales de postgres.
Las capturas de pantalla están incrustadas directamente en report.pdf, por lo que no se proporcionan como archivos de imagen separados.
Instalar:
psql, opcional pero recomendadoLa demo utiliza dos contenedores PostgreSQL:
| Service | Version | Container name | Host port | Purpose |
|---|---|---|---|---|
pg_vulnerable | PostgreSQL 10.2 | cve1058_pg_vulnerable | 15432 | demostración vulnerable |
pg_fixed | PostgreSQL 10.3 | cve1058_pg_fixed | 15433 | comparación parcheada/endurecida |
Asegúrate de que los puertos 15432 y 15433 estén libres.
El orden de ejecución esperado es:
exploit.sql como attacker.victim_query.sql como victim y observar el prefijo CVE-2018-1058 DEMO:.verify_qualify.sql como victim y observar la salida normal en minúsculas.fix.sql como postgres.victim_query.sql y observar la salida normal en minúsculas.exploit.sql en el puerto 15433 y observar permission denied for schema public.docker compose up -d pg_vulnerable
docker compose ps
Resultado esperado: el servicio pg_vulnerable debería estar ejecutándose y mapeado al puerto 15432.
Verificar la versión de PostgreSQL:
docker exec -it cve1058_pg_vulnerable psql -U postgres -d demo_cve1058 -c "SELECT version();"
Resultado esperado: PostgreSQL 10.2.
docker exec -it cve1058_pg_vulnerable psql -U postgres -d demo_cve1058 -c "\du"
Roles esperados:
postgresattackervictimEl atacante no es un superusuario de PostgreSQL.
Ejecutar el script del atacante:
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U attacker -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/exploit.sql
Salida esperada:
CREATE TABLE
GRANT
GRANT
CREATE FUNCTION
Esto crea:
public.exploit_log inofensiva;public.lower(varchar).PGPASSWORD='VictimPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U victim -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/victim_query.sql
Salida esperada:
CVE-2018-1058 DEMO: Alice Demo
CVE-2018-1058 DEMO: Bob Demo
Esto muestra que la consulta normal de la víctima resolvió lower(...) hacia la función controlada por el atacante.
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U attacker -d demo_cve1058 \
-c "TABLE public.exploit_log;"
Resultado esperado: al menos dos filas en public.exploit_log, una por cada fila procesada por la consulta de la víctima.
PGPASSWORD='VictimPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U victim -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/verify_qualify.sql
Salida esperada:
alice demo
bob demo
Esto funciona porque pg_catalog.lower(...) obliga a PostgreSQL a usar la función incorporada.
PGPASSWORD='postgres' \
psql -h 127.0.0.1 -p 15432 -U postgres -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/fix.sql
La salida esperada puede incluir:
DROP FUNCTION
DROP TABLE
REVOKE
REVOKE
Luego volver a ejecutar la consulta de la víctima:
PGPASSWORD='VictimPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U victim -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/victim_query.sql
Salida esperada:
alice demo
bob demo
La función controlada por el atacante ha desaparecido, y la consulta devuelve cadenas normales en minúsculas.
docker compose up -d pg_fixed
docker compose ps
Verificar la versión:
docker exec -it cve1058_pg_fixed psql -U postgres -d demo_cve1058 -c "SELECT version();"
Resultado esperado: PostgreSQL 10.3.
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15433 -U attacker -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/exploit.sql
Salida esperada:
ERROR: permission denied for schema public
Esto significa que el atacante no puede crear la función falsa en public, por lo que la cadena de ataque se detiene antes de la resolución de nombres.
Para detener los contenedores:
docker compose down
Para eliminar volúmenes y restablecer el proyecto por completo:
docker compose down -v
Esta demo es intencionalmente inofensiva. No roba datos, accede a archivos ni ejecuta comandos del sistema operativo.
El exploit utiliza un prefijo de cadena visible y una tabla de registro para demostrar que PostgreSQL resolvió un nombre de función no calificado hacia un objeto controlado por el atacante.
El CVE oficial se refiere a pg_dump y otras aplicaciones cliente. Este repositorio demuestra el mismo fallo de confianza en la ruta de búsqueda en un entorno de aula seguro y reproducible.
Si un puerto ya está en uso, detén cualquier servicio local de PostgreSQL o cambia los puertos del host en docker-compose.yml.
Si la salida no coincide con los resultados esperados, restablece el entorno con:
docker compose down -v
docker compose up -d pg_vulnerable
Si psql no está instalado localmente, los comandos de inspección de versión y roles aún se pueden ejecutar con docker exec dentro de los contenedores.
Si el exploit falla en pg_vulnerable, asegúrate de que la base de datos se haya restablecido y de que scripts/exploit.sql se ejecute antes de scripts/fix.sql.