class SSIDBroadcaster(threading.Thread): """ This object is a thread-friendly SSID broadcaster It's meant to be controlled by the Wireless State Machine """ def __init__(self, interface, essid, bssid=None): threading.Thread.__init__(self) self.interface = interface self.essid = essid if not bssid: bssid = getHwAddr(interface) self.bssid = bssid.lower() self.broadcast_interval = 0.15 self.channel = "\x06" self.setPrivacy(PRIVACY_NONE) self.sequence = randint(1200, 2000) self.__shutdown__ = False def __unfuckupSC__(self, fragment=0): """ This is a reserved method to return the sequence number in a way that is not f****d up by a bug in how the SC field is packed in Scapy. """ if self.sequence >= 0xFFF: self.sequence = 1 else: self.sequence += 1 SC = (self.sequence - ((self.sequence >> 4) << 4) << 12) + (fragment << 8) + ( self.sequence >> 4) # bit shifts FTW! return unpack('<H', pack('>H', SC))[0] def run(self): """ This is the thread routine that broadcasts the SSID. """ while not self.__shutdown__: self.beacon.getlayer(Dot11).SC = self.__unfuckupSC__() sendp(self.beacon, iface=self.interface, verbose=False) sleep(self.broadcast_interval) def setPrivacy(self, value): """ Configure the privacy settings for None, WEP, and WPA """ if value == PRIVACY_NONE: self.beacon = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid ) / Dot11Beacon(cap='ESS+short-preamble+short-slot') / Dot11Elt( ID="SSID", info=self.essid) / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24') / Dot11Elt( ID="DSset", info=self.channel) / Dot11Elt( ID=42, info="\x04") / Dot11Elt( ID=47, info="\x04") / Dot11Elt( ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WEP: self.beacon = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid) / Dot11Beacon( cap='ESS+privacy+short-preamble+short-slot') / Dot11Elt( ID="SSID", info=self.essid) / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24' ) / Dot11Elt(ID="DSset", info=self.channel) / Dot11Elt( ID=42, info="\x04") / Dot11Elt( ID=47, info="\x04") / Dot11Elt( ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WPA: self.beacon = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid ) / Dot11Beacon( cap='ESS+privacy+short-preamble+short-slot' ) / Dot11Elt(ID="SSID", info=self.essid) / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24' ) / Dot11Elt(ID="DSset", info=self.channel) / Dot11Elt( ID=221, info="\x00\x50\xf2\x01\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x01" ) / Dot11Elt( ID=42, info="\x00" ) / Dot11Elt( ID=50, info="\x30\x48\x60\x6c" ) / Dot11Elt( ID=221, info= "\x00\x50\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00" ) def sendBeacon(self): """ Convenience function for sending beacons without starting a thread """ self.beacon.getlayer(Dot11).SC = self.__unfuckupSC__() sendp(self.beacon, iface=self.interface, verbose=False) @staticmethod def sendBeaconEx(essid, interface, privacy=PRIVACY_NONE, bssid=None, channel=6): """ Convenience function for sending beacons without a thread or creating an instance """ if not bssid: bssid = getHwAddr(interface) channel = chr(channel) sequence = randint(1200, 2000) if privacy in [PRIVACY_NONE, 'none', 'NONE']: beacon = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=bssid, addr3=bssid, SC=sequence ) / Dot11Beacon(cap='ESS+short-preamble+short-slot') / Dot11Elt( ID="SSID", info=essid) / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24') / Dot11Elt( ID="DSset", info=channel) / Dot11Elt( ID=42, info="\x04") / Dot11Elt( ID=47, info="\x04") / Dot11Elt( ID=50, info="\x0c\x12\x18\x60") elif privacy in [PRIVACY_WEP, 'wep', 'WEP']: beacon = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=bssid, addr3=bssid, SC=sequence) / Dot11Beacon( cap='ESS+privacy+short-preamble+short-slot') / Dot11Elt( ID="SSID", info=essid) / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24' ) / Dot11Elt(ID="DSset", info=channel) / Dot11Elt( ID=42, info="\x04") / Dot11Elt( ID=47, info="\x04") / Dot11Elt( ID=50, info="\x0c\x12\x18\x60") elif privacy in [PRIVACY_WPA, 'wpa', 'WPA']: beacon = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=bssid, addr3=bssid, SC=sequence ) / Dot11Beacon( cap='ESS+privacy+short-preamble+short-slot' ) / Dot11Elt(ID="SSID", info=essid) / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24' ) / Dot11Elt(ID="DSset", info=channel) / Dot11Elt( ID=221, info="\x00\x50\xf2\x01\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x01" ) / Dot11Elt( ID=42, info="\x00" ) / Dot11Elt( ID=50, info="\x30\x48\x60\x6c" ) / Dot11Elt( ID=221, info= "\x00\x50\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00" ) else: raise Exception('Invalid privacy setting') sendp(beacon, iface=interface, verbose=False)
class SSIDBroadcaster(threading.Thread): """ This object is a thread-friendly SSID broadcaster It's meant to be controlled by the Wireless State Machine """ def __init__(self, interface, essid, bssid = None): threading.Thread.__init__(self) self.interface = interface self.essid = essid if not bssid: bssid = getHwAddr(interface) self.bssid = bssid.lower() self.broadcast_interval = 0.15 self.channel = "\x06" self.setPrivacy(PRIVACY_NONE) self.sequence = randint(1200, 2000) self.__shutdown__ = False def __unfuckupSC__(self, fragment = 0): """ This is a reserved method to return the sequence number in a way that is not f****d up by a bug in how the SC field is packed in Scapy. """ if self.sequence >= 0xFFF: self.sequence = 1 else: self.sequence += 1 SC = (self.sequence - ((self.sequence >> 4) << 4) << 12) + (fragment << 8) + (self.sequence >> 4) # bit shifts FTW! return unpack('<H', pack('>H', SC))[0] def run(self): """ This is the thread routine that broadcasts the SSID. """ while not self.__shutdown__: self.beacon.getlayer(Dot11).SC = self.__unfuckupSC__() sendp(self.beacon, iface=self.interface, verbose=False) sleep(self.broadcast_interval) def setPrivacy(self, value): """ Configure the privacy settings for None, WEP, and WPA """ if value == PRIVACY_NONE: self.beacon = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid)/Dot11Beacon(cap='ESS+short-preamble+short-slot')/Dot11Elt(ID="SSID",info=self.essid)/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=self.channel)/Dot11Elt(ID=42, info="\x04")/Dot11Elt(ID=47, info="\x04")/Dot11Elt(ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WEP: self.beacon = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid)/Dot11Beacon(cap='ESS+privacy+short-preamble+short-slot')/Dot11Elt(ID="SSID",info=self.essid)/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=self.channel)/Dot11Elt(ID=42, info="\x04")/Dot11Elt(ID=47, info="\x04")/Dot11Elt(ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WPA: self.beacon = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid)/Dot11Beacon(cap='ESS+privacy+short-preamble+short-slot')/Dot11Elt(ID="SSID",info=self.essid)/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=self.channel)/Dot11Elt(ID=221, info="\x00\x50\xf2\x01\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x01")/Dot11Elt(ID=42, info="\x00")/Dot11Elt(ID=50, info="\x30\x48\x60\x6c")/Dot11Elt(ID=221, info="\x00\x50\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00") def sendBeacon(self): """ Convenience function for sending beacons without starting a thread """ self.beacon.getlayer(Dot11).SC = self.__unfuckupSC__() sendp(self.beacon, iface=self.interface, verbose=False) @staticmethod def sendBeaconEx(essid, interface, privacy = PRIVACY_NONE, bssid = None, channel = 6): """ Convenience function for sending beacons without a thread or creating an instance """ if not bssid: bssid = getHwAddr(interface) channel = chr(channel) sequence = randint(1200, 2000) if privacy in [PRIVACY_NONE, 'none', 'NONE']: beacon = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=bssid, addr3=bssid, SC=sequence)/Dot11Beacon(cap='ESS+short-preamble+short-slot')/Dot11Elt(ID="SSID",info=essid)/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=channel)/Dot11Elt(ID=42, info="\x04")/Dot11Elt(ID=47, info="\x04")/Dot11Elt(ID=50, info="\x0c\x12\x18\x60") elif privacy in [PRIVACY_WEP, 'wep', 'WEP']: beacon = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=bssid, addr3=bssid, SC=sequence)/Dot11Beacon(cap='ESS+privacy+short-preamble+short-slot')/Dot11Elt(ID="SSID",info=essid)/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=channel)/Dot11Elt(ID=42, info="\x04")/Dot11Elt(ID=47, info="\x04")/Dot11Elt(ID=50, info="\x0c\x12\x18\x60") elif privacy in [PRIVACY_WPA, 'wpa', 'WPA']: beacon = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=bssid, addr3=bssid, SC=sequence)/Dot11Beacon(cap='ESS+privacy+short-preamble+short-slot')/Dot11Elt(ID="SSID",info=essid)/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=channel)/Dot11Elt(ID=221, info="\x00\x50\xf2\x01\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x01")/Dot11Elt(ID=42, info="\x00")/Dot11Elt(ID=50, info="\x30\x48\x60\x6c")/Dot11Elt(ID=221, info="\x00\x50\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00") else: raise Exception('Invalid privacy setting') sendp(beacon, iface=interface, verbose=False)
class ClientListener(threading.Thread): """ This object is a thread-friendly listener for Client connection attempts. The backlog corresponds to the size of the queue, if the queu is full because the items are not being handled fast enough then new association requests will be dropped and lost. """ def __init__(self, interface, backlog, essid=None, bssid=None): threading.Thread.__init__(self) self.interface = interface self.backlog = backlog self.essid = essid if not bssid: bssid = getHwAddr(interface) self.bssid = bssid.lower() self.lastpacket = None self.client_queue = Queue.Queue(self.backlog) # FIFO self.channel = "\x06" self.sequence = randint(1200, 2000) self.__shutdown__ = False def __unfuckupSC__(self, fragment=0): """ This is a reserved method to return the sequence number in a way that is not f****d up by a bug in how the SC field is packed in Scapy. """ if self.sequence >= 0xFFF: self.sequence = 1 else: self.sequence += 1 SC = (self.sequence - ((self.sequence >> 4) << 4) << 12) + (fragment << 8) + ( self.sequence >> 4) # bit shifts FTW! return unpack('<H', pack('>H', SC))[0] def __stopfilter__(self, packet): """ This is the stop filter for Scapy to be used to check if the packet was sent to EAPeak. """ if (packet.haslayer('Dot11Auth') or packet.haslayer('Dot11AssoReq')): if getBSSID( packet) == self.bssid and getSource(packet) != self.bssid: self.lastpacket = packet return True return False elif packet.haslayer('Dot11ProbeReq'): self.lastpacket = packet return True return False def setPrivacy(self, value): """ Configure the privacy settings for None, WEP, and WPA """ if value == PRIVACY_NONE: self.probe_response_template = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid) / Dot11ProbeResp( cap='ESS+privacy+short-preamble+short-slot') / Dot11Elt( ID="SSID", info='') / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24' ) / Dot11Elt(ID="DSset", info=self.channel) / Dot11Elt( ID=42, info="\x04") / Dot11Elt( ID=47, info="\x04") / Dot11Elt( ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WEP: self.probe_response_template = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid ) / Dot11ProbeResp(cap='ESS+short-preamble+short-slot') / Dot11Elt( ID="SSID", info='') / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24') / Dot11Elt( ID="DSset", info=self.channel) / Dot11Elt( ID=42, info="\x04") / Dot11Elt( ID=47, info="\x04") / Dot11Elt( ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WPA: self.probe_response_template = RadioTap() / Dot11( addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid ) / Dot11ProbeResp( cap='ESS+privacy+short-preamble+short-slot' ) / Dot11Elt(ID="SSID", info='') / Dot11Elt( ID="Rates", info='\x82\x84\x8b\x96\x0c\x12\x18\x24' ) / Dot11Elt(ID="DSset", info=self.channel) / Dot11Elt( ID=221, info="\x00\x50\xf2\x01\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x01" ) / Dot11Elt( ID=42, info="\x00" ) / Dot11Elt( ID=50, info="\x30\x48\x60\x6c" ) / Dot11Elt( ID=221, info= "\x00\x50\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00" ) def run(self): """ This is the thread routine that handles probe requests and sends probe responses when appropriate. """ while not self.__shutdown__: sniff(iface=self.interface, store=0, timeout=RESPONSE_TIMEOUT, stop_filter=self.__stopfilter__) if self.lastpacket: if self.lastpacket.haslayer('Dot11ProbeReq'): ssid = None # not to be confused with self.essid, they could be different and need to be evaluated tmp = self.lastpacket.getlayer(Dot11ProbeReq) while tmp: tmp = tmp.payload if tmp.fields['ID'] == 0: ssid = tmp.info break if ssid is None: continue elif ssid == '' and self.essid: ssid = self.essid if self.essid is None or self.essid == ssid: self.probe_response_template.getlayer( Dot11).addr1 = getSource(self.lastpacket) self.probe_response_template.getlayer( Dot11Elt).info = ssid sendp(self.probe_response_template, iface=self.interface, verbose=False) self.lastpacket = None continue clientMAC = getSource(self.lastpacket) if not self.client_queue.full(): self.client_queue.put(clientMAC, False) self.lastpacket = None continue
class ClientListener(threading.Thread): """ This object is a thread-friendly listener for Client connection attempts. The backlog corresponds to the size of the queue, if the queu is full because the items are not being handled fast enough then new association requests will be dropped and lost. """ def __init__(self, interface, backlog, essid = None, bssid = None): threading.Thread.__init__(self) self.interface = interface self.backlog = backlog self.essid = essid if not bssid: bssid = getHwAddr(interface) self.bssid = bssid.lower() self.lastpacket = None self.client_queue = Queue.Queue(self.backlog) # FIFO self.channel = "\x06" self.sequence = randint(1200, 2000) self.__shutdown__ = False def __unfuckupSC__(self, fragment = 0): """ This is a reserved method to return the sequence number in a way that is not f****d up by a bug in how the SC field is packed in Scapy. """ if self.sequence >= 0xFFF: self.sequence = 1 else: self.sequence += 1 SC = (self.sequence - ((self.sequence >> 4) << 4) << 12) + (fragment << 8) + (self.sequence >> 4) # bit shifts FTW! return unpack('<H', pack('>H', SC))[0] def __stopfilter__(self, packet): """ This is the stop filter for Scapy to be used to check if the packet was sent to EAPeak. """ if (packet.haslayer('Dot11Auth') or packet.haslayer('Dot11AssoReq')): if getBSSID(packet) == self.bssid and getSource(packet) != self.bssid: self.lastpacket = packet return True return False elif packet.haslayer('Dot11ProbeReq'): self.lastpacket = packet return True return False def setPrivacy(self, value): """ Configure the privacy settings for None, WEP, and WPA """ if value == PRIVACY_NONE: self.probe_response_template = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid)/Dot11ProbeResp(cap='ESS+privacy+short-preamble+short-slot')/Dot11Elt(ID="SSID",info='')/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=self.channel)/Dot11Elt(ID=42, info="\x04")/Dot11Elt(ID=47, info="\x04")/Dot11Elt(ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WEP: self.probe_response_template = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid)/Dot11ProbeResp(cap='ESS+short-preamble+short-slot')/Dot11Elt(ID="SSID",info='')/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=self.channel)/Dot11Elt(ID=42, info="\x04")/Dot11Elt(ID=47, info="\x04")/Dot11Elt(ID=50, info="\x0c\x12\x18\x60") elif value == PRIVACY_WPA: self.probe_response_template = RadioTap()/Dot11(addr1="ff:ff:ff:ff:ff:ff", addr2=self.bssid, addr3=self.bssid)/Dot11ProbeResp(cap='ESS+privacy+short-preamble+short-slot')/Dot11Elt(ID="SSID",info='')/Dot11Elt(ID="Rates",info='\x82\x84\x8b\x96\x0c\x12\x18\x24')/Dot11Elt(ID="DSset",info=self.channel)/Dot11Elt(ID=221, info="\x00\x50\xf2\x01\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x02" + "\x01\x00" + "\x00\x50\xf2\x01")/Dot11Elt(ID=42, info="\x00")/Dot11Elt(ID=50, info="\x30\x48\x60\x6c")/Dot11Elt(ID=221, info="\x00\x50\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00\x27\xa4\x00\x00\x42\x43\x5e\x00\x62\x32\x2f\x00") def run(self): """ This is the thread routine that handles probe requests and sends probe responses when appropriate. """ while not self.__shutdown__: sniff(iface=self.interface, store=0, timeout=RESPONSE_TIMEOUT, stop_filter=self.__stopfilter__) if self.lastpacket: if self.lastpacket.haslayer('Dot11ProbeReq'): ssid = None # not to be confused with self.essid, they could be different and need to be evaluated tmp = self.lastpacket.getlayer(Dot11ProbeReq) while tmp: tmp = tmp.payload if tmp.fields['ID'] == 0: ssid = tmp.info break if ssid == None: continue elif ssid == '' and self.essid: ssid = self.essid if self.essid == None or self.essid == ssid: self.probe_response_template.getlayer(Dot11).addr1 = getSource(self.lastpacket) self.probe_response_template.getlayer(Dot11Elt).info = ssid sendp(self.probe_response_template, iface=self.interface, verbose=False) self.lastpacket = None continue clientMAC = getSource(self.lastpacket) if not self.client_queue.full(): self.client_queue.put(clientMAC, False) self.lastpacket = None continue