def add_traffic_recv(dic, addr, from_addr=None, which=None): """ Adds recv to addr in Traffic key from parse() dictionnary :param dic: dict from parse() :param addr: str mac addr :param from_addr: str mac addr ::seealso:: parse() """ if is_multicast(from_addr) and which == "control": return if not is_multicast(addr) and isinstance(addr, str): if addr not in dic[WM_TRA]: dic[WM_TRA][addr] = Traffic(addr) dic[WM_TRA][addr].add_recv(from_addr, which)
def add_station(dic, bssid, ap_bssid): """ Adds bssid in Station key from parse() dictionnary :param dic: dict from parse() :param bssid: str mac addr :param ap_bssid: str mac addr ::seealso:: parse() """ if not is_multicast(bssid) and isinstance(bssid, str): if is_multicast(ap_bssid): ap_bssid = None if bssid not in dic[WM_STATION]: dic[WM_STATION][bssid] = Station(bssid, ap_bssid, vendor=dic[WM_VENDOR]) add_traffic(dic, bssid) elif ap_bssid is not None and dic[WM_STATION][bssid].ap_bssid is None: dic[WM_STATION][bssid].update(ap_bssid)
def get_broadcast(addr): """ Sent to web interface to visualise broadcast in client detail :param addr: str mac addr :return: addr if it is not broadcast else return broadcast + addr :rtype: str """ if is_multicast(addr): return "< %s - Broadcast >" % addr return addr
def add_ap(dic, bssid, seen): """ Adds an access point out of beacon/probeRes layers :param seen: str, seen from which layer, used in web interface """ if not is_multicast(bssid): if bssid not in dic[WM_AP]: dic[WM_AP][bssid] = AccessPoint(bssid, seen=seen, vendor=dic[WM_VENDOR]) add_traffic(dic, bssid) else: dic[WM_AP][bssid].update(seen)
def add_rssi(rssi, dic, addr): """ Adds rssi value to address in Traffic key from parse() dictionnary :param rssi: int :param dic: dict from parse() :param addr: str mac addr ::seealso:: parse() """ if rssi is not None and not is_multicast(addr) and\ isinstance(addr, str): if addr not in dic[WM_TRA]: dic[WM_TRA][addr] = Traffic(addr) traffic = dic[WM_TRA][addr] traffic.add_rssi(rssi)
def get_station_infos(packet, dic, channel=None): """ Parse the packet from its layers type add station and access point thanks to from-DS to-DS Handles traffic, rssi, handshakes, all stations and some ap :param packet: scapy packet :param dic: dictionnary from parse() ::seealso:: parse() """ ds = wifi_mapper_ds.get_addrs(packet) # Packets from AP to AP do not concern stations if ds[WM_DS_FROM] and ds[WM_DS_TO]: return rssi = rssi_scapy.get_rssi(packet) # Control packets are unreliable to get station, just add traffic and rssi if is_control(packet): if ds[WM_DS_SENT] is True: add_traffic_sent(dic, ds[WM_DS_STATION], to_addr=ds[WM_DS_DST], which="control") else: add_traffic_recv(dic, ds[WM_DS_STATION], from_addr=ds[WM_DS_SRC], which="control") add_rssi(rssi, dic, ds[WM_DS_STATION]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) return if packet.haslayer(Dot11ProbeResp): #Station receive probe response add_station(dic, ds[WM_DS_DST], None) add_traffic_recv(dic, ds[WM_DS_DST], from_addr=ds[WM_DS_SRC], which="probe") add_rssi(rssi, dic, ds[WM_DS_DST]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) elif packet.haslayer(Dot11ProbeReq): #Station request information add_station(dic, ds[WM_DS_SRC], None) add_traffic_sent(dic, ds[WM_DS_SRC], to_addr=None, which="probeReq") get_client_probe(packet, dic, ds[WM_DS_SRC]) add_rssi(rssi, dic, ds[WM_DS_SRC]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) elif packet.haslayer(Dot11Auth): #Authentication could be from or to station add_station(dic, ds[WM_DS_STATION], None) if ds[WM_DS_SENT]: add_traffic_sent(dic, ds[WM_DS_STATION], to_addr=ds[WM_DS_DST], which="Auth") add_ap(dic, ds[WM_DS_DST], seen="Auth") dic[WM_STATION][ds[WM_DS_STATION]].\ add_pre_eapol(ds[WM_DS_DST], "auth") else: add_traffic_recv(dic, ds[WM_DS_STATION], from_addr=ds[WM_DS_SRC],\ which="Auth") add_ap(dic, ds[WM_DS_SRC], seen="AuthResp") add_rssi(rssi, dic, ds[WM_DS_STATION]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) elif packet.haslayer(Dot11AssoReq): #Station request association add_station(dic, ds[WM_DS_SRC], None) add_ap(dic, ds[WM_DS_DST], seen="AssociationReq") add_traffic_sent(dic, ds[WM_DS_SRC], to_addr=ds[WM_DS_DST],\ which="Association") add_rssi(rssi, dic, ds[WM_DS_SRC]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) dic[WM_STATION][ds[WM_DS_SRC]].add_pre_eapol(ds[WM_DS_DST], "assos") elif packet.haslayer(Dot11ReassoReq): #Station request Reassociation add_station(dic, ds[WM_DS_SRC], None) add_ap(dic, ds[WM_DS_DST], seen="ReassociationReq") add_traffic_sent(dic, ds[WM_DS_SRC], to_addr=ds[WM_DS_DST],\ which="Reassociation") add_rssi(rssi, dic, ds[WM_DS_SRC]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) dic[WM_STATION][ds[WM_DS_SRC]].add_pre_eapol(ds[WM_DS_DST], "reassos") elif packet.haslayer(Dot11AssoResp): #Station receive association response add_station(dic, ds[WM_DS_DST], None) add_ap(dic, ds[WM_DS_SRC], seen="AssociationResp") add_traffic_recv(dic, ds[WM_DS_DST], from_addr=ds[WM_DS_SRC],\ which="Association") add_rssi(rssi, dic, ds[WM_DS_DST]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) dic[WM_STATION][ds[WM_DS_DST]].\ add_pre_eapol(ds[WM_DS_SRC], "assos_resp") elif packet.haslayer(Dot11ReassoResp): #Station receive Reassociation response add_station(dic, ds[WM_DS_DST], None) add_ap(dic, ds[WM_DS_SRC], seen="ReassociationResp") add_traffic_recv(dic, ds[WM_DS_DST], from_addr=ds[WM_DS_SRC],\ which="Reassociation") add_rssi(rssi, dic, ds[WM_DS_DST]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) dic[WM_STATION][ds[WM_DS_DST]].\ add_pre_eapol(ds[WM_DS_SRC], "reassos_resp") elif packet.haslayer(EAPOL): #Wpa handhsake between station and access point add_station(dic, ds[WM_DS_STATION], None) add_ap(dic, ds[WM_DS_BSSID], seen="Handshake") add_handshake(packet, dic, ds[WM_DS_STATION], ds[WM_DS_BSSID]) elif packet.haslayer(Dot11Disas): #Disassociation could be from or to station add_station(dic, ds[WM_DS_STATION], ds[WM_DS_BSSID]) if ds[WM_DS_SENT]: add_ap(dic, ds[WM_DS_DST], seen="DisassoSent") add_traffic_sent(dic, ds[WM_DS_STATION], to_addr=ds[WM_DS_DST],\ which="Disasso") else: add_ap(dic, ds[WM_DS_SRC], seen="DisassoRecv") add_traffic_recv(dic, ds[WM_DS_STATION], from_addr=ds[WM_DS_SRC],\ which="Disasso") add_rssi(rssi, dic, ds[WM_DS_STATION]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) dic[WM_STATION][ds[WM_DS_STATION]].\ add_ap_exit(ds[WM_DS_BSSID], "disasos", exited=ds[WM_DS_SENT]) elif packet.haslayer(Dot11Deauth): #Deauthentification could be from or to station add_station(dic, ds[WM_DS_STATION], ds[WM_DS_BSSID]) if ds[WM_DS_SENT]: add_ap(dic, ds[WM_DS_DST], seen="DeauthSent") add_traffic_sent(dic, ds[WM_DS_STATION], to_addr=ds[WM_DS_DST],\ which="Deauth") else: add_ap(dic, ds[WM_DS_SRC], seen="DeauthRecv") add_traffic_recv(dic, ds[WM_DS_STATION], from_addr=ds[WM_DS_SRC],\ which="Deauth") add_rssi(rssi, dic, ds[WM_DS_STATION]) add_rssi(rssi, dic, ds[WM_DS_BSSID]) dic[WM_STATION][ds[WM_DS_STATION]].\ add_ap_exit(ds[WM_DS_BSSID], "deauth", exited=ds[WM_DS_SENT]) elif is_data(packet) and not is_multicast(ds[WM_DS_DST]): #Data could be from or to station add_station(dic, ds[WM_DS_STATION], ds[WM_DS_BSSID]) if ds[WM_DS_SENT]: add_ap(dic, ds[WM_DS_DST], seen="DataSent") add_traffic_sent(dic, ds[WM_DS_STATION], to_addr=ds[WM_DS_DST],\ which="data") else: add_ap(dic, ds[WM_DS_SRC], seen="DataRecv") add_traffic_recv(dic, ds[WM_DS_STATION], from_addr=ds[WM_DS_SRC],\ which="data") add_rssi(rssi, dic, ds[WM_DS_STATION]) add_rssi(rssi, dic, ds[WM_DS_BSSID])
def get_ap_infos(packet, dic, channel=None): """ Get infos of access point in a beacon or probe response Parse Dot11 elements from packet and capabilities to get used privacy settings, ssid and channel :param packet: scapy packet :param dic: dict from parse() ::seealso:: parse() """ layer = Dot11 if packet.haslayer(Dot11) else Dot11FCS bssid = packet[layer].addr3 if is_multicast(bssid): return if bssid in dic[WM_AP]: if packet.haslayer(Dot11Beacon): dic[WM_AP][bssid].add_beacon() else: dic[WM_AP][bssid].add_proberesp() return elem = packet[Dot11Elt] capabilities = packet.sprintf( "{Dot11Beacon:%Dot11Beacon.cap%}" "{Dot11ProbeResp:%Dot11ProbeResp.cap%}").split('+') ssid, channel = None, None crypto = set() while isinstance(elem, Dot11Elt): #Some encoding errors there if elem.ID == ID_SSID: try: ssid = unicode(elem.info, 'utf-8') except UnicodeDecodeError: ssid = "" elif elem.ID == ID_DS and len(elem.info) == 1: #elem.info not always a char channel = ord(elem.info) elif elem.ID == ID_RSN: crypto.add("WPA2") elif elem.ID == ID_VENDOR and hasattr(elem, "info") and\ elem.info.startswith('\x00P\xf2\x01\x01\x00'): crypto.add("WPA") elem = elem.payload if not crypto: if 'privacy' in capabilities: crypto.add("WEP") else: crypto.add("OPN") if bssid not in dic[WM_AP]: ap = AccessPoint(bssid, ssid, channel, '/'.join(crypto), vendor=dic[WM_VENDOR]) add_traffic(dic, bssid) if packet.haslayer(Dot11Beacon): ap.add_beacon() else: ap.add_proberesp() dic[WM_AP][bssid] = ap else: ap = dic[WM_AP][bssid].check_infos(ssid, channel, '/'.join(crypto))
def add_traffic(dic, addr): if not is_multicast(addr) and isinstance(addr, str): if addr not in dic[WM_TRA]: dic[WM_TRA][addr] = Traffic(addr)