How to use Scapy to determine Wireless Encryption

2019-02-23 19:25发布

问题:

I am doing a Security Research on Wireless networks which involves coding a small tool that scans for Wifi Access points in the vicinity. Based on the Encryption type found it goes on with some other security tests.

So far I have python code that uses Scapy to enumerate different access points and whether they have Encryption Enabled (Enc= Y or Enc=N). The code for this is:

def sniffAP(p):
    if ( (p.haslayer(Dot11Beacon) or p.haslayer(Dot11ProbeResp))
                 and not aps.has_key(p[Dot11].addr3)):
        ssid       = p[Dot11Elt].info
        bssid      = p[Dot11].addr3
        channel    = int( ord(p[Dot11Elt:3].info))
        capability = p.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}\
                {Dot11ProbeResp:%Dot11ProbeResp.cap%}")

        # Check for encrypted networks
        if re.search("privacy", capability): enc = 'Y'
        else: enc  = 'N'

What I want is the ability to distinguish between different Encryption Type (WEP, WPA, WPA2, WPS) using python and scapy. Any ideas?

回答1:

Based on airodump-ng code (aicrack-ng suite), the information you're looking for is inside specific Dot11Elt layers. By the way in your code, you get SSID and channel by guessing that they are located in the first and third Dot11Elt layers, which seems to be the case, but I don't think it's mandatory.

This code should do the work:

def insert_ap(pkt):
    ## Done in the lfilter param
    # if Dot11Beacon not in pkt and Dot11ProbeResp not in pkt:
    #     return
    bssid = pkt[Dot11].addr3
    if bssid in aps:
        return
    p = pkt[Dot11Elt]
    cap = pkt.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}"
                      "{Dot11ProbeResp:%Dot11ProbeResp.cap%}").split('+')
    ssid, channel = None, None
    crypto = set()
    while isinstance(p, Dot11Elt):
        if p.ID == 0:
            ssid = p.info
        elif p.ID == 3:
            channel = ord(p.info)
        elif p.ID == 48:
            crypto.add("WPA2")
        elif p.ID == 221 and p.info.startswith('\x00P\xf2\x01\x01\x00'):
            crypto.add("WPA")
        p = p.payload
    if not crypto:
        if 'privacy' in cap:
            crypto.add("WEP")
        else:
            crypto.add("OPN")
    print "NEW AP: %r [%s], channed %d, %s" % (ssid, bssid, channel,
                                               ' / '.join(crypto))
    aps[bssid] = (ssid, channel, crypto)

aps = {}
sniff(iface='mon0', prn=insert_ap, store=False,
      lfilter=lambda p: (Dot11Beacon in p or Dot11ProbeResp in p))

Update: this code is now obsolete. An updated version of this code has been integrated to Scapy.