Na czym polega SQL Injection

Jadwiga Gnybek

Wśród różnorodnych technik przełamywania zabezpieczeń systemów IT, SQL Injection wydaje się być wciąż techniką cieszącą się największą „popularnością” wśród hakerów. Przyjrzyjmy się zatem na czym polega ta metoda i w jaki sposób możemy uchronić przed potencjalnym atakiem nasze aplikacje.

Metodą SQL Injection corocznie atakowane są tysiące witryn webowych. Powszechność internetowych witryn sklepowych i portali B2B sprawia, że w sieci „wystawionych” jest coraz więcej danych, które warto by nielegalnie posiąść. To właśnie jest motorem napędowym coraz to bardziej rozbudowanych technik hakerskich SQL Injection. Od dawna bowiem nie jest to już tylko zabawa w „policjantów i złodziei”; jest to ciemna strona biznesu, obejmująca zarówno szpiegostwo przemysłowe jak i nowoczesną gałąź przestępstw gospodarczych.

Wprowadzenie

Podobnie jak kolejne wersje aplikacji i systemów operacyjnych, techniki hakerskie też doczekały się nowych „edycji”. Powstało bowiem pojęcie SQL Injection 2.0 – jest to kolejna, tym razem zautomatyzowana przy pomocy popularnych wyszukiwarek odsłona tego sposobu przełamywania zabezpieczeń.

Ale zacznijmy od podstaw. Na czym polega SQL Injection? Jest to jedna z technik przełamywania zabezpieczeń, opierająca się na możliwości wprowadzania danych przez niewalidowane pola tekstowe, wprowadzające z kolei parametry zapytań SQL wykonywanych na bazach danych działających na rzecz aplikacji webowych. Zadaniem hakera jest wprowadzenie do zapytania SQL ciągu znaków diametralnie zmieniającego jego działanie. Ciąg taki można do aplikacji wprowadzić w dwojaki sposób: poprzez pole tekstowe przeznaczone do parametryzowania zapytań lub poprzez przyłączanie „złośliwego” kodu do łańcucha URL.

Rozpatrzmy jeden z prostszych przypadków. Celem ataku jest baza danych działająca w tle aplikacji webowej. Kluczem do dostępu do bazy jest formatka logowania, w którą uprawnieni użytkownicy wpisują nazwę użytkownika i hasło. Jednym z prostszych sposobów jest wprowadzenie do pola nazwy użytkownika na przykład następującego ciągu znaków „OR 1=1 –„. Spójrzmy co zrobi on z zapytaniem SQL. Programista aplikacji zaplanował wykonanie następującego zapytania:

SELECT * FROM users WHERE username ='$uid' AND password = '$pwd';

Gdzie $uid i $pwd są odpowiednio nazwą i hasłem uprawnionego do logowania się do aplikacji użytkownika. Jeśli haker wprowadzi zamiast nazwy użytkownika ciąg znaków „‚a’ OR 1=1 –” to zapytanie będzie wyglądało w następujący sposób:

SELECT * FROM users WHERE username ='a' OR 1=1 --' AND password = 'pwd'

Ta sekwencja cudzysłowów spowoduje obcięcie zapytania do postaci:

SELECT * FROM users WHERE username = 'a' OR 1=1;

Ponieważ 1=1 jest wyrażeniem zawsze prawdziwym, login na konto nieistniejącego użytkownika „a” zakończy się sukcesem.

Zgubna automatyzacja

Duża liczba udanych włamań tą techniką nie pozostawia złudzeń co to tego, że żmudny proces wyszukiwania serwerów podatnych na takie ataki został zautomatyzowany. Przy czym automatyzację należy tu rozumieć jako zrównoleglenie prac nad: wyszukiwaniem serwerów podatnych na taki atak, przygotowywaniem odpowiedniego exploitu i nielegalne pozyskiwanie danych. Do automatyzacji najbardziej nadają się dwa ostatnie działania. Odpowiednie narzędzia umożliwiają skuteczne ataki nawet mniej doświadczonym hakerom. To, co kiedyś wymagało bardziej zaawansowanej wiedzy (na przykład blind SQL injection), teraz wymaga jedynie posiadania odpowiednich narzędzi. Oczywiście działanie tych narzędzi rejestrowane jest przez mechanizmy logowania aktywności użytkowników, ale skrócenie czasu pomiędzy znalezieniem podatnego serwera, a wyprowadzeniem z niego danych znacznie podnosi prawdopodobieństwo sukcesu.

Oczywiście wiadomo, że ile technik zabezpieczeń i pomysłów na ich złamanie, tyle potencjalnych narzędzi. A każde z nich może wykonywać różne dające się automatyzować operacje. Do najczęstszych zautomatyzowanych działań hakerskich zaliczyć można: wprowadzanie oszukujących ciągów znaków do parametrów zapytań lub adresów URL; określanie typu bazy danych pracującej na potrzeby danej aplikacji; ekstrahowanie struktur bazodanowych; pobieranie danych za pośrednictwem GUI lub poprzez „przeszukiwanie binarne” czy też „instalowanie” w aplikacjach tylnych drzwi (backdoors). Poznajmy funkcjonalności kilku z nich.

Priamos to program opisywany czasem jako narzędzie do testowania podatności. Wprawdzie wymaga ręcznej konfiguracji miejsca ataku, ale świetnie nadaje się do przeczesywania podatnej bazy danych i pozyskiwania informacji o jej strukturze. Do wyszukiwania miejsc podatnych na atak nadaje się za to Power Injector. Umożliwia on również wielowątkowe żmudne przeczesywanie struktury podatnej atakowanej bazy danych. Do atakowania aplikacji współpracujących z Microsoft SQL Server przygotowany został program o dźwięcznej nazwie SQL Ninja. Jego ataki nakierowane są na konkretną procedurę o nazwie Xp_cmdshell. Znacznie bardziej inteligentnym urządzeniem jest SQL Map. Potrafi on wyszukiwać punkty podatne na „zastrzyki”, wykorzystując do tego celu wyszukiwarkę Google.

Oczywiście lista tych narzędzi jest długa, a naszym celem nie jest ich popularyzacja. Zatrzymajmy się więc teraz na chwilę na zagadnieniu wyszukiwania podatnych celów. Niezwykle ciekawym jest bowiem problem wykorzystywania do tego celu powszechnie używanych wyszukiwarek internetowych, gdyż specjalnie przygotowane zapytania pozwalają hakerowi szybko uzyskać z tego źródła listę dostępnych w Internecie aplikacji potencjalnie podatnych na atak przez SQL injection. Zapytań takich nawet samodzielnie wymyślać nie trzeba, można je bowiem w dużym wyborze znaleźć na hakerskich portalach. Wynikiem takiego przeszukiwania Internetu jest nie tylko adres domeny zawierającej aplikację nadającą się jako cel ataku, ale również wskazanie konkretnego punktu, gdzie atak taki powinien być skierowany. Teraz wystarczy tylko wprowadzić te dane do automatu realizującego atak. Czyli pełna automatyzacja zrealizowana stosunkowo prostymi metodami. Pamiętać jednak należy, że takie upublicznianie sposobów atakowania witryn jest (przynajmniej teoretycznie) bronią obosieczną i może być użyta również przez programistów w celu wyszukiwania własnych błędów. Przykładem takiej programistyczno hakerskiej aplikacji jest Goolag Scanner. Jest to aplikacja napisana przez członków z grupy Cult of the Dead Cow, mająca pomóc programistom w wyszukiwaniu błędów na stronach internetowych i wykorzystująca mechanizmy do wyszukiwania informacji Google. Goolag Scanner jest oczywiście narzędziem darmowym i działa na zasadzie filtracji danej witryny pod kątem znanych mu luk i błędów, które w konsekwencji mogą stać się przyczynkiem do włamania. Po skończonej analizie skaner generuje raport z możliwymi uchybieniami w budowie strony. Warto jednak zauważyć, że Cult of the Dead Cow to hakerzy, więc z jednej strony wiedzą co robią, z drugiej zaś nie wiadomo jakie są ich prawdziwe zamiary.

Atak i co dalej?

Przełamywanie zabezpieczeń aplikacji metodą SQL injection może być traktowane jako sposób na pozyskanie danych, ale może także stanowić wstęp do innych działań. Przykładem może być przejęcie kontroli nad aplikacją i zmiana publikowanych tam treści. Aby takie działanie było możliwe, witryna musi być podatna nie tylko na wykonywanie zainfekowanych poleceń SELECT. Trzeba znaleźć też sposób na wprowadzenie „z zewnątrz” poleceń INSERT lub UPDATE.

Prześledźmy bez zagłębiania się w zbytnie szczegóły scenariusz innego wykorzystania SQL injection. Naszym celem jest nie tyle bezpośrednia eksploracja danych dzięki uzyskaniu nieautoryzowanego dostępu do bazy. Chcemy raczej otworzyć sobie drogę do dalszych hakerskich działań. W pierwszym kroku haker modyfikuje zapytanie SQL – tak, aby dodać do wybranych pól tekstowych bazy danych element IFRAME HTML. IFRAME zawiera przekierowanie do serwera zawierającego potrzebne hakerowi do dalszych działań elementy złośliwego oprogramowania (malware). W chwili gdy użytkownik zainfekowanej aplikacji odczyta z bazy zmodyfikowaną zawartość pola tekstowego, nieświadom niczego ściągnie na swój komputer Trojana lub oprogramowanie rejestrujące pracę klawiatury. Dalsze działania hakera będą zależały oczywiście od celu ataku, ale droga do pozyskania wszystkich informacji „przepływających” przez nasz komputer stoi otworem. Niestety wszystkie te działania są dla użytkownika zupełnie „niewidoczne”. W czasie gdy Web browser renderuje stronę HTML, którą chcieliśmy wyświetlić, niejako „w tle” pobieramy również złośliwe oprogramowanie, które udaje część niezbędną do wyświetlenia oczekiwanej przez nas strony. Innym sposobem ataku „skojarzonego” z SQL injection jest Denial of Service (DoS). Konsekwencją takiego ataku może być zajęcie bazy jakimś dużym zapętlonym zapytaniem lub nawet wydanie bazie polecenia SHUTDOWN. Generalnie rzecz biorąc, celem takiego ataku jest zatrzymanie bazy danych działającej na potrzeby atakowanej aplikacji.

Atak przez procedury

Wracając do SQL injection, jedną z jego najgroźniejszych implementacji jest bezpośredni atak na bazę za pośrednictwem składowanych w bazie procedur. Programiści umieszczający „swoje” procedury w bazie danych Oracle, są oczywiście zobowiązani do nadania innym użytkownikom bazy prawa do ich wykonywania. Nie muszą jednak nadawać tym użytkownikom praw do wszystkich obiektów, z których dana procedura korzysta. Procedura wykonuje się bowiem zawsze korzystając z przywilejów, jakie w bazie posiada jej twórca (właściciel). Łatwo więc zauważyć, że jeśli procedura podatna jest na SQL injection, pozwala hakerowi na realizację swoich planów z wykorzystaniem uprawnień właściciela procedury, który nierzadko jest administratorem bazy. Oto przykład kodu w którym haker posługuje się parametrem RESULT_TABLE:

PROCEDURE VALIDATE_LAYER(LAYER IN VARCHAR2, RESULT_TABLE IN VARCHAR2) IS
......
UPDATE_STR:='INSERT INTO' || RESULT_TABLE 'VALUES(:gid,:gid_result)';
......
LOOP
    BEGIN
        FETCH QUERY_CRS INTO GID;
        EXIT WHEN QUERY_CRS%NOTFOUND;
        GID_RESULT:= MDSYS.MD2.VALIDATE_GEOM
        (UPPER(DBMS_ASSERT.QUALIFIED_SQL_NAME(LAYER) ), GID, NULL);
        EXECUTE IMMEDIATE UPDATE_STR USING GID, GID_RESULT;

Zagrożenie tego typu atakiem jest oczywiście tym większe, im większa jest liczba procedur składowanych w bazie. Można więc powiedzieć, że zagrożenie to ciągle rośnie. Zarówno za sprawą procedur do bazy dopisywanych, jak i tych umieszczanych w bazie standardowo. Jedną z procedur wskazywanych jako podatną na iniekcje jest będąca częścią Oracle Portal procedura WWW_RENDER_REPORT. Ponieważ procedura ta jest dostępna za pośrednictwem Portal URL, umożliwia przejęcie kontroli nad stworzonym przy użyciu tych narzędzi portalem.

Jak się bronić?

Jak widać, zagrożenia czyhają zewsząd. Cóż robić? Zabezpieczać! Zmieniać podatne fragmenty aplikacji. Sprawdzać szczelność zabezpieczeń i znów łatać dziury. Może nie brzmi to optymistyczne, ale działanie takie wydaje się wykonalne – pod warunkiem, że firma nasza posiada kody użytkowane aplikacji lub może taką pracę zlecić firmie będącej autorem rozwiązania. Mniej optymistyczne jest natomiast to, że jest to proces ciągły. Zabezpieczenie się przed jednym typem podatności wywołuje wynalezienie innego sposobu, przed którym znów musimy się bronić. Jest to zatem proces absorbujący sporo sił i środków, wymagający cyklicznego przygotowywania i wgrywania kolejnych poprawek. Nieco prościej jest, jeśli nasza aplikacja jest produktem „z półki”. Wtedy możemy oczekiwać, że praca ta zostanie wykonana po stronie jej twórców, a my jako klienci otrzymamy możliwie szybko kolejne patche.

Niezależnie od uszczelniania kodu aplikacji jako sposobu ochrony przed atakami hakerów, warto również zainwestować w inne środki prewencji. W przypadku SQL injection skuteczną metodą jest stosowanie ścian ogniowych z systemem IPS (Intrusion Prevention Systems). Dokonuje on przeszukania wszystkich przychodzących ciągów HTTP w poszukiwaniu podejrzanych fragmentów SQLa. Niestety przeszukania te w początkowym okresie pracy są mało inteligentne i zatrzymują również takie zapytania, na które nasza aplikacja oczekuje i powinna odpowiadać. Dużo pracy administratorów wymaga bowiem „nauczenie” systemów zabezpieczających, na jakie zapytania powinny zezwalać a na jakie nie. Nigdy również nie ma stuprocentowej pewności, że nauczyliśmy automat wszystkiego, z czym przyjdzie mu się zmierzyć.

Bezsprzecznie bardziej zaawansowanym technologicznie rozwiązaniem są pakiety chroniące przed SQL injection bez konieczności przejścia etapu „uczenia”, czyli ręcznego strojenia zasad filtracji. Jest to możliwe dzięki jednoczesnemu zastosowaniu modelu białych i czarnych list (dynamic positive – white list i dynamic negative – black list). Skutecznym środkiem prewencji jest również jednoczesne stosowanie pakietu SecureSphere; jest to rozwiązanie wielowarstwowe, poszukujące śladów prób włamania na wielu płaszczyznach: walidacji HTTP, sygnatur IPS, czy mechanizmów Dynamic Profiling. Dla przykładu: zadaniem modułu Dynamic Profiling jest śledzenie aktywności użytkowników i tworzenie schematów poprawnego wykorzystywania aplikacji. Schematy te służą następnie jako baza do porównania zapytań kierowanych do bazy i wyłapywania takich, jakie jeszcze nigdy nie były wykonywane – są więc potencjalnie niebezpieczne. Oczywiście moduł ten uczy się ciągle i reaguje na ewentualne zmiany w funkcjonalności monitorowanej aplikacji.

Podsumowanie

Uczą się moduły zabezpieczeń, uczą się też hakerzy. Na każde kolejne wcielenie pomysłów na atak, wcześniej czy później wymyślona zostanie obrona. I to w dobie szalejącego kryzysu niech będzie naszym światełkiem w tunelu. Pracy nam nie zabraknie.