Skip to content

Instantly share code, notes, and snippets.

@silviot
Created October 11, 2019 12:32
Show Gist options
  • Save silviot/e5360836fdf88f451630384759fa8d91 to your computer and use it in GitHub Desktop.
Save silviot/e5360836fdf88f451630384759fa8d91 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""Monitor signal strength of wifi deauthentication packets
"""
from ascii_graph import Pyasciigraph
from ascii_graph.colordata import hcolor
from ascii_graph.colordata import vcolor
from ascii_graph.colors import Blu, Red, Yel, Gre
from scapy.all import Dot11, sniff
from datetime import datetime
from itertools import groupby
import os
import sys
RETAIN_PERIOD = 100 # In REFRESH_INTERVALs
REFRESH_INTERVAL = 0.1 # In seconds
THRESHOLDS = {-80: Red, -70: Blu, -60: Yel, 0: Gre}
# Packet subtype constants
ASSOREQ = 0
ASSORESPO = 1
REASSOREQ = 2
REASSORESP = 3
PROBEREQ = 4
PROBERESP = 5
BEACON = 8
ATIM = 9
DISAS = 10
AUTH = 11
DEAUTH = 12 # The one we're actually interested in
ACK = 13
def PacketHandler(packet):
if packet.haslayer(Dot11):
if packet.type == 0 and packet.subtype == DEAUTH:
handle_packet(packet)
# if packet.type == 0 and packet.subtype == BEACON and packet.info == b'Shielded':
# handle_packet(packet)
SSIDS = []
ATTACKS_PERIODS = {}
LAST_DISPLAYED = dict(tstamp=0) # last timestamp disaplayed on screen
def handle_packet(packet):
dest = packet.addr2
ATTACKS_PERIODS.setdefault(LAST_DISPLAYED["tstamp"], []).append(packet)
this_display = (datetime.now().timestamp() // REFRESH_INTERVAL) * REFRESH_INTERVAL
if this_display != LAST_DISPLAYED["tstamp"]:
LAST_DISPLAYED["tstamp"] = this_display
print_attacks()
cleanup_attacks()
def print_attacks():
print("\033c", end="")
to_print = []
interfaces = []
to_print.append(f"{LAST_DISPLAYED['tstamp']} {' - '.join(interfaces)}")
to_print.append(
f"Attacks in the past {int(RETAIN_PERIOD * REFRESH_INTERVAL)} seconds: {sum(map(len, ATTACKS_PERIODS.values()))}"
)
graph = []
for _, packets in sorted(ATTACKS_PERIODS.items(), reverse=True):
for channel, powers in groupby(
sorted([(el.ChannelFrequency, el.dBm_AntSignal) for el in packets]),
key=lambda x: x[0],
):
graph.append((channel, average(el[1] for el in powers)))
rows, columns = os.popen("stty size", "r").read().split()
graph_height = int(rows) - 5
data = hcolor(graph[:graph_height], THRESHOLDS)
#data = graph[:graph_height]
for line in Pyasciigraph(
min_graph_length=10,
multivalue=False,
line_length=int(columns) - 20,
).graph("Signal strengths", data):
to_print.append(line)
print("\n".join(to_print))
def average(values):
if not isinstance(values, (list, tuple)):
values = list(values)
return sum(values) / len(values)
def cleanup_attacks():
threshold = datetime.now().timestamp() - (RETAIN_PERIOD * REFRESH_INTERVAL)
for tstamp in list(ATTACKS_PERIODS):
if tstamp < threshold:
del ATTACKS_PERIODS[tstamp]
def main():
if len(sys.argv) < 2:
print(f"Provide an interface name, like this:\n{sys.argv[0]} wlan0")
sys.exit(1)
sniff(iface=sys.argv[1], prn=PacketHandler)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment