Esempio n. 1
0
	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
Esempio n. 2
0
    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
Esempio n. 3
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
Esempio n. 4
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
Esempio n. 5
0
	def parseWirelessPacket(self, packet):
		"""
		This is the core packet parsing routine.  It takes a Scapy style
		packet object as an argument.
		"""
		if packet.name == 'RadioTap dummy':
			packet = packet.payload  # offset it so we start with the Dot11 header
		shouldStop = False
		self.packetCounter += 1
		# this section finds SSIDs in Bacons, I don't like this section, but I do like bacon
		if packet.haslayer('Dot11Beacon') or packet.haslayer('Dot11ProbeResp') or packet.haslayer('Dot11AssoReq'):
			tmp = packet
			for x in range(0, SSID_SEARCH_RECURSION):
				if 'ID' in tmp.fields and tmp.fields['ID'] == 0 and 'info' in tmp.fields:	# this line verifies that we found an SSID
					if tmp.fields['info'] == '\x00':
						break  # null SSIDs are useless
					if self.targetSSIDs and tmp.fields['info'] not in self.targetSSIDs:	# Obi says: These are not the SSIDs you are looking for...
						break
					bssid = getBSSID(packet)
					if not bssid:
						return
					ssid = ''.join([c for c in tmp.fields['info'] if ((ord(c) > 31 or ord(c) == 9) and ord(c) < 128)])
					if not ssid:
						return
					if bssid in self.OrphanedBSSIDs:								# if this info is relating to a BSSID that was previously considered to be orphaned
						newNetwork = self.KnownNetworks[bssid]						# retrieve the old one
						del self.KnownNetworks[bssid]								# delete the old network's orphaned reference
						self.OrphanedBSSIDs.remove(bssid)
						self.BSSIDToSSIDMap[bssid] = ssid							# this changes the map from BSSID -> BSSID (for orphans) to BSSID -> SSID
						newNetwork.updateSSID(ssid)
						if ssid in self.KnownNetworks:
							newNetwork = mergeWirelessNetworks(newNetwork, self.KnownNetworks[ssid])
					elif bssid in self.BSSIDToSSIDMap:
						continue
					elif ssid in self.KnownNetworks:								# this is a BSSID from a probe for an SSID we've seen before
						newNetwork = self.KnownNetworks[ssid]						# so pick up where we left off by using the curent state of the WirelessNetwork object
					elif bssid:
						newNetwork = eapeak.networks.WirelessNetwork(ssid)
						self.BSSIDToSSIDMap[bssid] = ssid
					newNetwork.addBSSID(bssid)

					self.KnownNetworks[ssid] = newNetwork
					del bssid, ssid
					break
				tmp = tmp.payload
				if tmp is None:
					break
			shouldStop = True
		if shouldStop:
			return

		# this section extracts useful EAP info
		cert_layer = None
		if 'EAP' in packet:
			fields = packet.getlayer('EAP').fields
			if fields['code'] not in [1, 2]:							# don't bother parsing through success and failures just yet.
				return
			eaptype = fields['type']
			for x in range(1, 4):
				addr = 'addr' + str(x)									# outputs addr1, addr2, addr3
				if not addr in packet.fields:
					return
			bssid = getBSSID(packet)
			if not bssid:
				return
			if bssid and not bssid in self.BSSIDToSSIDMap:
				self.BSSIDToSSIDMap[bssid] = bssid
				self.OrphanedBSSIDs.append(bssid)
				self.KnownNetworks[bssid] = eapeak.networks.WirelessNetwork(UNKNOWN_SSID_NAME)
				self.KnownNetworks[bssid].addBSSID(bssid)
			network = self.KnownNetworks[self.BSSIDToSSIDMap[bssid]]				# objects should be returned, network to client should affect the client object as still in the BSSIDMap
			bssid = getBSSID(packet)
			client_mac = getSource(packet)
			from_AP = False
			if client_mac == bssid:
				client_mac = getDestination(packet)
				from_AP = True
			if not bssid or not client_mac:
				return																# something went wrong
			if network.hasClient(client_mac):
				client = network.getClient(client_mac)
			else:
				client = eapeak.clients.WirelessClient(bssid, client_mac)
			if from_AP:
				network.addEapType(eaptype)
			elif eaptype > 4:
				client.addEapType(eaptype)
			elif eaptype == 3 and fields['code'] == 2:								# this parses NAKs and attempts to harvest the desired EAP types, RFC 3748
				if 'eap_types' in fields:
					for eap in fields['eap_types']:
						client.addEapType(eap)
					del eap
			if eaptype == 254 and packet.haslayer(EAP_Expanded):
				network.addExpandedVendorID(packet.getlayer(EAP_Expanded).vendor_id)
			if from_AP:													# from here on we look for things based on whether it's to or from the AP
				if packet.haslayer('LEAP'):
					leap_fields = packet.getlayer(LEAP).fields
					if 'data' in leap_fields and len(leap_fields['data']) == 8:
						client.addMSChapInfo(17, challenge=leap_fields['data'], identity=leap_fields['name'])
					del leap_fields
				elif packet.getlayer(EAP).payload.name in ['EAP_TLS', 'EAP_TTLS', 'PEAP', 'EAP_Fast']:
					eap_layer = packet.getlayer(EAP).payload
					conn_string = bssid + ' ' + client_mac
					frag_flag, len_flag = {'EAP_TLS':(64, 128), 'EAP_TTLS':(8, 16), 'PEAP':(16, 32), 'EAP_Fast':(8, 16)}[eap_layer.name]
					if eap_layer.flags & frag_flag and eap_layer.flags & len_flag:
						self.fragment_buffer[conn_string] = [eap_layer]
					elif eap_layer.flags & frag_flag:
						if conn_string in self.fragment_buffer:
							self.fragment_buffer[conn_string].append(eap_layer.payload)
					elif eap_layer.flags == 0 and conn_string in self.fragment_buffer:
						eap_layer = eap_layer.__class__(''.join([x.do_build() for x in self.fragment_buffer[conn_string]]) + eap_layer.payload.do_build())	# take that people trying to read my code! Spencer 1, you 0.
						del self.fragment_buffer[conn_string]
					if eap_layer.haslayer('TLSv1Certificate'):			# at this point, if possible, we should have a fully assembled packet
						cert_layer = eap_layer.getlayer(TLSv1Certificate)
					del eap_layer, conn_string, frag_flag, len_flag
				elif packet.haslayer('EAP_Expanded') and packet.getlayer('EAP_Expanded').vendor_type == 1 and packet.haslayer('WPS') and packet.getlayer('WPS').opcode == 4:
					try:
						wpsData = parseWPSData(packet.getlayer('WPS').data)
						if network.wpsData is None:
							network.wpsData = wpsData
						else:
							network.wpsData.update(wpsData)
					except: # pylint: disable=bare-except
						pass

			else:
				if eaptype == 1 and 'identity' in fields:
					client.addIdentity(1, fields['identity'])
				if packet.haslayer('LEAP'):
					leap_fields = packet.getlayer(LEAP).fields
					identity = None
					if 'name' in leap_fields:
						identity = leap_fields['name']
						client.addIdentity(17, identity)
					if 'data' in leap_fields and len(leap_fields['data']) == 24:
						client.addMSChapInfo(17, response=leap_fields['data'], identity=identity)
					del leap_fields, identity
				elif packet.haslayer('EAP_Expanded') and packet.getlayer('EAP_Expanded').vendor_type == 1 and packet.haslayer('WPS') and packet.getlayer('WPS').opcode == 4:
					try:
						wpsData = parseWPSData(packet.getlayer('WPS').data)
						if client.wpsData is None:
							client.wpsData = wpsData
						else:
							client.wpsData.update(wpsData)
					except: # pylint: disable=bare-except
						pass  # data is corrupted
			network.addClient(client)
			if not cert_layer:
				shouldStop = True
		if shouldStop:
			return

		if cert_layer and 'certificate' in cert_layer.fields:
			cert_data = cert_layer.certificate[3:]
			tmp_certs = []
			while cert_data:
				if len(cert_data) < 4:
					break								# length and 1 byte are at least 4 bytes
				tmp_length = struct.unpack('!I', '\x00' + cert_data[:3])[0]
				cert_data = cert_data[3:]
				if len(cert_data) < tmp_length:
					break						# I smell corruption
				tmp_certs.append(cert_data[:tmp_length])
				cert_data = cert_data[tmp_length:]
			for certificate in tmp_certs:
				try:
					certificate = X509.load_cert_string(certificate, X509.FORMAT_DER)
				except X509.X509Error:
					pass
				network.addCertificate(certificate)
		return