def parse_http_response(sessions):
    http_data = {}
    host_counter = 0

    for session, pkt in sessions.items():
        for packet in sessions[session]:
            response_headers = []

            if packet.haslayer(http.HTTPResponse):
                http_layer = packet.getlayer(http.HTTPResponse)  #Raw response
                headers = str(http_layer).split("\\r\\n\\r\\n")
                hdrs = headers[0]
                post_body = http_layer.payload

                http_data[f"Host{host_counter}"] = {}
                http_data[f"Host{host_counter}"]["Http_Version"] = str(
                    http_layer.Http_Version)
                http_data[f"Host{host_counter}"]["Status_Code"] = str(
                    http_layer.Status_Code)
                temp = hdrs.split("\\r\\n")

                for i in range(1, len(temp)):
                    #Example: 'Content-Encoding: gzip' . Split it to get a list which contains ['Content-Encoding', 'gzip']
                    hdr = temp[i].split(": ")
                    http_data[f"Host{host_counter}"][hdr[0]] = str(hdr[1])

                http_data[f"Host{host_counter}"]["POST_Body"] = str(post_body)
                http_data[f"Host{host_counter}"]["Raw Request"] = str(
                    http_layer)

                #Extract images from POST Body and write to them to disk
                if ('Content-Type' or 'content-type' or 'Content-type'
                        or 'content-Type') in http_data[f"Host{host_counter}"]:
                    if re.search(
                            '[iI]mage\/',
                            str(http_data[f"Host{host_counter}"].values())):
                        print(f"[+]Writing image to the disk...")

                        rand_num = str(random.randrange(
                            1000000, 9999999999999))

                        h = f"Host_{host_counter}"
                        dr = create_host_dir(h, rand_num)
                        filename = f"{dr}/{rand_num}"

                        with open(filename, 'wb') as f:
                            #Convert scapy.packet.raw object to bytes object and write to a binary file
                            f.write(bytes(post_body))

                    else:
                        pass  #other content types

                else:
                    #print(f"[-]Key not found or Content-Type is not Image: ")
                    pass

                host_counter += 1

    return http_data
Example #2
0
	def get_leap_data(self, packet, client):
		leap_fields = packet.getlayer('LEAP').fields
		identity = None
		if 'name' in leap_fields:
			identity = leap_fields['name']
			client.add_identity(17, identity)
		if 'data' in leap_fields and len(leap_fields['data']) == 24:
			client.add_ms_chap_info(17, response=leap_fields['data'], identity=identity)
		del leap_fields, identity
Example #3
0
	def get_eap_data(self, packet, bssid, client_mac):
		cert_layer = None
		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
		return cert_layer
def parse_http_reqs(sessions):
    http_data = {}
    host_counter = 0

    for session, pkt in sessions.items():
        for packet in sessions[session]:
            if packet.haslayer(http.HTTPRequest):
                http_layer = packet.getlayer(http.HTTPRequest)
                raw_req = str(http_layer)
                headers = str(http_layer).split("\\r\\n")
                #Remove last two garbage elements from headers list
                headers.pop(
                    -1
                )  # Remove "'"  caused by str(packet[TCP].payload).split("\\r\\n")
                headers.pop(
                    -1
                )  # Remove '' caused by str(packet[TCP].payload).split("\\r\\n")

                #Store all HTTP headers, Raw request etc for this host in a dict 'http_data'
                http_data[f"Host{host_counter}"] = {}
                http_data[f"Host{host_counter}"]["Method"] = str(
                    http_layer.Method)
                http_data[f"Host{host_counter}"]["Path"] = str(http_layer.Path)
                http_data[f"Host{host_counter}"]["HTTP_Version"] = str(
                    packet[TCP].Http_Version
                )  #Not sure as to why http_layer.HTTP_Version does not work
                http_data[f"Host{host_counter}"]["Host"] = str(http_layer.Host)

                #Start from Index 2 because we already captured a few headers above.
                for i in range(2, len(headers)):
                    hdr = headers[i].split(": ")
                    http_data[f"Host{host_counter}"][hdr[0]] = hdr[1]

                http_data[f"Host{host_counter}"]["Raw_Request"] = raw_req
                host_counter += 1

    return http_data
Example #5
0
	def get_leap_from_ap_data(self, packet, client):
		leap_fields = packet.getlayer('LEAP').fields
		if 'data' in leap_fields and len(leap_fields['data']) == 8:
			client.add_ms_chap_info(17, challenge=leap_fields['data'], identity=leap_fields['name'])
		del leap_fields
Example #6
0
	def get_wps_data(self, packet, network):
		wpsData = parse_wps_data(packet.getlayer('WPS').data)
		if network.wpsData is None:
			network.wpsData = wpsData
		else:
			network.wpsData.update(wpsData)
Example #7
0
	def get_client_wps_data(self, packet, client):
		wpsData = parse_wps_data(packet.getlayer('WPS').data)
		if client.wpsData is None:
			client.wpsData = wpsData
		else:
			client.wpsData.update(wpsData)
Example #8
0
	def parse_wireless_packet(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
		if packet.haslayer('Dot11Beacon') or packet.haslayer('Dot11ProbeResp') or packet.haslayer('Dot11AssoReq'):
			self.update_maps(packet)
			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]:
				return
			eaptype = fields['type']
			for x in range(1, 4):
				addr = 'addr' + str(x)
				if not addr in packet.fields:
					return
			bssid = get_bssid(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].add_BSSID(bssid)
			network = self.KnownNetworks[self.BSSIDToSSIDMap[bssid]]
			client_mac = get_source(packet)
			from_AP = False
			if client_mac == bssid:
				client_mac = get_destination(packet)
				from_AP = True
			if not bssid or not client_mac:
				return
			if network.has_client(client_mac):
				client = network.get_client(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:  # Parses NAKs and attempts to harvest the desired EAP types, RFC 3748
				self.get_client_eap_types(fields, client)
			if eaptype == 254 and packet.haslayer('EAP_Expanded'):
				network.add_expanded_vendor_id(packet.getlayer('EAP_Expanded').vendor_id)
			if from_AP:
				if packet.haslayer('LEAP'):
					self.get_leap_from_ap_data(packet, client)
				elif packet.getlayer(EAP).payload.name in ['EAP_TLS', 'EAP_TTLS', 'PEAP', 'EAP_Fast']:
					cert_layer = self.get_eap_data(packet, bssid, client_mac)
				elif packet.haslayer('EAP_Expanded') and packet.getlayer('EAP_Expanded').vendor_type == 1 and packet.haslayer('WPS') and packet.getlayer('WPS').opcode == 4:
					try:
						self.get_wps_data(packet, network)
					except:  # pylint: disable=bare-except
						pass

			else:
				if eaptype == 1 and 'identity' in fields:
					client.add_identity(1, fields['identity'])
				if packet.haslayer('LEAP'):
					self.get_leap_data(packet, client)
				elif packet.haslayer('EAP_Expanded') and packet.getlayer('EAP_Expanded').vendor_type == 1 and packet.haslayer('WPS') and packet.getlayer('WPS').opcode == 4:
					try:
						self.get_client_wps_data(packet, client)
					except:  # pylint: disable=bare-except
						pass  # Data is corrupted
			network.add_client(client)
			if not cert_layer:
				shouldStop = True
		if shouldStop:
			return

		if cert_layer and 'certificate' in cert_layer.fields:
			self.get_cert_data(network, cert_layer)
		return
Example #9
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