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(":")
Exemple #2
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)
Exemple #4
0
    def _ipsVaryIteration(self, ruleSet, sIPvarying):
        """If sIP=True, the checks are made assuming sIP ist the varying part
           else, the check are made assuming dIP is the varying part.
           The checks work like this:
           1. The key for a rule are the ports.
           2. If the key (ports) is not in sortingDict, the rule is added to
              sortingDict and to tablesDict.
           3. If the key (ports) is already added, it is checked if the new rule
              is belonging to the rule already added.
              Belonging to is defined as that:
              3.1 If, by putting the rule together, they would have the same IP
                  on both sides (source/destination) they don't belong together.
              3.2 If the IPs don't belong into the same size slashSize networks,
                  the rules don't belong together.
            4. If the rule can be put together by making the existing IPs into
               size slashsize networks, the IPs are made into networks.
            5. If a rule has its key already in the dict, but can not be matched
               to the existing rule, it is put into the restSet.
            sPorts/dPorts exist in key and value, because they could be the same ("any")
            as the one already in the hashmap and still contain different elements. 
            To provide a correct elements list they needs to be extended.
            """
        self.sortingDict.clear()
        self.tablesDict.clear()
        newR = RuleSet()
        restSet = RuleSet()
        for r in ruleSet:
            if sIPvarying:
                value = [r.sIPs, r.dIPs, r.sPorts, r.dPorts, r.timeStamp, r.flag]
            else:
                value = [r.dIPs, r.sIPs, r.sPorts, r.dPorts, r.timeStamp, r.flag]

            key1 = copy.deepcopy(r.dPorts)
            key2 = copy.deepcopy(r.sPorts)
            keys = (r.direction, key1, r.interface, r.action, key2)
                 
            if keys not in self.sortingDict:
                self.sortingDict[keys] = value
                self.tablesDict[keys] = value
            else:
                tmpIPs1 = IPsMap()
                tmpIPs1.extend(value[0])
                tmpIPs1.extend(self.tablesDict[keys][0])
                tmpIPs2 = IPsMap()
                tmpIPs2.extend(value[1])
                tmpIPs2.extend(self.tablesDict[keys][1])

                sPortsRandom = value[2].isRandomized and\
                               self.tablesDict[keys][2].isRandomized \
                               or not value[2].isRandomized and not \
                               self.tablesDict[keys][2].isRandomized
        
                if not tmpIPs1.ipInBoth(tmpIPs2) and sPortsRandom \
                   and self.tablesDict[keys][1].checkForJoinedNetwork(value[1], self.SLASH_SIZE):
                        self.tablesDict[keys][0].extend(value[0])
                        self.tablesDict[keys][2].extend(value[2])
                        self.tablesDict[keys][3].extend(value[3])
                        if self.proto == "tcp":
                            self.tablesDict[keys][5].extend(value[5])
                else:
                    if sIPvarying:
                        restSet.insert(Rule(keys[0], value[0], value[2], \
                                            value[1], value[3], self.proto, keys[2], keys[3], self.style,  value[4], value[5]))
                    else:
                        restSet.insert(Rule(keys[0], value[1], value[2], \
                                            value[0], value[3], self.proto, keys[2], keys[3], self.style, value[4], value[5]))
        
        for key, value in self.tablesDict.iteritems():
            if sIPvarying:
                newR.insert(Rule(key[0], value[0], value[2], value[1], \
                                 value[3], self.proto, key[2], key[3], self.style, value[4], value[5]))
            else:
                newR.insert(Rule(key[0], value[1], value[2], value[0], \
                                 value[3], self.proto, key[2], key[3], self.style, value[4], value[5]))

        return newR, restSet