Example #1
0
def parse_packet(packet):
    try:
        off, rt = radiotap.radiotap_parse(packet)
    except:
        global packets_dropped
        packets_dropped = packets_dropped + 1
        # TODO Why this happening?
        return

    if packet[off] == '\x80':
        # beacon frame
        return

    mac = packet[off + 4:off + 10]
    now = strftime("%Y-%m-%d %H:%M:%S")
    address = radiotap.macstr(mac)
    if not address or address == 'ff:ff:ff:ff:ff:ff':
        return

    if address not in all_devices:
        all_devices[address] = {
            'mac_address': address,
            'first_seen': now,
            'last_seen': now,
            'packets': 0,
        }

    # Use dBm: http://stackoverflow.com/questions/14777114/what-is-rssi-value-in-802-11-packet
    all_devices[address].update({
        'power': rt.get('dbm_antsignal', 0),
        'noise': rt.get('dbm_antnoise', 0),
        'last_seen': now,
        'packets': all_devices[address]['packets'] + 1,
    })

    # Only active devices matter
    # We do that because so much fake mac is appearing, wasn't happening only in C
    # Probably the python radiotap is not working well...
    # TODO why?
    if all_devices[address]['packets'] > 20:
        if address not in devices:
            global devices_count
            devices_count = devices_count + 1

            try:
                r = requests.get('http://www.macvendorlookup.com/api/v2/' + address)
                if r.status_code == 200:
                    vendor = r.json()[0]['company']
                else:
                    vendor = 'Unknown'
            except:
                vendor = 'Unknown'
            devices[address] = {
                'vendor': vendor
            }

        devices[address].update(all_devices[address])

    global packets_count
    packets_count = packets_count + 1
Example #2
0
def packet_parse(packet):

    off, radiotap = radiotap_parse(packet)
    off, i80211 = ieee80211_parse(packet, off)
    # TODO fix ahead, better clean it!
    # note: this is done to remove the frame check sequence from packet_data
    i80211_detail = i80211_info(i80211, packet[0:len(packet) - 4], off)
    parsed = radiotap
    parsed.update(i80211)
    parsed.update(i80211_detail)

    return parsed
Example #3
0
    def handle(self, *args, **options):
        pc = pcap.pcap(name='mon0')
        pc.setnonblock(True)
        w = we.WirelessExtension('mon0')
        while 1:
            with transaction.atomic():
                while (time.time() < self.queue):
                    result = pc.next()
                    if not result: continue
                    tstamp, pkt = result
                    off, radiotap = r.radiotap_parse(pkt)
                    off, pkt = r.ieee80211_parse(pkt, off)
                    if not pkt: continue
                    if pkt['from_ds']:
                        if pkt['to_ds']:
                            device, create = Device.objects.get_or_create(
                                src_mac=pkt['addr4'])
                        else:
                            device, create = Device.objects.get_or_create(
                                src_mac=pkt['addr2'])
                    else:
                        device, create = Device.objects.get_or_create(
                            src_mac=pkt['addr2'])
                    if pkt['to_ds']:
                        if pkt['addr3'] != 'ff:ff:ff:ff:ff:ff':
                            device.dst_mac = pkt['addr3']
                    else:
                        if pkt['addr1'] != 'ff:ff:ff:ff:ff:ff':
                            device.dst_mac = pkt['addr1']

                    device.signal = radiotap['dbm_antsignal']
                    device.lastseen = timezone.now()

                    device.save()

                    if pkt['type'] == 0 and pkt['subtype'] == 4:
                        if pkt['data'][0] != '\x01':
                            Probe.objects.get_or_create(
                                device=device,
                                probe=pkt['data'].split('\x01')[0])
                    if pkt['type'] == 0 and pkt['subtype'] == 8:
                        essid = pkt['data'][12:]
                        if essid != '\x01':
                            Probe.objects.get_or_create(
                                device=device, probe=essid.split('\x01')[0])

            self.queue = time.time() + 10
            self.channel += 1
            if (self.channel > len(self.channels)):
                self.channel = 0
            print self.channel
            w.set_channel(self.channels[self.channel])
Example #4
0
def parse_file(fn):
    pkt = open(fn, 'rb').read()

    while len(pkt):
        off, radiotap = r.radiotap_parse(pkt, valuelist=True)
        for row in radiotap:
            if 'oui' in row:
                print_vendor(row)
            for k, v in row.items():
                if k in fields_to_print:
                    lbl, fmt = fields_to_print[k]
                    print('\t%s: %s' % (lbl, fmt(v)))
        pkt = pkt[off:]
Example #5
0
def parse_file(fn):
    pkt = open(fn).read()

    while len(pkt):
        off, radiotap = r.radiotap_parse(pkt, valuelist=True)
        for row in radiotap:
            if 'oui' in row:
                print_vendor(row)
            for k,v in row.items():
                if k in fields_to_print:
                    lbl, fmt = fields_to_print[k]
                    print '\t%s: %s' % (lbl, fmt(v))
        pkt = pkt[off:]
Example #6
0
def test_ac_rate_1():
    """
    Frame 1: 4865 bytes on wire (38920 bits), 188 bytes captured (1504 bits)
Radiotap Header v0, Length 38
    Header revision: 0
    Header pad: 0
    Header length: 38
    Present flags
    MAC timestamp: 270036265
    Flags: 0x40
    Channel frequency: 5180 [A 36]
    Channel flags: 0x0140, Orthogonal Frequency-Division Multiplexing (OFDM), 5 GHz spectrum
    SSI Signal: -76 dBm
    Antenna: 0
    RX flags: 0x0000
    VHT information
        Known VHT information: 0x44
        .... .1.. = Guard interval: short (1)
        Bandwidth: 80 MHz (4)
        User 0: MCS 9
            1001 .... = MCS index 0: 9 (256-QAM 5/6)
            .... 0011 = Spatial streams 0: 3
            Coding 0: BCC (0)
            [Data Rate: 1299.9 Mb/s]
802.11 radio information
    PHY type: 802.11ac (8)
    Short GI: True
    Bandwidth: 80 MHz (4)
    User 0: MCS 9
    Channel: 36
    Frequency: 5180 MHz
    Signal strength (dBm): -76 dBm
    TSF timestamp: 270036265
IEEE 802.11 Unrecognized (Reserved frame), Flags: o.m.R..T
IEEE 802.11 wireless LAN extension frame
    """
    buf = (
        """\x00\x00&\x00+H \x00)m\x18\x10\x00\x00\x00\x00@\x00<\x14@\x01\xb4\x00\x00\x00D\x00\x04\x04\x93"""
        "\x00\x00\x00\x00\x00\x00\x00\x8c\xa9z\xa8\'\xda\x8c.\xeaD$l\x95\x16\xa9>\xd5\x8eo\xdb\xb7$\xceIF"
        """\xa1\x19\xd38\x0b\xc4%\xce\xb5.\xbaM\'\xad\xc9\x8a.\x83\'\xa9\xab\xe1<\xe8B\x0c\x1dE\x08@"\xf7"""
        """\x06Bb\xdf\xf2\xf7\x11\xd8\xf2\xd6[\x98Lv\xa9{\x07Ph~\xa1\x8a\x96\xf7o\xff\xb9\x1c\xc3\xf0\xd3\x04"""
        """\xfb\xfe\xbc\xa5\x16\xbd;l\xb1\xa7l\xc5\xf3\x84\xdf\xdd`Vn\xeb\xac\xbf\x04\x9by\x91T"`\xbb\xbbl\n"""
        """\xfd\xd77\'_\x91\x1d_\xb8\xa6\\0S\xf9q\xd8\x18O\xb7\xf0G\xc0\x9e\x0e|\xa8 \x14""")
    off, radiotap = r.radiotap_parse(buf)
    assert radiotap
    assert len(radiotap['vht_user'])==1
    assert radiotap['vht_user'][0] == {'vht_rate_mbps': 1300.0,
                                       'vht_coding': 0,
                                       'vht_mcs_index': 9,
                                       'vht_mcs_descr': ('256QAM', '5/6')}
Example #7
0
def test_ac_rate_2():
   """
   Frame 1: 1615 bytes on wire (12920 bits), 188 bytes captured (1504 bits)
Radiotap Header v0, Length 38
    Header revision: 0
    Header pad: 0
    Header length: 38
    Present flags
    MAC timestamp: 254101463
    Flags: 0x40
    Channel frequency: 5180 [A 36]
    Channel flags: 0x0140, Orthogonal Frequency-Division Multiplexing (OFDM), 5 GHz spectrum
    SSI Signal: -76 dBm
    Antenna: 0
    RX flags: 0x0000
    VHT information
        Known VHT information: 0x44
        .... .0.. = Guard interval: long (0)
        Bandwidth: 80 MHz (4)
        User 0: MCS 8
            1000 .... = MCS index 0: 8 (256-QAM 3/4)
            .... 0011 = Spatial streams 0: 3
            Coding 0: BCC (0)
            [Data Rate: 1053.0 Mb/s]
802.11 radio information
    PHY type: 802.11ac (8)
    Short GI: False
    Bandwidth: 80 MHz (4)
    User 0: MCS 8
    Channel: 36
    Frequency: 5180 MHz
    Signal strength (dBm): -76 dBm
    TSF timestamp: 254101463
IEEE 802.11 QoS Null function (No data), Flags: ....R.F.
   """
   buf = (
    """\x00\x00&\x00+H \x00\xd7G%\x0f\x00\x00\x00\x00@\x00<\x14@\x01\xb4\x00\x00\x00D\x00\x00\x04\x83\x00\x00"""
    """\x00\x00\x00\x00\x00\xc9\n\xacT\x9d\x0b#T\xe6]\xa3p\xdfN\x98\xfdyR_\x8a=~\xb7\x90\x07\x10_2\x95\xa6\xa3"""
    """\xf2\x06\xa9/E\xa5?\xcbg\xac\x11Y]\xcb\\\xd8-\n\xc8\xb6|}0[S\x8d\xac\xcc\xafmT%\xd2\xa7\xdep\xfb\xe2\x0f"""
    """\xf1\x0e\xd8hF\xcb\xf6\x92t\xd5\n\xed\xb4y\xf2qj\x8a\x04\xbc\xf3C\x93]\xd9n\xa0\xfa{l\xff\xa3=MC\xb0"""
    """\xd2\xf6\x0f\xb8\x87\xf2T\xdf#}\xfe\xe1\x8f\xe1\xa1\xd5zI\x1f6\xceZ\xa0\xae\x14\x01\xfeb\xce\xa3@\xa4"""
    """\xe2M\x13\n\xb9\x99\x1f\n\x88p\xcb\xb8""")
   off, radiotap = r.radiotap_parse(buf)
   assert radiotap
   assert len(radiotap['vht_user'])==1
   assert radiotap['vht_user'] == {0: {'vht_rate_mbps': 1053.0,
                                       'vht_mcs_index': 8,
                                       'vht_coding': 0,
                                       'vht_mcs_descr': ('256QAM', '3/4')}}
Example #8
0
    def handle(self, *args, **options):
        pc = pcap.pcap(name='mon0')
        pc.setnonblock(True)
        w = we.WirelessExtension('mon0')
        while 1:
            with transaction.atomic():
                while (time.time() < self.queue):
                    result = pc.next()
                    if not result: continue
                    tstamp, pkt = result
                    off, radiotap = r.radiotap_parse(pkt)
                    off, pkt = r.ieee80211_parse(pkt, off)
                    if not pkt: continue
                    if pkt['from_ds']:
                        if pkt['to_ds']:
                            device, create = Device.objects.get_or_create(src_mac=pkt['addr4'])
                        else:
                            device, create = Device.objects.get_or_create(src_mac=pkt['addr2'])
                    else:
                        device, create = Device.objects.get_or_create(src_mac=pkt['addr2'])
                    if pkt['to_ds']:
                        if pkt['addr3'] != 'ff:ff:ff:ff:ff:ff':
                            device.dst_mac = pkt['addr3']
                    else:
                        if pkt['addr1'] != 'ff:ff:ff:ff:ff:ff':
                            device.dst_mac = pkt['addr1']

                    device.signal = radiotap['dbm_antsignal']
                    device.lastseen = timezone.now()

                    device.save()

                    if pkt['type'] == 0 and pkt['subtype'] == 4:
                        if pkt['data'][0] != '\x01':
                            Probe.objects.get_or_create(device=device, probe=pkt['data'].split('\x01')[0])
                    if pkt['type'] == 0 and pkt['subtype'] == 8:
                        essid = pkt['data'][12:]
                        if essid != '\x01':
                            Probe.objects.get_or_create(device=device, probe=essid.split('\x01')[0])

            self.queue = time.time()+10
            self.channel += 1
            if (self.channel > len(self.channels)):
                self.channel = 0
            print self.channel
            w.set_channel(self.channels[self.channel])
Example #9
0

def build_packet_cb(db, stdout, ignored):
    def packet_callback(packet):
        now = time.time()
        # look up vendor from OUI value in MAC address
        try:
            parsed_mac = netaddr.EUI(packet.addr2)
            vendor = parsed_mac.oui.registration().org
        except netaddr.core.NotRegisteredError, e:
            vendor = u'UNKNOWN'
        except IndexError:
            vendor = u'UNKNOWN'

        # parse radiotap headers to get RSSI value
        offset, headers = radiotap_parse(str(packet))
        rssi = headers['dbm_antsignal']

        try:
            ssid = packet.info.decode('utf-8')
        except UnicodeDecodeError:
            # encode the SSID in base64 because it will fail
            # to be inserted into the db otherwise
            ssid = u'b64_%s' % base64.b64encode(packet.info)
        fields = [now, packet.addr2, vendor, ssid, rssi]

        if packet.addr2 not in ignored:
            insert_into_db(fields, db)

            if stdout:
                # convert time to iso
Example #10
0
def beacon_ts(mac, fixed):
    ts, = struct.unpack_from('<Q', fixed, 0)
    return ts

fn = sys.argv[1]
pc = pcap.pcap(fn)
count = 0
sta_files = {}
window_files = {}
nstas = 0
windows = {}

for ts, pkt in pc:

    rofs, rtap = radiotap.radiotap_parse(pkt)
    ofs, mac = radiotap.ieee80211_parse(pkt, rofs)

    if not rtap.has_key('TSFT'):
	    continue
    ts = rtap['TSFT']

    # check for expiry of any windows, if so write them to window_files
    for sta in windows.keys():
        window = windows[sta]
        if ts > window['end']:
            print >>window_files[sta], '%d %d' % (window['start'], window['end'])
            windows.pop(sta)

    count += 1
Example #11
0
    'RADIOTAP_NAMESPACE', 'VENDOR_NAMESPACE', 'EXT'
]


def parse_radiotap_index(present_bytes):
    present_bits = '{:032b}'.format(
        int.from_bytes(present_bytes, byteorder='little'))[::-1]
    field_list = []
    for i, b in enumerate(present_bits):
        if b == '1':
            field_list.append((i, RADIOTAP_FIELD_TABLE[i]))
    return field_list


radiotap_bga = (b'\x00\x00'
                b'\x0d\x00'
                b'\x04\x80\x02\x00'
                b'\x02'
                b'\x00\x00\x00'
                b'\x00')
radiotap_ht = (b'\x00\x00'
               b'\x0e\x00'
               b'\x00\x80\x0a\x00'
               b'\x00\x00'
               b'\x00'
               b'\x07\x00\x01')

r_hdr_len, r_hdr_parsed = radiotap.radiotap_parse(radiotap_ht)
print(parse_radiotap_index(b'\x00\x80\x0a\x00'))
print(r_hdr_len, r_hdr_parsed)
import radiotap as r
import pcap
from scapy.all import *

pc = pcap.pcap(name='variable_rate_attack02_mon_VP')

pkt = pc[0]

off, radiotap = r.radiotap_parse(pkt)

print(radiotap)

off, mac = r.ieee80211_parse(pkt, off)

print(mac)
Example #13
0
    def packet_callback(packet):
        if not packet.haslayer(Dot11):
            return

        with open('/proc/uptime', 'r') as f:
            uptime = f.readline().split()[0]
        now = datetime.now()

        address = None
        ap_address = None
        if packet.type == 0:
            if sta and packet.subtype == 0:
                sender = 'STA_AssoReq'
                ap_address = packet.addr1
                address = packet.addr2
            elif sta and packet.subtype == 1:
                sender = 'AP_AssoResp'
                address = packet.addr1
                ap_address = packet.addr2
            elif sta and packet.subtype == 2:
                sender = 'STA_ReassoResp'
                ap_address = packet.addr1
                address = packet.addr2
            elif sta and packet.subtype == 3:
                sender = 'AP_ReassoResp'
                address = packet.addr1
                ap_address = packet.addr2
            elif sta and packet.subtype == 4:
                sender = 'STA_ProbeReq'
                address = packet.addr2
            elif sta and packet.subtype == 5:
                sender = 'AP_ProbeResp'
                address = packet.addr1
                ap_address = packet.addr2
            elif not sta and packet.subtype == 8:
                sender = 'AP_Beacon'
                ap_address = packet.addr2
            elif sta and packet.subtype == 9:
                sender = 'AP_ATIM'
                address = packet.addr1
                ap_address = packet.addr2
            elif sta and packet.subtype == 10:
                sender = 'AP_Disas'
                address = packet.addr1
                ap_address = packet.addr2
            elif sta and packet.subtype == 11:
                sender = 'STA_Auth'
                ap_address = packet.addr1
                address = packet.addr2
            elif sta and packet.subtype == 12:
                sender = 'STA_Deauth'
                ap_address = packet.addr1
                address = packet.addr2
            else:
                return
        elif sta and packet.type == 2 and packet.subtype == 0:
            ds = packet.FCfield & 0x3
            # to_ds = (ds & 0x1) != 0
            # from_ds = (ds & 0x2) != 0
            if ds == 1:  # STA to AP
                sender = 'STA_Data'
                ap_address = packet.addr1
                address = packet.addr2
            elif ds == 2:  # AP to STA
                address = packet.addr1
                sender = 'AP_Data'
                ap_address = packet.addr2
            else:
                return
        else:
            return

        global last_address, last_ap_address
        if address == last_address and ap_address == last_ap_address:
            return
        last_address = address
        last_ap_address = ap_address

        content = {
            'uptime': uptime,
            'date': now.strftime("%Y/%m/%d %H:%M:%S"),
            'sender': sender,
            'channel': channel
        }
        if address:
            content['address'] = address.upper()
            content['vendor'] = get_vendor(address)

        if ap_address:
            content['ap_address'] = ap_address.upper()
            content['ap_vendor'] = get_vendor(ap_address)
            try:
                content['ap_name'] = packet.info.decode('utf-8',
                                                        errors='replace')
            except UnicodeDecodeError:
                content['ap_name'] = packet.info
            except AttributeError:
                pass

        offset, headers = radiotap_parse(str(packet))
        if sender.startswith('STA_'):
            content['rssi'] = headers['dbm_antsignal']
        else:
            content['ap_rssi'] = headers['dbm_antsignal']

        output(queue, content)