-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassociation-randomizer_web.py
144 lines (133 loc) · 7.61 KB
/
association-randomizer_web.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#! /usr/bin/env python
######
# v1.0
# Randomize Transmit, Source, BSSID and SSID data for Assoc. Req. frames
# Source file needs to be in pcap format, or wcap (native OSX sniffer).
# If it's not, you can convert with:
# tshark -r <input_file> -w <output_file> -F pcap
#######
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
from random import randint
import sys, os, os.path, binascii, signal, subprocess, tempfile, cgi, cgitb
#enable debugging with
#cgitb.enable()
form = cgi.FieldStorage()
fileitem = form['filename']
# function to apply to each frame
converted = []
pkt_num = 0
def associations(frame):
global pkt_num
global temp_pkts_name
new_temp_name = (fn + '_' + str(pkt_num))
if frame.type == 0 and frame.subtype == 0:
print "<p>Association Request found...</p>"
print "<h4>Original info:</h4>Client: %s<br>AP: %s<br> BSSID: %s<br> SSID: %s<br>" % (frame.addr2, frame.addr1, frame.addr3, frame.info)
frame.addr1 = '11:11:11:11:11:11'
frame.addr2 = '22:22:22:22:22:22'
frame.addr3 = '11:11:11:11:11:11'
ssid_taglen = len(frame.info)
frame.info = ''.join(["%s" % randint(0, 9) for num in range(0, ssid_taglen)])
print "<h4>New info:</h4>Client: %s<br>AP: %s<br>BSSID: %s<br> SSID: %s" % (frame.addr2, frame.addr1, frame.addr3, frame.info)
print "<br>This will be packet <b>%i</b> in the new pcap file" % (pkt_num + 1)
# Determine spatial stream support
frame_read = frame[Dot11Elt]
while isinstance(frame_read, Dot11Elt):
if frame_read.ID == 45 and "\xff\xff\xff" in frame_read.info:
print "<br>This is a <b>three stream</b> device"
elif frame_read.ID == 45 and "\xff\xff" in frame_read.info:
print "<br>This is a <b>two stream</b> device"
elif frame_read.ID == 45 and "\xff" in frame_read.info:
print "<br>This is a <b>single stream</b> device"
# Determine channels supported
if frame_read.ID == 36 and "$\x044\x04d\x0b\x95\x05" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64, 100-140 and 149-165</b>"
elif frame_read.ID == 36 and "$\x044\x04d\x0c\x95\x05\x01\x0b" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64, 100-140 and 149-165</b>"
elif frame_read.ID == 36 and "$\x044\x04d\x0b" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64 and 100-140</b>"
elif frame_read.ID == 36 and "x044\x04d\x0b\x95\x04\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64, 100-140 and 149-165</b>"
elif frame_read.ID == 36 and "\x01\x01\x02\x01\x03\x01\x04\x01\x05\x01\x06\x01\x07\x01\x08\x01\t\x01\n\x01\x0b\x01\x0c\x01\r\x01\x0e\x01$\x01(\x01,\x010\x014\x018\x01<\x01@\x01d\x01h\x01l\x01p\x01t\x01x\x01|\x01\x80\x01\x84\x01\x88\x01\x8c\x01\x95\x01\x99\x01\x9d\x01\xa1\x01\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>1-14, 36-48, 52-64, 100-140 and 149-165</b>"
elif frame_read.ID == 36 and "$\x044\x04d\x0c\x95\x04\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64, 100-144 and 149-165</b>"
elif frame_read.ID == 36 and "\x01\x01\x02\x01\x03\x01\x04\x01\x05\x01\x06\x01\x07\x01\x08\x01\t\x01\n\x01\x0b\x01$\x01(\x01,\x010\x014\x018\x01<\x01@\x01d\x01h\x01l\x01p\x01t\x01\x84\x01\x88\x01\x8c\x01\x95\x01\x99\x01\x9d\x01\xa1\x01\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>1-11, 36-48, 52-64, 100-140 and 149-165</b>"
elif frame_read.ID == 36 and "$\x04\x95\x04\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>36-48 and 149-165 (No DFS support)</b>"
elif frame_read.ID == 36 and "\x01\x01\x02\x01\x03\x01\x04\x01\x05\x01\x06\x01\x07\x01\x08\x01\t\x01\n\x01\x0b\x01$\x01(\x01,\x010\x01\x95\x01\x99\x01\x9d\x01\xa1\x01\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>1-11, 36-48 and 149-165 (No DFS support)</b>"
elif frame_read.ID == 36 and "$\x01(\x01,\x010\x014\x018\x01<\x01@\x01d\x01h\x01l\x01p\x01t\x01x\x01|\x01\x80\x01\x84\x01\x88\x01\x8c\x01\x95\x01\x99\x01\x9d\x01\xa1\x01\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64, 100-140 and 149-165</b>"
elif frame_read.ID == 36 and "$\x044\x04d\x08\x95\x04\xa5\x01" in frame_read.info:
print "<br>This client supports channels: <b>36-48, 52-64, 100-128 and 149-165</b>"
frame_read = frame_read.payload
# write the new randomized frame to file, with increment
temp_pkts = tempfile.NamedTemporaryFile(delete=False)
temp_pkts_name = temp_pkts.name
orig_name = os.path.basename(fileitem.filename.replace("\\", "/" ))
wrpcap('./caps/' + str(orig_name) + '_random_' + str(pkt_num) + '.pcap', frame)
print "<br>Wrote pkt, moving on..."
pkt_num = int(pkt_num) + 1
temp_pkts.close()
# Check FCS on 802.11 frame, return True is FCS is good or False otherwise
# Note: if FCS invalid (or not present) frame won't be processed.
# If you'd like to process frames w/ out this check, comment out the following function
# and change the below line "prn = checkfcs" to: "prn = associations"
magic = 0x2144df1c
pnum = 0
def checkfcs(pkt):
global pnum
pnum = pnum + 1
if pkt.haslayer(Dot11):
qcrc = binascii.crc32(pkt.payload.__str__()) & 0xffffffff
if qcrc == magic:
associations(pkt)
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Association Frame Randomizer</title>"
print "</head>"
print "<body>"
print "Reading pcap file..."
#print "</body>"
#print "</html>"
# if you want to direct right to Download from submit button use the following
#def present_download():
# open the tmp file for downloading
#read_pkts = open(temp_pkts_name, 'rb')
#outfile = read_pkts.read()
#print "Content-Type: application/vnd.tcpdump.pcap\nContent-Disposition: attachment; filename=\"%s\"\n" % (str(fn) + "_randomized.pcap")
#sys.stdout.write(outfile)
#read_pkts.close()
def mergecaps():
subprocess.Popen("/usr/bin/mergecap -F pcap -w ./caps/%s_randomized.pcap ./caps/%s_random_*" % (fn, fn) , shell=True, stdout=subprocess.PIPE).stdout.read()
print "<br> Processing Complete"
if os.path.isfile('./caps/%s_randomized.pcap' % fn):
print "<br><h4><a href=\"./caps/%s_randomized.pcap\">Click to download randomized pcap</a></h4>" % (fn)
else:
print "<br><p><h3>Error: NO Association Frames with valid FCS found!</p></h3>"
print "<br>If you think you've reached this even though assoc. frame exists in pcap, try opening in wireshark with display filter: \"wlan.fc.type_subtype==0\" to make sure. Make sure no whitespace exists in the filenme. <br>You could also try disabling FCS check on previous screen, by selecting \"RadioTap header NOT present\" option. It's possible that Association Frames are present, but are being skipped due to failed FCS."
if fileitem.filename:
global fn
fn = os.path.basename(fileitem.filename.replace("\\", "/" ))
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
infile = '/tmp/%s' % fn
if form.getvalue('pcap convert'):
print "<b>Attempting conversion on %s.</b>" % fn
subprocess.Popen("/usr/bin/tshark -r %s -w /tmp/converted-%s -F pcap" % (infile, fn) , shell=True, stdout=subprocess.PIPE).stdout.read()
infile = "/tmp/converted-%s" % fn
if form.getvalue('No Radiotap'):
print "No RadioTap Selected (FCS check disabled)."
sniff(offline=infile, prn = associations)
mergecaps()
else:
print "Expecting RadioTap Header presence."
sniff(offline=infile, prn = checkfcs)
mergecaps()
else:
print "ERROR: No file uploaded"
sys.exit(0)