def handlePacket(self, pkt): IP_layer = IP if IP in pkt else IPv6 # add IPv6 support another night... if IP_layer == IPv6: return self.pkts.append(pkt) self.packet_count += 1 elts = [] edges = [] # FLOW ANALYSIS - reconstruct TCP flow if possible # do flow analysis here, if necessary - this will be replaced by dpkt's magic if TCP in pkt or UDP in pkt: Flow.pkt_handler(pkt, self.flows) flow = self.flows[Flow.flowid(pkt)] self.send_flow_statistics(flow) new_elts, new_edges = self.checkHTTP(flow) if new_elts: elts += new_elts if new_edges: edges += new_edges # end flow analysis # STANDARD PACKET ANALYSIS - extract IP addresses and domain names # the magic for extracting elements from packets happens here new_elts, new_edges = self.checkIP(pkt) # pass decode information if found if new_elts: elts += new_elts if new_edges: edges += new_edges new_elts, new_edges = self.checkDNS(pkt) if new_elts: elts += new_elts if new_edges: edges += new_edges # TLS MITM - intercept TLS communications and send cleartext to malcom # We want to be protocol agnostic (HTTPS, FTPS, ***S). For now, we choose which # connections to intercept based on destination port number # We could also catch ALL connections and MITM only those which start with # a TLS handshake tlsports = [443] if TCP in pkt and pkt[TCP].flags & 0x02 and pkt[TCP].dport in tlsports and not self.pcap and self.intercept_tls: # of course, interception doesn't work with pcaps # mark flow as tls flow.tls = True # add host / flow tuple to the TLS connection list debug_output("TLS SYN: {}:{} -> {}:{}".format(pkt[IP].src, pkt[TCP].sport, pkt[IP].dst, pkt[TCP].dport)) # this could actually be replaced by only flow self.tls_proxy.hosts[(pkt[IP].src, pkt[TCP].sport)] = (pkt[IP].dst, pkt[TCP].dport, flow.fid) self.tls_proxy.factory.flows[flow.fid] = flow if elts != [] or edges != []: self.send_nodes(elts, edges) # send individual packets to modules in case they use them for mod in self.modules.values(): mod.on_packet(pkt)