Python w służbie pentestera

24 lutego 2014, 21:28 | Teksty | komentarze 22
: zin o bezpieczeństwie - pobierz w pdf/epub/mobi.

Wstęp

Język Python to interpretowany język skryptowy obecny praktycznie we wszystkich liczących się dzisiaj systemach operacyjnych. Jego uniwersalność, dość prosta i przyswajalna składnia oraz mnogość istniejących rozszerzeń (w nomenklaturze Pythona zwanych modułami) sprawia, że jest bardzo chętnie wykorzystywany jako narzędzie do tworzenia zarówno prostych, konsolowych skryptów, jak i do aplikacji desktopowych czy serwisów internetowych.

Z tych powodów jest także jednym z częściej wybieranych przez specjalistów od bezpieczeństwa języków służących do pisania narzędzi przydatnych w tej dziedzinie.Oto kilka najbardziej znanych.

1. scapy

Na pewno każdy, kto zetknął się z tematyką szeroko rozumianego bezpieczeństwa informatycznego, słyszał bądź używał świetnego generatora pakietów scapy. Scapy napisany został w Pythonie, każdy, kto ma ochotę przeanalizować jego kod źródłowy, może to zrobić, zaglądając do oficjalnego repozytorium kodu na stronie, bądź pobrać go bezpośrednio na swój komputer (potrzebny będzie zainstalowany klient systemu kontroli wersji Mercurial).

2. sqlmap

Drugim powszechnie znanym narzędziem stworzonym przy pomocy Pythona jest sqlmap, czyli zautomatyzowany skaner podatności SQL Injection. Także w jego przypadku autorzy stawiają na otwartość kodu źródłowego, więc nie ma żadnych przeszkód, by repozytorium kodu sqlmapa pobrać i zapoznać się z nim lokalnie (wymagany klient systemu kontroli wersji Git).

3. w3af

Kolejnym przykładem jest framework do przeprowadzania testów penetracyjnych aplikacji webowych – w3af. Ten rozwijany przez Andresa Ranchio projekt to doskonały przykład na to, jak Python może posłużyć do zbudowania zaawansowanej aplikacji, której możliwości nie ograniczają się jedynie do wyświetlania prostych komunikatów na ekranie (w3af można używać zarówno jako aplikacji konsolowej, jak i desktopowej z graficznym GUI). Kod źródłowy dostępny jest w serwisie GitHub – andresriancho/w3af.

4. Golismero

Projektem podobnym do w3af, choć nieco mniej rozbudowanym, jest Golismero – bardzo przyjemne w użyciu zautomatyzowane narzędzie do wyszukiwania podatności w aplikacjach webowych. Golismero wyróżnia się funkcją generowania raportu w formacie HTML lub tekstowym (co może przydać się np. przy przygotowywaniu raportu z testu penetracyjnego) oraz łatwością rozbudowy o nowe pluginy. Kod źródłowy Golismero można pobrać z repozytorium w serwisie GitHub – golismero/golismero.

To tylko kilka przykładów z bardzo bogatej gamy programów napisanych w Pythonie. Ale to nie koniec: jest to też jeden z najczęściej wykorzystywanych języków do tworzenia exploitów czy wszelkiej maści rozszerzeń do innych popularnych narzędzi – np. dla Burp Suite.

Poznaliśmy kilka projektów stworzonych w Pythonie, czas przyjrzeć się nieco dokładniej samemu językowi i paru jego funkcjom.

 

Dlaczego warto poznać Pythona

Niewątpliwie jedną z bardziej pożądanych umiejętności każdego specjalisty bezpieczeństwa IT jest zdolność programowania (choćby podstawowa) i znajomość co najmniej jednego języka programowania.

Do efektywnej pracy (przykładowo w charakterze specjalisty od bezpieczeństwa aplikacji webowych) przydaje się znajomość HTML, JavaScript oraz technologii serwerowych, takich jak PHP, Java/JavaEE, Perl, ASP.NET. Specjalista zajmujący się analizą złośliwego oprogramowania (wirusów, rootkitów, malware instalującego się w systemie operacyjnym) powinien mieć opanowane w stopniu co najmniej dobrym takie języki jak C, C++ czy Assembler. Każdy, w zależności od swoich upodobań oraz przyjętej ścieżki rozwoju zawodowego i w ramach specjalizacji, powinien we własnym zakresie poświęcić nieco czasu na poznanie i naukę wybranego bądź wybranych języków.

Wydaje się jednak niezbędnym minimum, by każdy, niezależnie od konkretnego zadania, któremu poświęca swój czas, był w stanie pomóc sobie przez zautomatyzowanie pewnych czynności w postaci choćby prostego skryptu powłoki czy konsolowej aplikacji napisanej w interpretowanym języku (Perl bądź Python).

Ma to dwojaką korzyść – nauka języka oraz jego stosowanie w praktyce bardzo rozwijają warsztat oraz umiejętności praktyczne, co jest cechą szczególnie pożądaną w branży Security. Drugą korzyścią jest budowanie własnego, unikalnego zestawu narzędzi, które bardzo często, jako wyspecjalizowane w konkretnym zadaniu (niemal jak skalpel chirurgiczny), sprawdzą się dużo lepiej niż dostępne powszechnie gotowe rozwiązania-kombajny.

Wybrałem Pythona między innymi z powodów, które podałem na wstępie – jego względnie dużą popularność w porównaniu choćby do Perla, dostępność na różnych platformach oraz całkiem prostą do przyswojenia składnię – choć tu początkowo wpadłem w pewną pułapkę, wynikającą z doświadczenia z innymi językami – bloki kodu w Pythonie są wyznaczane przez głębokość wcięć, a nie nawiasy klamrowe, jak ma to miejsce w C, Javie, PHP czy JavaScript.

Na początek mała uwaga – niniejszy artykuł nie jest tutorialem, który ma nauczyć kogokolwiek programowania w Pythonie od podstaw – jest cała masa materiałów, samouczków i tutoriali, łącznie z oficjalną dokumentacją języka na stronie Python.org. Artykuł zawiera zbiór kilku prostych narzędzi konsolowych napisanych przy użyciu języka Python, wykonujących ściśle określone zadania, które mogą być inspiracją do samodzielnej nauki i wykorzystania Pythona we własnym zakresie i w swoich projektach.
Wszystkie przykłady zostały napisane w Pythonie w wersji 2.7.6 oraz przetestowane i uruchomione na komputerze działającym pod kontrolą systemu OS X 10.9. Nie powinno być najmniejszych problemów z ich uruchomieniem w dowolnej dystrybucji systemów Linux i FreeBSD.

 

Trochę podstaw

Programy w Pythonie bardzo rzadko pisane są z wykorzystaniem jedynie podstawowych konstrukcji języka. Do budowy bardziej skomplikowanych skryptów wykorzystuje się moduły, czyli gotowe do użycia biblioteki wyspecjalizowane w określonych zadaniach.

W przykładach zostały użyte moduły:

  • httplib – będący implementacją protokołu HTTP po stronie klienta,
  • sys – zawierający mnóstwo wbudowanych funkcji i pozwalający m.in. na odczyt argumentów linii poleceń,
  • os – będący interfejsem umożliwiającym wykonywanie poleceń powłoki systemowej.

Poza modułami dostępnymi wraz z językiem, Python umożliwia programiście pisanie własnych i ich wykorzystywanie w innych programach.

 

Skrypt pierwszy – Banner Grabber

Na początek coś bardzo prostego – Banner Grabber, czyli narzędzie do odpytywania serwera WWW o jego sygnaturę. Nazwa skryptu pochodzi od techniki znanej jako „banner grabbibng”.

Kod źródłowy skryptu zawiera kilka elementów, które poniżej omawiam dokładniej:

W linijce oznaczonej [1] znajduje się informacja, że skrypt jest napisany w języku Python i do jego uruchomienia system powinien użyć interpretera tego języka (a konkretnie – uruchomić program python z katalogu /usr/bin).

Kolejne dwie instrukcje [2] służą do zaimportowania do naszego skryptu modułów httplib oraz sys – będziemy korzystać z ich funkcjonalności w dalszej części skryptu.

Konstrukcja if __name__ == '__main__': w linii [3] jest pewnym programistycznym trickiem charakterystycznym dla Pythona, dokładniejszy opis tej techniki można znaleźć np. pod tym adresem Użycie __name__ w Pythonie).

W kolejnych linijkach [4] odczytujemy argumenty wiersza poleceń. sys.argv to tablica, której pierwszy element (o zerowym indeksie – w Pythonie, podobnie jak w innych językach, indeksy elementów tablic liczymy od 0) – to nazwa skryptu. Dlatego argumenty, którymi w tym przypadku będą: host, port oraz adres url, odczytujemy jako elementy tablicy argv o indeksach od 1 do 3. Przykładowe wywołanie (odpytanie serwera WWW serwisu sekurak.pl, na porcie 80 i w głównym drzewie katalogów /) będzie wyglądało następująco:

[5] to wywołanie funkcji, zdefiniowanej w [6]. Jak widzimy, funkcja przyjmuje jako argumenty to, co wcześniej odczytaliśmy z linii poleceń. Następnie [7] tworzone jest połączenie do określonego hosta na podanym porcie, a następnie wywoływany jest adres url [8]. Stosujemy tu metodę HEAD, gdyż nie zależy nam na treści strony, a jedynie na samym nagłówku odpowiedzi HTTP. Ze zwróconego nagłówka [9] odczytujemy liczbowy status odpowiedzi HTTP (tak dla pewności) [10] oraz interesującą nas informację, czyli nagłówek Server.

W odpowiedzi powinniśmy otrzymać komunikat:

 

Skrypt drugi – Reverse DNS Scanner

Bardzo często w trakcie przeprowadzania rekonesansu zachodzi konieczność ustalenia, jakie nazwy domenowe odpowiadają konkretnym adresom IP w badanej sieci. Jak wiemy, służy do tego m.in. konsolowa komenda host (aby więcej dowiedzieć się o opcjach udostępnianych przez tę komendę, wpisz w swojej konsoli polecenie man host).

Jeśli zachodzi konieczność sprawdzenia kilku adresów IP, wydanie za każdym razem polecenia host wraz z adresem IP nie wydaje się jeszcze jakoś specjalnie uciążliwe. Problem pojawia się w przypadku większej liczby adresów IP, np. całej podsieci składającej się z 255 adresów.

W takim wypadku można skorzystać z drugiego skryptu, a mianowicie prostego DNS Reverse Scannera. Jedynym jego zadaniem jest przeiterowanie przez cały zakres podanych mu adresów IP i wykonanie polecenia host na każdym z nich.

Poza konstrukcją [1], która rozbija dwa podane adresy IP, budując z ostatnich części adresów przedział, w jakim ma wykonać się pętla poniżej, warta zwrócenia uwagi jest linijka [2]. Polecenie system z modułu os pozwala nam na wykonanie dowolnego polecenia powłoki tak, jakbyśmy wpisali je bezpośrednio w konsoli (wynik otrzymujemy również w konsoli).

Jak można się spodziewać, skrypt zwraca listę informacji o odnalezionych nazwach domenowych z serwerów DNS, odpowiadających badanym adresom IP:

Dla porównania – podobne narzędzie napisałem kiedyś w języku Perl. Jego źródło można znaleźć pod tym adresem. Skrypt w Pythonie jest nieco bardziej przejrzysty i łatwiejszy w interpretacji.

 

Skrypt trzeci – Admin Panel Scanner

W trakcie testów penetracyjnych aplikacji webowych jedną z pierwszych czynności jest próba odnalezienia bądź odgadnięcia lokalizacji części administracyjnej (np. w celu zbadania podatności na błędy uwierzytelniania). Ponieważ programiści to ludzie z natury leniwi, w większości przypadków lokalizacja takiego panelu administracyjnego to katalog lub plik o nazwie wywodzącej się od słów ‚admin’ lub ‚login’.

Ponieważ konkretna lokalizacja może zależeć od technologii, w jakiej powstał serwis, bądź od struktury katalogów wymuszonej np. przez użycie określonego frameworka czy systemu, do szybkiej lokalizacji sekcji administracyjnej może przydać się kolejny z prezentowanych skryptów:

Podobnie jak w pierwszym skrypcie skorzystamy z modułów sys oraz httplib. Dodatkowo w naszym programie użyjemy modułu naszego autorstwa. Moduł ten będzie składał się tylko z definicji tablicy zawierającej listę ścieżek do kilkuset najpopularniejszych lokalizacji paneli administracyjnych. Moduł można pobrać spod tego adresu, a używamy go w postaci prostego przypisania do zmiennej w naszym skrypcie [2].

Po wywołaniu funkcji scan() wraz z interesującymi nas parametrami, czyli odczytanymi z linii poleceń nazwami hosta i ścieżki do aplikacji www na serwerze, pierwszą instrukcją jest otwarcie pliku logu [3], w którym skrypt zapisze wszystkie odnalezione ścieżki. Jak widać, otwarcie pliku w Pythonie graniczna się do podania jego nazwy oraz trybu (zapis, odczyt, dodawanie) – więcej na ten temat znajduje się w dokumentacji. W [4] następuje złożenie konkretnego adresu url, składającego się z podanej jako argument ścieżki do aplikacji i doklejonej do niej lokalizacji odczytanej z tablicy adminpanels.

Wszystko odbywa się w pętli, za każdym razem po wywołaniu adresu sprawdzany jest status HTTP odpowiedzi [5]. Jeśli zawiera on wartość wskazującą, że pod danym adresem znajduje się dostępny zasób (200, 301, 302, 304, 401 lub 403), skrypt wyświetla nam odpowiednią informację na wyjściu [6], jednocześnie zapisując ją w pliku logu [7].

Po zakończeniu pracy plik z logiem jest zamykany, by zwolnić zasoby systemowe [8], a program kończy działanie. Wywołując Admin Panel Scanner przykładowo dla serwisu opartego na WordPress, otrzymamy:

 

Skrypt czwarty – XSS UTF-16 Payload Encoder

Na zakończenie skrypt, którego jedynym zadaniem jest translacja podanego ciągu do sekwencji znaków zakodowanych w postaci wartości UTF-16. UTF-16 to jeden z akceptowanych przez przeglądarki internetowe formatów zapisu kodu JavaScript. Kodowanie w formacie UTF-16 jest często wykorzystywane w przypadku tworzenia payloadów do testowania podatności na błędy XSS (innymi formatami jest np. URL Encoding, który zamienia znaki specjalne, jak < czy ” na %3c i %22).

W porównaniu z poprzednimi skryptami ten wzbogaciliśmy o niewielką pomoc w przypadku, gdy użytkownik poda nieprawidłową liczbę argumentów [2]. Omówienie należy się też linijce [1] – iterując po kolejnych znakach ciągu wejściowego, zamieniamy każdy znak na (kolejno):

  • jego odpowiednik dziesiętny w kodzie ASCII – realizuje to zadanie funkcja ord(),
  • wartość otrzymaną jako rezultat f-cji ord() zamieniamy na odpowiadającą jej liczbę szesnastkową przy pomocy hex(),
  • ponieważ poprzednia operacja dodaje nam ciąg ‚0x’ przed szesnastkową reprezentacją znaku, a my potrzebujemy postaci UTF-16, czyli cztery cyfry poprzedzone znakiem ‚\u’ wykonujemy kolejną zamianę, ostatecznie otrzymując odpowiednio zakodowany znak.

Po zakończeniu przeliczania wszystkich znaków ciągu zwracamy na wyjściu gotowy zakodowany payload:

 

Zakończenie

Przedstawione skrypty są bardzo proste, nie zawierają praktycznie żadnej obsługi błędów, a ich funkcjonalność pozostawia wiele do życzenia. Niemniej jednak mają jedną niezaprzeczalną zaletę: wykonują zadania, do których zostały napisane i robią to szybko niezależnie od środowiska, a ich uruchomienie sprowadza się do wpisania odpowiedniego polecenia w konsoli. Napisanie podobnego narzędzia, po nabraniu wprawy i doświadczenia w posługiwaniu się Pythonem, często może okazać się szybsze, niż wyszukanie, pobranie z sieci, instalacja i uruchomienie spełniającego konkretne zadanie „dużego” programu.

Niewątpliwie satysfakcjonująca będzie również świadomość, że korzystamy z własnoręcznie napisanego programu. Kto wie, być może z prostego skryptu, który powstanie z konieczności przeprowadzenia określonego zadania, z czasem powstanie rozbudowane i uznane w świecie specjalistów od zabezpieczeń narzędzie?

 

Źródła

Jak napisałem we wstępie, w Internecie istnieje bardzo dużo materiałów do samodzielnej nauki języka Python na każdym poziomie zaawansowania. Sam rozpocząłem swoją przygodę z tym językiem (do czego również zachęcam, ale może ktoś poda lepsze źródła w komentarzu do tego tekstu) od oficjalnego tutoriala dostępnego na stronie projektu pod adresem The Python Tutorial.

Oczywiście, jak w przypadku każdego języka, podstawą w trakcie nauki jest dokumentacja – na stronie Python v2.7.6 documentation znajdziemy podzieloną na działy, aktualizowaną i bardzo, bardzo bogatą dokumentację Pythona 2.7.6

Inne źródła:

  • Python tools for penetration testers – spis narzędzi związanych z bezpieczeństwem, napisanych w Pythonie.
  • Writing Basic Security Tools using Python – prezentacja Ali Al-Shemery (w formacie pdf) na opisywany temat i inspiracja do napisania powyższego tekstu. Stanowi doskonałe, szybkie wprowadzenie w tematykę programowania sieciowego w Pythonie, modułów httplib, urllib i ich wykorzystania. Zawiera też kilka praktycznych przykładów.

Rafał ‚bl4de’ Janicki– bloorq[at]gmail.com

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. pl

    Świetne!

    Odpowiedz
  2. Michał B
    Odpowiedz
  3. dex
    Odpowiedz
    • bl4de

      @dex
      Dzięki za linka. To opracowanie na Wikibooks bazuje właśnie na oficjalnym tutorialu ze strony python.org.

      Dla kogoś, kto woli materiały w naszym rodzimym języku jest to doskonały zamiennik :)

      Odpowiedz
  4. Maciej

    Polecam książkę „Violent Python: A Cookbook for Hackers, Forensic Analysts, Penetration Testers and Security Engineers”, autorem jest TJ O’Connor.

    Odpowiedz
    • bl4de

      Dzięki za informację :)

      Faktycznie świetna pozycja, żałuję, że nie trafiłem na nią w trakcie pracy nad artykułem.

      Odpowiedz
  5. Lukasz

    Swietny artykul, dzieki!

    Odpowiedz
    • bl4de

      Dzięki :)

      W „drodze” jest już druga część ;)

      Odpowiedz
  6. józek

    Ruby ;)

    Odpowiedz
    • Bash ;) Swoją drogą widziałem kiedyś w dość starej książce o programowaniu w bashu, pełen kod sklepu interenetowego (CGI) :-)

      Odpowiedz
      • józek

        Koleś który programuje w bashu powinien dostać Nobla, Guinessa i Oscara za samo zaparcie, motywacje oraz twórczość abstrakcyjną.

        Odpowiedz
  7. Peter

    Masowy skaner LFI – nie skończony, trochę błędów, ale może się komuś będzie chciało go pociągnąć dalej ;P

    http://pastebin.com/L5G405tG

    + w tym samym katalogu wrzucamy libkę google (http://pastebin.com/CdYQjS5V)

    odpalamy, wpisujemy lfiscan, następnie 0, a później ile stron ma pobrać – np 100.
    ———————-
    Automat do generowania CSRF PoC’y – jak ktoś nie ma licencji na burpa ;)

    http://pastebin.com/Ff0cCWKx

    Odpowiedz
  8. PPCG

    Korzystając z okazji, wszystkich zainteresowanych Pythonem zachęcamy do odwiedzania serwisu polskiej społeczności Pythona, na którym to można znaleźć kursy, artykuły i aktualności dotyczące tego języka.

    http://pl.python.org/

    Dostępne jest także forum społeczności:

    http://pl.python.org/forum/

    … oraz kanał IRC (w sieci FreeNode):

    #python.pl

    Zapraszamy wszystkich czytelników Sekurat.pl!

    Odpowiedz
  9. radq

    Bardzo fajny artykuł, zwłaszcza, że przymierzam się do nauki języka. Mógłbyś napisać coś o wersji 2.7.6 vs 3.3? Dlaczego polecasz starszą?

    Odpowiedz
    • bl4de

      @radq

      Wybór wersji 2.7.6 był podyktowany czystym przypadkiem – zacząłem uczyć się tego języka właśnie z tutoriala poświęconego tej wersji i tak zostało :)

      Na pewno dobrym pomysłem jest zapoznanie się z wersją 3, jednakże pomiędzy obiema wersjami występują pewne różnice, które sprawiają, że kod napisany w Pythonie 3 może nie zadziałać w interpreterze Pythona 2.

      Dokładne różnice oraz ewentualne problemy z niezgodnością wersji zostały opisane w opracowaniu „Should I use Python 2 or Python 3 for my development activity?” na Wiki Pythona i myślę, że tam znajdziesz odpowiedź na swoje pytanie:

      https://wiki.python.org/moin/Python2orPython3

      Odpowiedz
    • Wersja 2.x istnieje dłużej więc dla niej jest więcej bibliotek, opisów, tutoriali. Ale 3.x nie zostaje w tyle więc warto znać obie wersje.

      W razie pytań zapraszam na wspomniane forum pythona

      http://pl.python.org/forum/

      Odpowiedz
    • Peter

      Bo wersji 3.x używają tylko autorzy tego języka ;)

      Odpowiedz
  10. Rubyist

    A taki Metasploit czy jigsaw są w Rubim. ;)

    Odpowiedz
  11. takie rzeczy akurat jeszcze łatwiej w bashu, w jednej linijce bez wielokilobajtowych bibliotek :-)
    metasploita słyszałem przepisują na pythona właśnie, bo jak już zostało powiedziane, jest wszędzie

    Odpowiedz

Odpowiedz