Seria o SQL Injection:
Jak zostać ekspertem od SQL Injection – cz. 1
Jak zostać ekspertem od SQL Injection – cz. 2
Jak zostać ekspertem od SQL Injection – cz. 3
Jak zostać ekspertem od SQL Injection – cz. 4
Jak zostać ekspertem od SQL Injection – cz. 5
Moja autorska seria artykułów poświęcona atakom SQL Injection, w dość obszerny sposób omawia zagadnienia związane z tą klasą ataków na aplikacje. Postaram się zilustrować częste błędy programistyczne/implementacyjne oraz ciekawe sposoby ataków i przykładów błędnie napisanego kodu.
Przykłady tej serii omawiam na przykładach MySQL oraz PHP. Dlaczego te technologie, skoro wiadomo, że istnieje wiele innych, lepszych? Uważam, że nauka bezpieczeństwa web aplikacji powinna omawiać błędy które bardzo często spotkasz w realnym świecie i których jest najwięcej. Aplikacji opartych na PHP i MySQL jest ogromna ilość i jeszcze wiele lat będą one dostępne.
Kolejnym argumentem jest to, że względnie łatwo omówić pewne klasy bezpieczeństwa na przykładzie PHP, gdzie składnia jest prosta i nawet początkujący zrozumie w czym tkwi błąd. To samo dotyczy się składni SQL.
Z czasem pokażę Ci, że znajomość konkretnych języków programowania nie jest najważniejsza w poszukiwaniu błędów, więc naukę rozpocznij od dogłębnego zrozumienia klas ataków. W taki sposób zdobędziesz doświadczenie wykorzystywania podatności na praktycznie dowolnym systemie i na dowolnej platformie.
Na podstawie takiej wiedzy, żaden inny system nie będzie już sprawiał Ci trudności w poszukiwaniu błędów – gwarantuję Ci to.
Ja sam zaczynałem właśnie od nauki podatności PHP i MySQL i z bardzo dużym powodzeniem wykorzystuję tak zdobytą wiedzę od wielu lat do dziś włącznie, co jakiś czas tylko ją uzupełniając.
Czego dowiesz się w części pierwszej „Jak zostać ekspertem od SQL Injection”?
W tej części opiszę Ci podstawowe zagadnienia składni języka SQL. Tylko te najważniejsze, umożliwiające Ci poszukiwanie Twoich pierwszych podatności – nie jest to pełny tutorial SQL, natomiast w zupełności wystarczający na tym etapie drogi do bycia ekspertem SQL Injection!
Cała seria artykułów opisuje najczęściej występujące rodzaje ataków wstrzyknięcia kodu SQL (ang. SQL Injection) w odniesieniu do aplikacji webowych tworzonych w technologii PHP z wykorzystaniem systemów bazodanowych MySQL. Omawiam tutaj szereg odmian ataku wstrzyknięcia kodu SQL.
Wprowadzenie do SQL Injection
Ataki typu SQL Injection polegają na wykorzystaniu błędów programistycznych, głównie w językach skryptowych (PHP, ASP itd.) ale nie ograniczają się do nich. Błędy te polegają na braku filtrowania danych wejściowych, które wykorzystywane są do dynamicznie generowanych zapytań SQL. Przez co możliwa jest zmiana całości lub fragmentu zapytania do systemu bazodanowego. Wykorzystanie podatności aplikacji na ataki wstrzyknięcia kodu SQL może doprowadzić do ujawnienia zawartości bazy danych lub jej modyfikacji.
Wprowadzenie do problematyki ataków SQL Injection
SQL (ang. Structured Query Language), jest językiem używanym w dostępie do baz danych. Aktualnym obowiązującym standardem SQL na dzień dzisiejszy jest SQL:2016. Strukturalny język zapytań SQL używamy do pobierania danych z bazy, aktualizacji rekordów w bazie, usuwania danych, wprowadzania danych oraz wykonywania zapytań do bazy.
Zapytania SQL dzielą się na trzy główne podzbiory:
– DML (ang. Data Manipulation Language) , czyli Język Manipulacji Danymi
- SELECT pobranie informacji z bazy danych,
- INSERT umieszczenie informacji danych w bazie,
- UPDATE zmiana danych w bazie,
- DELETE usunięcie danych z bazy.
– DDL (ang. Data Definition Language), czyli Język Definicji Danych
- CREATE tworzenie struktur takich jak tabela, baza, index itp.,
- DROP usunięcie struktur,
- ALTER zmiana struktur.
– DCL (ang. Data Control Language), czyli Język Kontroli nad Danymi
- GRANT – zarządzanie uprawnieniami do struktur.
W tym artykule omówię jedynie zbiór DML, gdyż jedynie go wykorzystujemy w atakach SQL Injection na aplikacje stworzone w oparciu o system bazodanowy MySQL. Systemy bazodanowe opierają się na międzynarodowych standardach SQL, lecz każdy z nich posiada dodatkowe implementacje języka, dodatkowe rozszerzenia oraz używają różnej składni, dlatego ten artykuł oraz przykłady w tu zawarte dotyczą systemu bazodanowego MySQL.
Błędy typu SQL Injection zaliczamyą do jednych z najczęściej występujących błędów z punktu widzenia bezpieczeństwa w aplikacjach webowych. Błędy tego typu są błędami aplikacji, nie zaś systemu bazodanowego, czy też konfiguracji serwera WWW. Atakujący często wykorzystują specjalne znaki ASCII, które po wstrzyknięciu do zapytania SQL, znacznie ułatwiają uzyskanie pożądanych informacji.
Znaki specjalne oraz funkcje i dyrektywy SQL
Poniżej opisana jest część znaków specjalnych oraz funkcji i dyrektyw SQL, które wykorzystywane są do modyfikacji i uzyskania informacji z baz danych w atakach typu SQL Injection. Znajomość ich będzie dla Ciebie kluczowa do wykonywania skutecznych testów w oparciu o różne warianty SQL Injection:
1. ‘ lub “
Ograniczniki ciągu znaków – znaki ujęte pomiędzy cudzysłowami lub apostrofami traktowane są jako tekst. Znaki ograniczeń tekstu wykorzystywane są do zamknięcia części zapytania w celu doklejenia kolejnej spreparowanej części zapytania SQL,
2. – lub #
Komentarze pojedynczych linii – symbole te służą do komentowania wyrażeń składających się z jednej linii. Część wyrażenia znajdująca się za tymi znakami nie jest interpretowana przez system bazodanowy i jest ignorowana. Używane są do komentowania oryginalnego fragmentu zapytania SQL, po doklejeniu spreparowanego fragmentu kodu,
3. /**/
Komentarz wielu linii – taki sposób komentowania służy do komentarzy składających się z wielu linii. Może służyć również do komentowania pojedynczej linii. Wszystko co jest pomiędzy /* oraz */ jest ignorowane. W przypadku wykorzystania takiego komentarza, w zapytaniu SQL, komentarz taki jest traktowany jako znak spacji. Podobnie jak wyżej, taki sposób komentowania może posłużyć do zniwelowania poprawnej części zapytania po doklejeniu spreparowanego kodu SQL. Umożliwia także w niektórych przypadkach omijanie zabezpieczeń wykrywających ataki, takich jak systemy IDS oraz IPS,
4. +
Znak dodawania oraz symbol spacji, gdy używamy w adresie URL. Może służyć do omijania systemów wykrywania włamań, wykonywania operacji arytmetycznych na bazie danych,
5. %
Symbol oznaczający dowolny ciąg znaków. W adresie URL wykorzystywany do poprzedzania wartości hexadecymalnych symboli ASCII. Może posłużyć do kodowania niebezpiecznych wyrażeń użytych w wysyłanym żądaniu HTTP do serwera, w celu ominięcia zabezpieczeń IDS oraz IPS. W systemie bazodanowym MySQL używany jako symbol oznaczający dowolny znak w zapytaniu SQL. W takim przypadku wykorzystujemy do ataku SQL Injection przy użyciu metody brutalnej z wykorzystaniem słowa kluczowego LIKE,
6. LIKE
Predykat stosowany do ataku brutalnego na zawartość pola tabeli, może posłużyć także przeciw wykorzystaniu systemów wykrywania włamań i innych systemów detekcji nieprawidłowości, w użyciu razem ze znakiem %
7. @zmienna
Wyrażenie oznaczające zmienną lokalną zadeklarowaną w systemie bazodanowym. Jeśli zmienna lokalna jest ustawiona w systemie bazodanowym, jej zawartość może zostać wyświetlona, podczas ataku typu SQL Injection,
8. @@zmienna
Wyrażenie oznaczające zmienną globalną zadeklarowaną w systemie bazodanowym. Zmienna globalna którą wyświetlamy przez skrypt podczas ataku typu SQL Injection. Przykładem takiej zmiennej jest zmienna @@VERSION, która przetrzymuje informacje o wersji serwera bazodanowego. Jest synonimem funkcji VERSION(). Może posłużyć do odczytu wersji serwera, w przypadku, gdy system wykrywania włamań reaguje na ciąg znaków zawierający słowo VERSION,
9. UNION
Operator służący do łączenia dwóch lub więcej rezultatów zapytań SQL. Podczas ataku typu SQL Injection, jest to najczęściej wykorzystywany operator, dzięki któremu pobieramy informacje z bazy danych. W przypadku, gdy skrypt zwraca jedną wartość wszystkich danych pobranych z bazy, atakujący doprowadza do zwrócenia wartości nieokreślonej NULL, przez pierwszą część zapytania i dokleja własne, zwracające pożądaną wartość,
10. SELECT
Instrukcja służąca do pobierania danych z tabel. W przypadku ataku, przy użyciu tego polecenia wybieramy określone dane z tabel,
11. CONCAT
Funkcja służąca do łączenia ciągów znaków w jeden ciąg. W przypadku ataku SQL Injection wykorzystywana do wypisywania kilku pól tabeli przy użyciu jedynie jednego warunku wyboru SELECT,
12. CHAR
Funkcja służąca do wypisywania znaku, na podstawie jego odpowiednika ASCII. Może zostać wykorzystana do ominięcia aktywnych i pasywnych zabezpieczeń. Poprzez tą funkcję mogą być wprowadzane dane w postaci heksadecymalnej, bez wstawiania ograniczników końca i początku danego ciągu znaków, np. napis ABC może być przedstawiony w postaci: char(0×414243), gdzie 0×41 oznacza ‘A’, 0×42 oznacza ‘B’ i 0×43 oznacza ‘C’,
13. IF
Instrukcja warunkowa służąca do wykonania określonych zapytań w przypadku zwrócenia wartości logicznej TRUE oraz FALSE. Używana w ataku typu Blind SQL Injection, gdzie żadna wartość tekstu nie jest wypisywana na ekran, co uniemożliwia sprawdzenie wartości logicznej wprowadzonego zapytania. W takim przypadku możliwe jest jedynie mierzenie czasów wykonywania się skryptu,
14. BENCHMARK
Funkcja umożliwiająca przeprowadzenie testów wydajnościowych podanego zapytania SQL. W połączeniu z instrukcją warunkową IF, atakujący może wykorzystać tą funkcję, w przypadku gdy skrypt podatny na atak nie zwraca żadnych wartości bezpośrednio na stronie WWW,
15. LOAD_FILE
Funkcja umożliwiająca wyświetlenie zawartości pliku znajdującego się po stronie serwera. Aby plik mógł być załadowany i wyświetlony, do pliku muszą być ustawione odpowiednie prawa dostępu, oraz jego rozmiar nie może przekroczyć maksymalnej dozwolonej wartości. W przypadku podatnej aplikacji, atakujący jest w stanie np. załadować i wyświetlić zawartość pliku /etc/passwd, zawierającego nazwy użytkowników systemu Linux,
16. SELECT INTO OUTFILE
Umożliwia zapis zawartości wyniku zapytania do określonego pliku. W połączeniu z innymi potencjalnymi błędami w aplikacji webowej może umożliwić atakującemu wykonanie dowolnego skryptu po stronie serwera WWW, podmianę witryny WWW itd.,
17. DATABASE
Umożliwia wyświetlenie nazwy bazy danych, z którą łączy się podatny skrypt WWW,
18. USER
Umożliwia wyświetlenie nazwy użytkownika, który jest połączony za pomocą skryptu z bazą danych, oraz nazwę hosta, z którego następuje połączenie,
19. CURRENT_USER
Zwraca nazwę użytkownika, z którego uprawnieniami działa skrypt oraz nazwę hosta,
20. LAST_INSERT_ID
Określa numer ostatnio wprowadzonego rekordu. W przypadku wielu wprowadzonych rekordów za pomocą jednego polecenia INSERT, wartość LAST_INSERT_ID jest zwiększana jedynie o 1,
21. VERSION
Funkcja wyświetlająca wersję systemu bazodanowego, który wykorzystuje skrypt.
Podsumowanie – SQL Injection
W tej części serii Jak Zostać Ekspertem od SQL Injection poznałeś podstawowe podzbiory SQL oraz dowiedziałeś się, które z nich wykorzystasz na co dzień w testach SQL Injection.
Poznałeś kluczowe zestawy znaków specjalnych oraz funkcji i dyrektyw SQL, takie “must have” do przejścia do kolejnego etapu – do aktywnego wykrywania podatności – Jak zostać ekspertem od SQL INJECTION – cz.2.
Co w kolejnej części?
W kolejnym artykule z tej serii – Jak zostać ekspertem od SQL INJECTION – cz.2 – dowiesz się w jaki sposób wykrywać podatności typu SQL Injection.
Zobaczysz jak w praktyce wykorzystać poznane funkcje i dyrektywy SQL, dowiesz się co to Blind SQL Injection i jak go wykrywać. Poznasz to “magiczne” or 1=1 jego zastosowanie i różne jego warianty – zero tajemnic.
Jeśli spodobał Ci się ten artykuł – udostępnij go dalej proszę, w taki sposób dotrze on do większej liczby osób.
Podziel się ze mną swoimi uwagami poniżej, cenne uwagi są zawsze mile widziane i pomogą mi odpowiedzieć na Twoje pytania 🙂