Example #1
0
    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)