Last active
July 8, 2020 14:33
-
-
Save LoranKloeze/0b21b2a563340091b5b3b9069ea51168 to your computer and use it in GitHub Desktop.
Special for OSX: this script grabs 802.11 probe requests from the air and puts them on your screen or in a sqlite3-db
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2.7 | |
# 802.11 probe requests processor | |
# Copyright (C) 2017 Ralon cybersecurity | |
# Loran Kloeze - loran@ralon.nl - @lorankloeze | |
# MIT license: do with it what you want but use it for good | |
# | |
# Tested on OS X El Capitan 10.11.6 - MacBook Air | |
# | |
# This script grabs probe requests from the air and outputs them on the screen | |
# and/or saves them to a sqlite3-db. | |
# On the screen it will simply prints a request as it comes in. If the database | |
# already contains a ssid/mac combination, it is overwritten. | |
# | |
# Reconnect your wifi if your network connection | |
# is lost after after using this script | |
# | |
# Prerequisites | |
# - make sure 'tcpdump' is installed and in working order | |
# - if tcpdump crashes, run this script again using sudo and doublecheck | |
# your interface | |
# | |
# | |
# It should output something like this when screen output is enabled | |
# | |
# Time SSID Mac-address Signal | |
# 11:23:44 GuestWIFI 23:dd:89:12:3d:ff -89 | |
# 11:24:01 GuestWIFI 23:dd:89:12:3d:ff -87 | |
# 11:23:44 ThomsonFF56D1 67:d1:99:5a:bc:73 -76 | |
# . . . . | |
# . . . . | |
# . . . . | |
import subprocess | |
import re | |
import sqlite3 | |
import time | |
import datetime | |
import os | |
### Settings | |
# The interface that is to be inspected. Make sure monitor mode is enabled for | |
# this interface. | |
monitor_dev = "en0" | |
# Enable output to stdout | |
output_to_stdout = True | |
# Enable save output to sqlite3-database | |
save_to_db = False | |
# Path of the sqlite3-database. | |
db_path = "/tmp/probes.db" | |
# Tcpdump may stop/crash if monitor_dev goes offline. Restart tcpdump in | |
# restart_delay_sec seconds after it stops/crashes. | |
restart_delay_sec = 5 | |
### Program | |
mainConn = 0 | |
mainCursor = 0 | |
def prettyPrint(ant, mac, ssid): | |
pad_spaces = 32 - len(ssid) # 32 is the max length of a 802.11 SSID | |
while pad_spaces > 0: | |
ssid += ' ' | |
pad_spaces -= 1 | |
niceTime = datetime.datetime.today().strftime('%H:%M:%S') | |
print niceTime, ssid, mac, ant | |
def startProbing(): | |
FNULL = open(os.devnull, 'w') | |
proc = subprocess.Popen(['tcpdump','-l', '-I', '-i', monitor_dev, '-e', '-s', '256', 'type', 'mgt', 'subtype', 'probe-req'], | |
stdout=subprocess.PIPE, stderr=FNULL) | |
patt = "(-\\d+)dB signal .+SA:([0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+:[0-9a-f]+) .+Probe Request \\((.+)\\)" | |
while True: | |
line = proc.stdout.readline() | |
line = line.rstrip() | |
if line != '': | |
m = re.search(patt, line) | |
if m is not None and len(m.groups()) == 3: | |
ant = m.group(1).rstrip() | |
mac = m.group(2).rstrip() | |
ssid = m.group(3).rstrip() | |
timestamp = int(time.time()) | |
if output_to_stdout: | |
prettyPrint(ant, mac, ssid) | |
if save_to_db: | |
mainCursor.execute("INSERT OR REPLACE INTO probes VALUES (?,?,?,?)", (ssid, mac, ant, timestamp)) | |
mainConn.commit() | |
else: | |
break | |
def printIntro(): | |
print '+------------------------------------------------------------+' | |
print '+ Scanner for enumerating probe requests from base stations +' | |
print '+ +' | |
print '+ (c) 2017 Ralon cybersecurity +' | |
print '+ Loran Kloeze - loran@ralon.nl - @lorankloeze +' | |
print '+ License: MIT +' | |
print '+ +' | |
print '+------------------------------------------------------------+' | |
print 'Using monitor device', monitor_dev | |
if save_to_db: | |
print 'Saving requests to database at', db_path | |
if output_to_stdout: | |
print 'Pretty printing request is enabled' | |
print 'It may take a while before the first requests appear' | |
print 'Start scanning...' | |
if output_to_stdout: | |
print 'Time SSID Mac-address Signal' | |
def main(): | |
if save_to_db: | |
global mainConn | |
global mainCursor | |
mainConn = sqlite3.connect(db_path) | |
mainCursor = mainConn.cursor() | |
mainCursor.execute('''CREATE TABLE IF NOT EXISTS probes | |
(ssid text, mac text, ant numeric, last_seen numeric)''') | |
mainCursor.execute('''CREATE UNIQUE INDEX IF NOT EXISTS ssid_index ON probes | |
(ssid)''') | |
mainCursor.execute('''CREATE INDEX IF NOT EXISTS last_seen_index ON probes | |
(last_seen)''') | |
mainConn.commit() | |
while True: | |
printIntro() | |
startProbing() | |
print "Tcpdump crashed/stopped, waiting for", restart_delay_sec, "seconds to restart" | |
time.sleep(restart_delay_sec) | |
if save_to_db: | |
mainConn.close() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment