-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b18ed97
commit aff0cdd
Showing
2 changed files
with
108 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,31 @@ | ||
# probemon | ||
A simple command line tool for monitoring and logging 802.11 probe frames | ||
|
||
I decided to build this simple python script using scapy so that I could record 802.11 probe frames over a long period of time. This was specifically useful in my use case: proving that a person or device was present at a given location at a given time. | ||
|
||
## Usage | ||
|
||
``` | ||
usage: probemon.py [-h] [-i INTERFACE] [-t TIME] [-o OUTPUT] [-b MAX_BYTES] | ||
[-c MAX_BACKUPS] [-d DELIMITER] [-f] [-s] | ||
a command line tool for logging 802.11 probe request frames | ||
optional arguments: | ||
-h, --help show this help message and exit | ||
-i INTERFACE, --interface INTERFACE | ||
capture interface | ||
-t TIME, --time TIME output time format (unix, iso) | ||
-o OUTPUT, --output OUTPUT | ||
logging output location | ||
-b MAX_BYTES, --max-bytes MAX_BYTES | ||
maximum log size in bytes before rotating | ||
-c MAX_BACKUPS, --max-backups MAX_BACKUPS | ||
maximum number of log files to keep | ||
-d DELIMITER, --delimiter DELIMITER | ||
output field delimiter | ||
-f, --mac-info include MAC address manufacturer | ||
-s, --ssid include probe SSID in output | ||
``` | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#!/usr/bin/python | ||
|
||
import time | ||
import datetime | ||
import argparse | ||
import netaddr | ||
import sys | ||
import logging | ||
from scapy.all import * | ||
from logging.handlers import RotatingFileHandler | ||
|
||
|
||
NAME = 'probemon' | ||
DESCRIPTION = "a command line tool for logging 802.11 probe request frames" | ||
|
||
|
||
|
||
def build_packet_callback(time_fmt, logger, delimiter, mac_info, ssid): | ||
def packet_callback(packet): | ||
if not packet.haslayer(Dot11): | ||
return | ||
|
||
if packet.type != 0 or packet.subtype != 0x04: | ||
return | ||
|
||
# list of output fields | ||
fields = [] | ||
|
||
# determine preferred time format | ||
log_time = str(int(time.time())) | ||
if time_fmt == 'iso': | ||
log_time = datetime.datetime.now().isoformat() | ||
|
||
fields.append(log_time) | ||
|
||
# append the mac address itself | ||
fields.append(packet.addr2) | ||
|
||
# parse mac address and look up the organization from the vendor byte | ||
if mac_info: | ||
parsed_mac = netaddr.EUI(packet.addr2) | ||
fields.append(parsed_mac.oui.registration().org) | ||
|
||
# include the SSID in the probe frame | ||
if ssid: | ||
fields.append(packet.info) | ||
|
||
logger.info(delimiter.join(fields)) | ||
|
||
return packet_callback | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description=DESCRIPTION) | ||
parser.add_argument('-i', '--interface', help="capture interface") | ||
parser.add_argument('-t', '--time', default='iso', help="output time format (unix, iso)") | ||
parser.add_argument('-o', '--output', default='probemon.log', help="logging output location") | ||
parser.add_argument('-b', '--max-bytes', default=5000000, help="maximum log size in bytes before rotating") | ||
parser.add_argument('-c', '--max-backups', default=99999, help="maximum number of log files to keep") | ||
parser.add_argument('-d', '--delimiter', default='\t', help="output field delimiter") | ||
parser.add_argument('-f', '--mac-info', action='store_true', help="include MAC address manufacturer") | ||
parser.add_argument('-s', '--ssid', action='store_true', help="include probe SSID in output") | ||
args = parser.parse_args() | ||
|
||
if not args.interface: | ||
print "error: capture interface not given, try --help" | ||
sys.exit(-1) | ||
|
||
# setup our rotating logger | ||
logger = logging.getLogger(NAME) | ||
logger.setLevel(logging.INFO) | ||
handler = RotatingFileHandler(args.output, maxBytes=args.max_bytes, backupCount=args.max_backups) | ||
logger.addHandler(handler) | ||
|
||
built_packet_cb = build_packet_callback(args.time, logger, args.delimiter, args.mac_info, args.ssid) | ||
sniff(iface=args.interface, prn=built_packet_cb) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |