
Dimostrazione riproducibile basata su Docker dell'escalation dei privilegi di PostgreSQL CVE-2018-1058 tramite percorso di ricerca non controllato, con confronto tra ambienti vulnerabili e corretti.
Questo repository contiene il rapporto finale e gli artefatti di riproducibilità per:
CVE-2018-1058: Escalation dei Privilegi in PostgreSQL tramite Percorso di Ricerca Non Controllato
L'obiettivo è dimostrare il fallimento di fiducia del percorso di ricerca alla base di CVE-2018-1058 utilizzando un ambiente Docker locale sicuro.
La demo non riproduce l'esatto percorso di esecuzione storico di pg_dump. Riproduce invece la stessa causa principale descritta nella guida di PostgreSQL: uno schema scrivibile da un attaccante contiene un oggetto simile, e un'altra sessione risolve un nome non qualificato a quell'oggetto.
.
├── report.pdf
├── docker-compose.yml
├── README.md
└── scripts/
├── init.sql
├── init_safe.sql
├── exploit.sql
├── victim_query.sql
├── verify_qualify.sql
└── fix.sql
Il rapporto finale è report.pdf. Include l'analisi scritta e gli screenshot corrispondenti agli output attesi di seguito.
Non è richiesto alcun Dockerfile. Il progetto utilizza immagini ufficiali di postgres.
Gli screenshot sono incorporati direttamente in report.pdf, quindi non vengono forniti come file immagine separati.
Installa:
psql, opzionale ma raccomandatoLa demo utilizza due contenitori PostgreSQL:
Assicurati che le porte 15432 e 15433 siano libere.
L'ordine di esecuzione previsto è:
exploit.sql come attacker.victim_query.sql come victim e osserva il prefisso CVE-2018-1058 DEMO:.verify_qualify.sql come victim e osserva l'output normale in minuscolo.fix.sql come postgres.victim_query.sql e osserva l'output normale in minuscolo.exploit.sql sulla porta 15433 e osserva permission denied for schema public.docker compose up -d pg_vulnerable
docker compose ps
Risultato atteso: il servizio pg_vulnerable dovrebbe essere in esecuzione e mappato sulla porta 15432.
Controlla la versione di PostgreSQL:
docker exec -it cve1058_pg_vulnerable psql -U postgres -d demo_cve1058 -c "SELECT version();"
Risultato atteso: PostgreSQL 10.2.
docker exec -it cve1058_pg_vulnerable psql -U postgres -d demo_cve1058 -c "\du"
Ruoli attesi:
postgresattackervictimL'attaccante non è un superutente PostgreSQL.
Esegui lo script dell'attaccante:
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
Output atteso:
CREATE TABLE
GRANT
GRANT
CREATE FUNCTION
Questo crea:
public.exploit_log;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
Output atteso:
CVE-2018-1058 DEMO: Alice Demo
CVE-2018-1058 DEMO: Bob Demo
Questo mostra che la query normale della vittima ha risolto lower(...) nella funzione controllata dall'attaccante.
PGPASSWORD='AttackerPw!ChangeMe' \
psql -h 127.0.0.1 -p 15432 -U attacker -d demo_cve1058 \
-c "TABLE public.exploit_log;"
Risultato atteso: almeno due righe in public.exploit_log, una per ogni riga elaborata dalla query della vittima.
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
Output atteso:
alice demo
bob demo
Funziona perché pg_catalog.lower(...) forza PostgreSQL a usare la funzione integrata.
PGPASSWORD='postgres' \
psql -h 127.0.0.1 -p 15432 -U postgres -d demo_cve1058 \
-v ON_ERROR_STOP=1 -f scripts/fix.sql
L'output atteso può includere:
DROP FUNCTION
DROP TABLE
REVOKE
REVOKE
Quindi riesegui la query della vittima:
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
Output atteso:
alice demo
bob demo
La funzione controllata dall'attaccante è sparita e la query restituisce stringhe minuscole normali.
docker compose up -d pg_fixed
docker compose ps
Controlla la versione:
docker exec -it cve1058_pg_fixed psql -U postgres -d demo_cve1058 -c "SELECT version();"
Risultato atteso: 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
Output atteso:
ERROR: permission denied for schema public
Ciò significa che l'attaccante non può creare la funzione falsa in public, quindi la catena di attacco si ferma prima della risoluzione del nome.
Per fermare i contenitori:
docker compose down
Per rimuovere i volumi e resettare completamente il progetto:
docker compose down -v
Questa demo è intenzionalmente innocua. Non ruba dati, non accede a file e non esegue comandi del sistema operativo.
L'exploit utilizza un prefisso di stringa visibile e una tabella di log per dimostrare che PostgreSQL ha risolto un nome di funzione non qualificato in un oggetto controllato dall'attaccante.
La CVE ufficiale riguarda pg_dump e altre applicazioni client. Questo repository dimostra lo stesso fallimento di fiducia del percorso di ricerca in un contesto didattico sicuro e riproducibile.
Se una porta è già in uso, ferma qualsiasi servizio PostgreSQL locale o modifica le porte host in docker-compose.yml.
Se l'output non corrisponde ai risultati attesi, resetta l'ambiente con:
docker compose down -v
docker compose up -d pg_vulnerable
Se psql non è installato localmente, i comandi di ispezione della versione e dei ruoli possono comunque essere eseguiti con docker exec all'interno dei contenitori.
Se l'exploit fallisce su pg_vulnerable, assicurati che il database sia stato resettato e che scripts/exploit.sql sia eseguito prima di scripts/fix.sql.
| Servizio | Versione | Nome contenitore | Porta host | Scopo |
|---|
pg_vulnerable | PostgreSQL 10.2 | cve1058_pg_vulnerable | 15432 | dimostrazione vulnerabile |
pg_fixed | PostgreSQL 10.3 | cve1058_pg_fixed | 15433 | confronto corretto/rinforzato |