示例#1
0
def _handle_packet(packet, result):
    from scapy.all import RadioTap, Dot11Elt, Dot11Beacon, rdpcap, Scapy_Exception, Dot11, Dot11ProbeResp, Dot11AssoReq, \
        Dot11ReassoReq, Dot11EltRSN, Dot11EltVendorSpecific, Dot11EltMicrosoftWPA
    """
    Analyze each packet and extract the data from Dot11 layers
    """

    if hasattr(packet, 'cap') and 'privacy' in packet.cap:
        # packet is encrypted
        if 'encryption' not in result:
            result['encryption'] = set()

    if packet.haslayer(Dot11Beacon):
        if packet.haslayer(Dot11Beacon)\
                or packet.haslayer(Dot11ProbeResp)\
                or packet.haslayer(Dot11AssoReq)\
                or packet.haslayer(Dot11ReassoReq):
            if 'bssid' not in result and hasattr(packet[Dot11], 'addr3'):
                result['bssid'] = packet[Dot11].addr3
            if 'essid' not in result and hasattr(packet[Dot11Elt], 'info'):
                result['essid'] = packet[Dot11Elt].info
            if 'channel' not in result and hasattr(packet[Dot11Elt:3], 'info'):
                result['channel'] = int(ord(packet[Dot11Elt:3].info))

    if packet.haslayer(RadioTap):
        if 'rssi' not in result and hasattr(packet[RadioTap], 'dBm_AntSignal'):
            result['rssi'] = packet[RadioTap].dBm_AntSignal
        if 'channel' not in result and hasattr(packet[RadioTap],
                                               'ChannelFrequency'):
            result['channel'] = freq_to_channel(
                packet[RadioTap].ChannelFrequency)

    # see: https://fossies.org/linux/scapy/scapy/layers/dot11.py
    if packet.haslayer(Dot11EltRSN):
        if hasattr(packet[Dot11EltRSN], 'akm_suites'):
            auth = AKMSUITE_TYPES.get(packet[Dot11EltRSN].akm_suites[0].suite)
            result['encryption'].add(f"WPA2/{auth}")
        else:
            result['encryption'].add("WPA2")

    if packet.haslayer(Dot11EltVendorSpecific)\
    and (packet.haslayer(Dot11EltMicrosoftWPA)
         or packet.info.startswith(b'\x00P\xf2\x01\x01\x00')):

        if hasattr(packet, 'akm_suites'):
            auth = AKMSUITE_TYPES.get(packet.akm_suites[0].suite)
            result['encryption'].add(f"WPA2/{auth}")
        else:
            result['encryption'].add("WPA2")
    # end see

    return result
示例#2
0
    def _parse_identity(self, radio, dot11, dot11elt):
        payload = b''
        while dot11elt:
            payload += dot11elt.info
            dot11elt = dot11elt.payload.getlayer(Dot11Elt)

        if payload != b'':
            adv = json.loads(payload)
            self._on_advertisement( \
                dot11.addr3,
                wifi.freq_to_channel(radio.Channel),
                radio.dBm_AntSignal,
                adv)
示例#3
0
def extract_from_pcap(path, fields):
    """
    Search in pcap-file for specified information

    path: Path to pcap file
    fields: Array of fields that should be extracted

    If a field is not found, FieldNotFoundError is raised
    """
    results = dict()
    for field in fields:
        if not isinstance(field, WifiInfo):
            raise TypeError("Invalid field")

        subtypes = set()

        if field == WifiInfo.BSSID:
            from scapy.all import Dot11Beacon, Dot11ProbeResp, Dot11AssoReq, Dot11ReassoReq, Dot11, sniff
            subtypes.add('beacon')
            bpf_filter = " or ".join([f"wlan type mgt subtype {subtype}" for subtype in subtypes])
            packets = sniff(offline=path, filter=bpf_filter)
            try:
                for packet in packets:
                    if packet.haslayer(Dot11Beacon):
                        if hasattr(packet[Dot11], 'addr3'):
                            results[field] = packet[Dot11].addr3
                            break
                else:  # magic
                    raise FieldNotFoundError("Could not find field [BSSID]")
            except Exception:
                raise FieldNotFoundError("Could not find field [BSSID]")
        elif field == WifiInfo.ESSID:
            from scapy.all import Dot11Beacon, Dot11ReassoReq, Dot11AssoReq, Dot11, sniff, Dot11Elt
            subtypes.add('beacon')
            subtypes.add('assoc-req')
            subtypes.add('reassoc-req')
            bpf_filter = " or ".join([f"wlan type mgt subtype {subtype}" for subtype in subtypes])
            packets = sniff(offline=path, filter=bpf_filter)
            try:
                for packet in packets:
                    if packet.haslayer(Dot11Elt) and hasattr(packet[Dot11Elt], 'info'):
                        results[field] = packet[Dot11Elt].info.decode('utf-8')
                        break
                else:  # magic
                    raise FieldNotFoundError("Could not find field [ESSID]")
            except Exception:
                raise FieldNotFoundError("Could not find field [ESSID]")
        elif field == WifiInfo.ENCRYPTION:
            from scapy.all import Dot11Beacon, sniff
            subtypes.add('beacon')
            bpf_filter = " or ".join([f"wlan type mgt subtype {subtype}" for subtype in subtypes])
            packets = sniff(offline=path, filter=bpf_filter)
            try:
                for packet in packets:
                    if packet.haslayer(Dot11Beacon) and hasattr(packet[Dot11Beacon], 'network_stats'):
                        stats = packet[Dot11Beacon].network_stats()
                        if 'crypto' in stats:
                            results[field] = stats['crypto']  # set with encryption types
                            break
                else:  # magic
                    raise FieldNotFoundError("Could not find field [ENCRYPTION]")
            except Exception:
                raise FieldNotFoundError("Could not find field [ENCRYPTION]")
        elif field == WifiInfo.CHANNEL:
            from scapy.all import sniff, RadioTap
            from pwnagotchi.mesh.wifi import freq_to_channel
            packets = sniff(offline=path, count=1)
            try:
                results[field] = freq_to_channel(packets[0][RadioTap].ChannelFrequency)
            except Exception:
                raise FieldNotFoundError("Could not find field [CHANNEL]")
        elif field == WifiInfo.RSSI:
            from scapy.all import sniff, RadioTap
            from pwnagotchi.mesh.wifi import freq_to_channel
            packets = sniff(offline=path, count=1)
            try:
                results[field] = packets[0][RadioTap].dBm_AntSignal
            except Exception:
                raise FieldNotFoundError("Could not find field [RSSI]")

    return results
示例#4
0
    def create_graph(data, channel=None):
        if not data:
            return '{}'

        data = json.loads(data)

        node_text = list()
        edge_x = list()
        edge_y = list()
        node_x = list()
        node_y = list()
        node_symbols = list()
        node_sizes = list()
        node_colors = list()

        for ap_data in data:
            name = ap_data['hostname'] or ap_data['vendor'] or ap_data['mac']
            color = Viz.lookup_color(name)
            # nodes
            x, y = abs(ap_data['rssi']), freq_to_channel(ap_data['frequency'])
            node_x.append(x)
            node_y.append(y)
            node_text.append(name)
            node_symbols.append('square')
            node_sizes.append(15 + len(ap_data['clients']) * 3)
            node_colors.append(color)

            for c in ap_data['clients']:
                # node
                cname = c['hostname'] or c['vendor'] or c['mac']
                xx, yy = Viz.random_pos(cname, x, y, 3)
                node_x.append(xx)
                node_y.append(yy)
                node_text.append(cname)
                node_symbols.append('circle')
                node_sizes.append(10)
                node_colors.append(color)

                # edge
                edge_x.append(x)
                edge_x.append(xx)
                edge_x.append(None)
                edge_y.append(y)
                edge_y.append(yy)
                edge_y.append(None)

        edge_trace = go.Scatter(x=edge_x,
                                y=edge_y,
                                line=dict(width=1, color='#888'),
                                hoverinfo='none',
                                mode='lines')

        node_trace = go.Scatter(x=node_x,
                                y=node_y,
                                mode='markers',
                                marker=dict(
                                    size=node_sizes,
                                    color=node_colors,
                                    symbol=node_symbols,
                                ),
                                hovertext=node_text,
                                hoverinfo='text')

        channel_line = go.Scatter(
            mode='lines',
            line=dict(width=15, color='#ff0000'),
            x=[min(node_x) - 5, max(node_x) + 5],
            y=[channel, channel],
            opacity=0.25,
            hoverinfo='none',
        ) if channel else dict()

        return json.dumps((channel_line, edge_trace, node_trace),
                          cls=plotly.utils.PlotlyJSONEncoder)