12:21
7/7/2017

Kontynuujemy nasz cykl videoporadników pt. “Niebezpieczny Poradnik Pentestera“. W drugim odcinku (już dostępny na YouTube!) przyglądamy się atakowi SQL injection, który od kilku lat nie powinien już wystąpić w żadnej standardowo pisanej aplikacji, gdyż metody ochrony są znane, proste w użyciu, a jak ktoś programuje z wykorzystaniem frameworka, ta podatność jest prawie niemożliwa do wprowadzenia w kod. Jako pentesterzy, wiemy jednak, że takie błędy wciąż się zdarzają…

Przed publikacją tego artykułu, rzuciliśmy okiem na statystyki wykonywanych przez nas testów penetracyjnych za ostatnie pół roku. W testowanych przez nasz zespół pentesterski serwisach internetowych, podatności SQL injection (i Blind SQL injection) odkryliśmy aż w 6 przypadkach. Bardzo często w tzw. “legacy” kodzie, ale niekiedy także w “autorskich hackach“, czyli wymagających wyjścia poza framework sytuacjach (np. w trakcie obsługi przez serwis danych z ciasteczek, które lądowały do bazy). A więc wciąż warto testować serwisy pod kątem tej podatności. I dziś pokazujemy, jak można to zrobić przy użyciu popularnego narzędzia sqlmap.

Jeśli chciałbyś poznać więcej technik testowania swojej webaplikacji pod kątem bezpieczeństwa i na żywo, w dedykowanym labie, uruchomić starannie wyselekcjonowane i sprawdzone narzędzia służące do atakowania (i obrony!) serwisów internetowych, to zapraszamy na nasze szkolenie z Bezpieczeństwa Webaplikacji — najbliższe edycje odbędą się we wrześniu w Warszawie, Krakowie, Wrocławiu i Gdańsku i zostały już pojedyncze wolne miejsca!. Aby przekonać się, jak wygląda to szkolenie, zapraszamy do zapoznania się z opiniami uczestników ostatniego terminu tego szkolenia. Pierwszym 3 osobom rejestrującym się z kodem “videoporadnik” przyznamy 100PLN rabatu.

Czym jest SQL injection?

Ataki typu SQL Injection polegają na wstrzyknięciu do wnętrza zapytania SQL przygotowanego przez programistę, swojej części kodu, która zmieni zachowanie atakowanej aplikacji. W większości przypadków, do przeprowadzenia tego rodzaju ataków atakujący musi dysponować zaawansowaną wiedzą z zakresu języka SQL, ale nie zawsze jest to wymagane. W tym artykule przedstawimy jedno z popularnych narzędzi do przeprowadzania zautomatyzowanych testów bezpieczeństwa, które nie wymaga od użytkownika niczego, poza wskazaniem parametrów w serwisie, co do której mamy podejrzenia, że mogą być przetwarzane w zapytaniach SQL.

Wersja wideo poradnika

Poradnik jest dostępny na naszym kanale YouTube, ale dla Waszej wygody osadzamy go tutaj:

…a poniżej tekstowy opis odcinka.

Przygotowanie środowiska

Jeśli widziałeś poprzedni odcinek naszej serii i masz już gotową konfigurację, którą tam przygotowywaliśmy, możesz przejść do kolejnego rozdziału, ponieważ w tym poradniku będziemy pracować na identycznym środowisku dockerowym. Jeśli nie, wróć do pierwszego odcinka i skonfiguruj dockera na swoim VPS (my do tego celu wykorzystujemy i polecamy serwery z Digital Ocean, bo dzięki szybkim dyskom SSD i rozliczaniu sekundowym nie tylko sprawnie działają, ale dodatkowo dzięki tej promocji, 2 miesiące pracy na serwerze możecie mieć za free).

Aby szybko postawić niezbędne nam do testów środowisko, posłużymy się programem docker-compose. W tym celu najpierw musimy ściągnąć plik konfiguracyjny z opisem środowiska testowego:

wget https://nbzp.cz/docker-hacklab

Teraz uruchamiamy docker-compose z następującymi parametrami:

docker-compose -f docker-hacklab up -d

Wyjaśnienie parametrów:

    -f docker-hacklab == wczytaj scenariusz z opisem laba, który chcemy stworzyć (to jest nazwa ściągniętego wcześniej pliku)

    up == aktywuj skonfigurowany klaster dockerów

    -d == wszystkie utworzone i uruchomione kontenery mają działać w tle

W zależności od szybkości łącza i od tego, czy jest to czysty system operacyjny, czy taki na którym już wcześniej stawialiśmy kontenery, powyższe polecenie może wykonywać się od kilku sekund do około 20 minut. Jeśli wszystko zadziałało, powinniśmy w systemie widzieć dwa nowe kontenery o nazwie “kali” i “dvwa“, czyli naszą aplikację “do bicia”.

Możesz to sprawdzić za pomocą polecenia:
docker ps

Domena “nbzpvps”

W naszych poradnikach posługujemy się domeną http://nbzpvps/, która wprowadziła lekkie zamiesznie w komentarzach pod ostatnim wpisem. Jest to jedynie alias zdefiniowany na lokalnym komputerze za pomocą takiego wpisu w pliku hosts.

1.2.3.4 nbzpvps

Gdzie 1.2.3.4 to numer IP przydzielony przez DigitalOcean lub innego dostawcę serwerów VPS.

Dla przypomnienia — na systemach Linux/Unix/OSX plik hosts znajduje się tu:
/etc/hosts

A na Windowsie będzie to:
Windows\System32\Drivers\etc\hosts

Wybieranie celu do ataku

Testy — podobnie jak w poprzednim odcinku — przeprowadzamy na specjalnie przygotowanej, domyślnie “dziurawej” aplikacji DVWA (Damn Vulnerable Web Application). Po zalogowaniu się danymi admin/password, przechodzimy do zakładki “SQL Injection”. W formularzu który pojawi się na ekranie, można wpisać dowolne dane — czy to liczbowe, czy tekstowe. My wpisaliśmy liczbę: 123

Po wysłaniu formularza, adres URL strony zmienił się na:

http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#

Ten URL będzie startowym adresem dla naszego narzędzia.

Instalacja SQLmap

Na początek musimy połączyć się z kontenerem kali-linux i zainstalować na nim aplikację SQLmap. Wydajemy więc kolejno dwa polecenia:

docker attach kali
apt-get install sqlmap

Drugie z poleceń trzeba będzie dodatkowo zatwierdzić klawiszem ENTER, po czym nastąpi instalacja kilkunastu pakietów, niezbędnych do działania aplikacji.

Pierwsze uruchomienie SQLmapa

Podstawowe wywołanie programu ogranicza się do podania nazwy aplikacji i parametru “-u” definiującego cel ataku. Wpisujemy więc:

sqlmap -u "http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#"

W większości przypadków, ta składnie powinna wystarczyć, by narzędzie przeprowadziło szereg testów pod kątem podatności SQL injection. Niestety, DVWA jest aplikacją, która wymaga zalogowania, więc tak uruchomiony SQLmap zostanie przekierowany na adres /login.php. Nie jest to zachowanie oczekiwane, więc można nacisnąć CTRL+C aby przerwać testy.

Zdobywanie tokena sesyjnego

W aplikacjach webowych fakt bycia zalogowanym rozpoznawany jest najczęściej za pomocą ciasteczka sesyjnego (np. w przypadku aplikacji pisanych w PHP, będzie to “PHPSESSID“). Aby uruchomić SQLmapa z zalogowanego użytkownika (tj. z odpowiednim ciasteczkiem), musimy wcześniej zdobyć wszystkie ciastka, jakie zostały utworzone przez DVWA.

Można to zrobić za pomocą dowolnego dodatku do przeglądarki pokazującego zawartość cookies lub korzystając z natywnych jej rozwiązań, tzw. inspektora, bedącego elementem narzędzi developerskich. W inspektorze (po zalogowaniu do DVWA!) otwieramy zakładkę Sieć/Network, a następnie odświeżamy stronę i klikamy na zapytanie wysłane do adresu, który chcemy zaatakować (prawdopodobnie pierwszy na liście).

W sekcji Nagłówki/Headers odszukujemy pole nagłówka związane z obsługą ciasteczek. Będzie ono prawdopodobnie poprzedzone zwrotem “cookie” lub “set-cookie“. Należy skopiować wszystkie ciastka jakie widoczne są na tej liście. Prawdopodobnie będą to dwie pozycje: PHPSESSID i security.

Na naszym filmie wygląda to tak:
PHPSESSID=123456789ABCDEF456321; security=high

Po pierwsze musimy zmienić poziom bezpieczeństwa z “high” na “low”. Jest to mechanizm stosowany jedynie w DVWA. Jeśli wartość ustawiona jest na “high” — wszystkie luki w tej aplikacji są załatane i nie da się wykorzystać żadnej podatności. Oczywiście podczas pentestów prawdziwego serwisu, raczej nie znajdziesz w nim ustawień pozwalających obniżyć poziom bezpieczeństwa ;)

Nowa wartość ciasteczek będzie więc wyglądać następująco:
PHPSESSID=123456789ABCDEF456321; security=low

Jeśli słowny opis tej procedury jest dla Ciebie zbyt skomplikowany, to warto zobaczyć jak wykonać te kroki w naszym wideo poradniku.

Rekonesans z użyciem SQLmap i ciasteczek

Mamy już wartość tokena sesyjnego i dodatkowe ciastko sterujące poziomiem bezpieczeństwa serwisu — możemy je więc dodać do podstawowego polecenia za pomocą parametru “–cookies“.

sqlmap -u "http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#" --cookie="PHPSESSID=123456789ABCDEF456321; security=low"

Już po kilku sekundach, SQLmap zaraportuje dwie informacje:

  • baza danych w atakowanej aplikacji to MySQL
  • prawdopodobnie, parametr ID z adresu URL jest podatny na SQL Injection

Aplikacja zapyta, czy chcemy pominąć testy przygotowane dla innych baz danych, skoro najprawdopodobniej nasza ofiara działa na silniku MySQL. Odpowiadamy twierdząco (ENTER).

Kolejne pytanie będzie dotyczyło wykonywania rozszerzonych testów bezpieczeństwa. Tutaj dla oszczędności czasu warto zaprzeczyć (naciskamy ‘n‘ i ENTER). Testy tego typu przydają się, jeśli SQLmap nie może znaleźć “wstrzyknięcia” podczas standardowego skanowania. Tutaj mamy jednak pewność, że aplikacja jest na tyle dziurawa, że nie ma sensu tracić czasu by się o tym bardziej przekonać.

Ostatnie pytanie narzędzia dotyczy testowanych parametrów. SQLmap wykrył, że z użyciem parametru “ID” można bez problemu dostać się do bazy. Na pytanie, czy chcemy szukać innych podatnych parametrów, odpowiadamy więc przecząco. Jeden punkt zaczepienia w tym przypadku w zupełności nam wystarczy.

Na ekranie z podsumowaniem zobaczymy przykładowe zapytania, które można wysłać do aplikacji, aby wywołać atak SQL Injection. Jak w większości aplikacji, tak i w SQLmapie, możemy sterować ilością i złożonością wyświetlanych na konsoli danych dotyczących pracy narzędzia (parametr -v). Informacje te mogą być przydatne dla osób, które chce nauczyć się ręcznego przeprowadzania takich ataków. My jednak chcemy wykonać atak w pełni zautomatyzowany, na tym etapie bez głębszego wnikania w to, co dzieje się “pod spodem”.

Właściwy atak

Po wstępnym rekonesansie, SQLmap utworzył konfigurację dla atakowanego serwisu. Testy dotyczące rodzaju bazy danych czy podatnych parametrów nie będą już wykonywane. Każde kolejne uruchomienie aplikacji będzie wykorzystywać wiedzę zdobytą w poprzednich krokach.

Zobaczmy więc, co jeszcze potrafi SQLmap — uruchamiamy krótki spis parametrów.

sqlmap --help

Spróbujmy np. pobrać tzw. banner bazy danych, czyli nazwę, którą się ona przedstawia (przeważnie jest to nazwa produktu + wersja). Według listy przełączników, opcja którą powinniśmy dodać do naszego wywołania to “-b”. Doklejamy więc ją do poprzedniego polecenia:

sqlmap -u "http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#" --cookie="PHPSESSID=123456789ABCDEF456321; security=low" -b

W outpucie komendy znajdziemy linijkę oznaczoną jako “banner: “, z której dowiemy się, że testowana baza danych to MySQL w wersji 5.5.38, uruchomiona na serwerze Ubuntu 14.04.

W identyczny sposób (zamieniając “-b” na inny przełącznik) możemy np. wylistować spis wszystkich tabel w bazie danych. Robimy to za pomocą parametru –tables

sqlmap -u "http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#" --cookie="PHPSESSID=123456789ABCDEF456321; security=low" --tables

Na liście wyciągniętych danych widać tabelę users. Spróbujmy pobrać jej zawartość. Robimy to za pomocą dwóch parametrów:

    -T <tabela> == definiuje tabelę docelową
    –dump == pobiera dane

Kompletne polecenie wygląda więc następująco:

sqlmap -u "http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#" --cookie="PHPSESSID=123456789ABCDEF456321; security=low" -T users --dump

Łamanie haseł dostępowych do MySQL

Mając dostęp do bazy danych, często (choć to zależy od uprawnień i poprawności hardeningu serwera bazodanowego) możemy pobrać hashe haseł należących do innych użytkowników. SQLmap posiada moduł służący do pobierania i łamania tych hashy. Służy do tego parametr –passwords.

Kompletne polecenie:

sqlmap -u "http://<domena>/vulnerabilities/sqli/?id=123&Submit=Submit#" --cookie="PHPSESSID=123456789ABCDEF456321; security=low" --passwords

Zadane zostaną dwa pytania. Pierwsze, czy chcemy zapisać pobrane hashe w plikach tymczasowych (odpowiadamy wedle uznania — my na filmie odpowiedzieliśmy ‘N’) oraz czy chcemy złamać pobrane hashe za pomocą metody słownikowej. Na drugie pytanie odpowiadamy twierdząco, bo to jest celem naszych działań.

Jeśli wybierzemy metodę słownikową, zostaniemy zapytani o plik ze słownikiem. Jako, że nie przygotowaliśmy wcześniej takiego pliku, posłużymy się standardową listą haseł dołączoną do sqlmapa. Wystarczy więc tylko nacisnąć ENTER.

Ostatnie pytanie dotyczy sprawdzania sufixów. Jeśli się na to zgodzimy, to do haseł ze słownika dodawane będą popularne końcówki. Jeśli słowo to np. “kwiatek”, to program sprawdzi hasła: kwiatek, kwiatek123, kwiatek!, kwiatek555 itd. Zwiększy to kilkudziesięciokrotnie czas potrzebny na łamanie hashy, ale zwiększy także prawdopodobieństwo złamania hasha. Jako, że pracujemy na wyjątkowo podatnej aplikacji webowej, założyliśmy, że hasło nie jest skomplikowane, więc zrezygnowałem z testowania sufixów.

Teraz nasz ekran zaczyna przypominać terminal znany z hackerskich filmów rodem z Hollywood. Łamanie haseł odbywa się jednak naprawdę. Po pewnym czasie (zależnym od rozmiarów słownika), hasło powinno zostać złamane. W tym przypadku brzmiało ono: hacker.

Ręczne połączenie do bazy danych

Chcąc zweryfikować, czy pozyskane dane dostępowe są poprawne, możemy spróbować połączyć się z docelową bazą danych. Aby to zrobić, musimy na początek zainstalować klienta MySQL.

apt-get install default-mysql-client

A następnie uruchomić go z parametrami:

mysql -h <host> -u admin -p<haslo>

Opis parametrów:

  • -h <host> == definiujemy adres bazy danych. W środowisku testowym możemy tam wpisać po prostu “dvwa”.
  • -u admin == definicja nazwy użytkownika. “admin” to konto, które pojawiło się na ekranie po udanym złamaniu hashy haseł.
  • -p<hasło> == hasło zdobyte metodą słownikową

Jeśli po wykonaniu tego polecenia zobaczysz znak zachęty MySQL i brak jakichkolwiek błędów, będzie to oznaczało, że jesteś już w systemie docelowym. Od tego momentu znajomość języka SQL jest niezbędna. Jeśli jednak go nie znasz, zawsze możesz rozłączyć się z serwerem i zapoznać się z innymi opcjami automatycznymi, jakie oferuje SQLmap.

Zauważ, że podobnie jak w przypadku omawianej w poprzednim odcinku Hydry, tak i SQLmap zostawia w logach systemowych ogromne ilości wpisów świadczących o tym, że ktoś przeprowadzał testy bezpieczeństwa w danym serwisie.

Podsumowanie

Znalezienie podatnych parametrów na stronie internetowej z użyciem SQLmap jest stosunkowo proste i przydatne. Automatyzacja odciążą testera, ale trzeba być świadomym jej braków. Pamiętaj jednak, że tylko ręczne testy bezpieczeństwa dadzą Ci pełną pewność co do tego, że Twoja aplikacja jest bezpieczna. Pamiętaj również, że testy automatyczne odgrywają znane scenariusze ataku, przed którymi programista mógł zabezpieczyć swoją aplikacje. Symulacje ataków wykonywane przez człowieka zawsze będą skuteczniejsze i dają możliwość lepszej interpretacji wyników.

Z SQLmapa (i innych powszechnie dostępnych automatów) warto korzystać jeszcze z jednego powodu. Inni też mają do nich dostęp i mogą je równie łatwo i szybko uruchomić, biorąc na cel naszą aplikację. Dlatego warto zrobić to przed nimi, aby być świadomym ewentualnych problemów, które w naszej webaplikacji odkryć może publicznie dostępne narzędzie.

Na koniec, jak zwykle przypominamy, że wykonywanie “niezamówionych testów bezpieczeństwamoże być karalne. Zdobywaj więc wiedzę odpowiedzialnie, jedynie na swoich maszynach!

PS. Jeśli chciałbyś poznać więcej technik testowania swojej webaplikacji pod kątem bezpieczeństwa i na żywo, w dedykowanym labie, uruchomić starannie wyselekcjonowane i sprawdzone narzędzia służące do atakowania (i obrony!) serwisów internetowych, to zapraszamy na nasze szkolenie z Bezpieczeństwa Webaplikacji — najbliższe edycje odbędą się we wrześniu w Warszawie, Krakowie, Wrocławiu i Gdańsku i zostały już pojedyncze wolne miejsca!. Aby przekonać się, jak wygląda to szkolenie, zapraszamy do zapoznania się z opiniami uczestników ostatniego terminu tego szkolenia. Pierwszym 3 osobom rejestrującym się z kodem “videoporadnik” przyznamy 100PLN rabatu. Do zobaczenia na szkoleniu!

Przeczytaj także:

12 komentarzy

Dodaj komentarz
  1. Interesujące jest to, że po wypełnieniu końcowego formularza dane zdają się nie być nigdzie przesyłane.

    • Komentarz chyba nie pod tym postem ;)

    • Przykład comment injection ;)

  2. Cześć,
    SQL injection jest dobrze opisane w większości książek dot. pentestów, ale praktycznie w żadnej nie znalazłem opisu odpowiednika tego ataku na bazy noSQL. Przykładowo – z tego co wiem – MongoDB umożliwia wstrzyknięcie javascriptu. Możecie napisać artykuł na ten temat?

    • +1, przydało by się :)

  3. Autorom chyba chodziło o “Blind SQL injection” a nie “Bind SQL injection”. Jedna literka a znaczenie całkowicie inne :)

    • Za duzo latania binda w ostatnich dniach… :)

  4. parametr –passwords nie sluzy do lamania hasel innych uzytkownikow tylko do lamania hasla dostepu do bazy danych (co wykorzystujecie pozniej) (nazywane jest to database management system users password hashes)

    zeby zdobyc hasla innych uzytkownikow aplikacji webowej do ktorej sie wlamujemy (dvwa) mozna podac przy okazji polecenia –dump. Tak samo zostanie wykorzystane lamanie slownikowe.

    troche to nie jasno jest opisane moim zdaniem
    to jednak dwie rozne rzeczy.

  5. Przy próbie złamania hasła pokazuje się hash, natomiast sqlmap nie łamie go ([WARNING] no clear password(s) found), mimo że w słowniku z którego pobiera hasła znajduje się słowo “hacker”. Jakieś pomysły dlaczego?

    • Mam to samo. Nie mogę się też zalogować do bazy SQL jako admin:hacker.

      Podejrzewam, że środowisko pobierane z https://nbzp.cz/docker-hacklab jest trochę inne niż stworzone w poprzednim odcinku (i nie chodzi tylko o nazwy kontenerów).

      Środowiska pokazanego na filmie nie udało mi się podnieść – docker-compose coś marudził na temat “wrong Compose file version” :-/

    • Środowisko pobierane z https://nbzp.cz/docker-hacklab ustawia hasło admina:

      dvwa:
      image: citizenstig/dvwa
      container_name: dvwa
      ports:
      – “80:80”
      environment:
      – MYSQL_PASS=hacker

      na innym konfigu nie zadziała…

  6. W sumie przydałoby się chociaż lakoniczne wytłumaczenie co się dzieje, bo ktoś niezorientowany i tak niewiele wyniesie z tych filmów.
    Co robi przycisk “submit”? Jakie zapytanie jest wykonywane do bazy danych?

    Ale ogólnie fajnie :)

Twój komentarz

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.

RSS dla komentarzy: