def _packetHandler(self, buf, ts): """Parse a pcap buffer""" SINGLE_IP_SLASHSIZE = 32 try: if (self.p.datalink() == self.PFLOG_DUMP): #pkt = dpkt.pflog.Pflog(buf) pkt = Pflog(buf) self.interface = pkt.interfaceName self.direction = "in" if pkt.direction == 1 else "out" subpkt = pkt.data try: subpkt = dpkt.ip.IP(subpkt) except: #skip non IP packets return else: pkt = dpkt.ethernet.Ethernet(buf) subpkt = pkt.data if not isinstance(subpkt, dpkt.ip.IP): #skip non IP packets return proto = subpkt.p shost = socket.inet_ntoa(subpkt.src) dhost = socket.inet_ntoa(subpkt.dst) shostInner = False dhostInner = False if self.innerNetworks != None: for n in self.innerNetworks: slashSize = str(n).split("/")[1] if IPv4Network(str(shost)+"/"+str(slashSize)) == n: shostInner = True if IPv4Network(dhost+"/"+slashSize) == n: dhostInner = True if shostInner and dhostInner: self.direction = "none-inner" elif shostInner and not dhostInner: self.direction = "out" elif not shostInner and dhostInner: self.direction = "in" else: self.direction = "none-outer" except dpkt.Error: #skip non-ethernet packages return try: if proto == socket.IPPROTO_TCP: try: tcp = subpkt.data flag = tcp.flags if self.connectionChecking: rightFlag = ((flag == dpkt.tcp.TH_SYN) \ or (flag & dpkt.tcp.TH_FIN != 0)) else: rightFlag = (flag == dpkt.tcp.TH_SYN) dport = tcp.dport sport = tcp.sport sIP = IPsMap(self.saveElements) sIP.insert(IPv4Address(shost)) sPort = PortsMap(self.MAX_NUM_PORTS_ANY, self.saveElements) sPort.insert(Port(sport, True)) dIP = IPsMap(self.saveElements) dIP.insert(IPv4Address(dhost)) dPort = PortsMap(self.MAX_NUM_PORTS_ANY, self.saveElements) dPort.insert(Port(dport, False)) if flag == dpkt.tcp.TH_SYN: flag = "SYN" else: flag = "FIN" r = Rule(self.direction, sIP, sPort, dIP, dPort, "tcp", \ self.interface, self.action, self.style, [ts, ], [flag, ]) if self.p.datalink() == self.PFLOG_DUMP or rightFlag: self.tcpRuleSet.insert(r) if self.ddosDetection: self.tcpRuleList.append((IPv4Address(shost), ts)) except AttributeError: #skip broken packages return elif proto == socket.IPPROTO_UDP: udp = subpkt.data dport = udp.dport sport = udp.sport sIP = IPsMap(self.saveElements) sIP.insert(IPv4Address(shost)) sPort = PortsMap(self.MAX_NUM_PORTS_ANY, self.saveElements) sPort.insert(Port(sport, True)) dIP = IPsMap(self.saveElements) dIP.insert(IPv4Address(dhost)) dPort = PortsMap(self.MAX_NUM_PORTS_ANY, self.saveElements) dPort.insert(Port(dport, False)) r = Rule(self.direction, sIP, sPort, dIP, dPort, "udp", \ self.interface, self.action, self.style, [ts, ]) self.udpRuleSet.insert(r) if self.ddosDetection: self.udpRuleList.append((IPv4Address(shost), ts)) elif proto == socket.IPPROTO_ICMP: sIP = IPsMap(self.saveElements) sIP.insert(IPv4Address(shost)) sPort = PortsMap(self.MAX_NUM_PORTS_ANY) sPort.insert(Port(-1, True)) dIP = IPsMap(self.saveElements) dIP.insert(IPv4Address(dhost)) dPort = PortsMap(self.MAX_NUM_PORTS_ANY) dPort.insert(Port(-1, False)) r = Rule(self.direction, sIP, sPort, dIP, dPort, "icmp", \ self.interface, self.action, self.style, [ts, ]) self.icmpRuleSet.insert(r) if self.ddosDetection: self.icmpRuleList.append((IPv4Address(shost), ts)) except dpkt.Error: return
class InfectedHostsDetector: """ InfectedHostsDetector takes found portscans and policy violations and tries to find indected hosts. """ def __init__(self, tcpPortscans, udpPortscans, policyViolations, suspPolVio): self.tcpPortscans = tcpPortscans self.udpPortscans = udpPortscans self.policyViolations = policyViolations self.portscans = RuleSet() self.doubleIPs = IPsMap() self.portscanIPs = IPsMap() self.violationIPs = IPsMap() self.clearedPolicyViolations = RuleSet() self.suspPolVio = suspPolVio.split(":") def detectInfectedHosts(self): for ps in self.tcpPortscans.portscanSet: if ps.direction == "out" or ps.direction == "none-inner": self.portscans.insert(ps) for ps in self.udpPortscans.portscanSet: if ps.direction == "out" or ps.direction == "none-inner": self.portscans.insert(ps) for pv in self.policyViolations: if pv.direction == "out" or pv.direction == "none-inner": if str(pv.dPorts.values()[0].portNumber) in self.suspPolVio: self.clearedPolicyViolations.insert(pv) for portscan in self.portscans: for violation in self.clearedPolicyViolations: if portscan.sIPs == violation.sIPs: self.doubleIPs.insert(portscan.sIPs) for doubleIP in self.doubleIPs: for policyVio in self.clearedPolicyViolations.values(): if policyVio.sIPs == doubleIP: try: self.clearedPolicyViolations.remove(policyVio) except: # already removed pass for doubleIP in self.doubleIPs: for portscan in self.portscans.values(): if portscan.sIPs == doubleIP: try: self.portscans.remove(portscan) except: # already removed pass for violation in self.clearedPolicyViolations: self.violationIPs.insert(violation.sIPs) for portscan in self.portscans: self.portscanIPs.insert(portscan.sIPs) def printInfectedHosts(self): for host in self.doubleIPs: print "%s might be infected! Warning signals include: portscans and policy violations" % str(host) for host in self.portscanIPs: print "%s might be infected! Warning signals include: portscans" % str(host) for host in self.violationIPs: print "%s might be infected! Warning signals include: policy violations" % str(host)