def test_depends_ab_ba(self):
        rs = RuleSet()

        rs.addDep("a", "b")
        rs.addDep("b", "a")

        self.assertTrue(rs.isCoherent(), "rs.isCoherent failed")
Пример #2
0
    def _portsVary(self, sPortVarying):
        """If key is not in sortingDict put key-value pairs in sortingDict and
           tablesDict,
           else merge value to existing value.
           sIPs/dIPs 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()
        for r in self.ruleSet:
            if sPortVarying:
                keys = (r.direction, r.sIPs, r.dIPs, r.dPorts, r.interface, r.action)
                value = (r.sPorts, r.timeStamp, r.flag, r.sIPs, r.dIPs)
            else:
               keys = (r.direction, r.sIPs, r.sPorts, r.dIPs, r.interface, r.action)
               value = (r.dPorts, r.timeStamp, r.flag, r.sIPs, r.dIPs)
            self._sortIntoDicts(keys, value)

        for key, value in self.tablesDict.iteritems():
            if sPortVarying:
                r = Rule(key[0], value[3], value[0], value[4], key[3], self.proto, key[4], key[5], self.style, value[1], value[2])
            else:
                r = Rule(key[0], value[3], key[2], value[4], value[0], self.proto, key[4], key[5], self.style,  value[1], value[2])
            newR.insert(r)

        self.ruleSet = newR
        del newR    
    def __init__(self):
        ruleset_id = 'ga_ws_pub_sdts'
        ruleset_name = 'GA Web Service Publication Standards'
        passed = True
        rules_results = []

        # make a Graph from the string or file

        #
        #   Run all the rules
        #
        service_pass = r'http://services.ga.gov.au/gis/services/NEXIS_Building_Exposure/MapServer/WFSServer?request=GetCapabilities'
        service_fail = r'http://www.ga.gov.au/gis/services/topography/National_Ferry_Terminals/MapServer/WFSServer?request=GetCapabilities'

        #rules_results.append(GaTitle(service_pass).get_result())
        rules_results.append(WebServiceTitle(service_pass).get_result())

        # calculate if RuleSet passed
        for rule in rules_results:
            if not rule['passed']:
                passed = False

        #
        #   Call the base RuleSet constructor
        #
        RuleSet.__init__(self,
                         ruleset_id,
                         ruleset_name,
                         '*****@*****.**',
                         rules_results,
                         passed)
Пример #4
0
 def test_ruleset(self):
     with open('people.json') as f1:
         people_data = json.load(f1)
     results = list()
     for person in people_data['people']:
         with open('rules.json') as f2:
             rules_data = json.load(f2)
         rs = RuleSet(rules_data)
         results.append(rs.evaluate(person))
     for result in results:
         if result['name'] == 'FRED':
             self.assertEqual(result['status'], 'COOL')
         elif result['name'] == 'GINGER':
             self.assertEqual(result['status'], 'OLD')
         elif result['name'] == 'SID':
             self.assertEqual(result['status'], 'ANCIENT')
         elif result['name'] == 'NANCY':
             self.assertEqual(result['status'], 'VERY OLD')
         elif result['name'] == 'JOE':
             self.assertEqual(result['status'], 'YOUNG')
         elif result['name'] == 'FLO':
             self.assertEqual(result['status'], 'VERY OLD')
         elif result['name'] == 'REG':
             self.assertEqual(result['status'], 'WEIRD')
         elif result['name'] == 'BRIAN':
             self.assertEqual(result['status'], 'DEAD')
         elif result['name'] == 'ELSIE':
             self.assertEqual(result['status'], 'OLD HIPPY')
             self.assertEqual(result['nickname'], 'Hippy')
Пример #5
0
    def __init__(self):
        ruleset_id = 'ga_ws_pub_sdts'
        ruleset_name = 'GA Web Service Publication Standards'
        passed = True
        rules_results = []

        # make a Graph from the string or file

        #
        #   Run all the rules
        #
        service_pass = r'http://services.ga.gov.au/gis/services/NEXIS_Building_Exposure/MapServer/WFSServer?request=GetCapabilities'
        service_fail = r'http://www.ga.gov.au/gis/services/topography/National_Ferry_Terminals/MapServer/WFSServer?request=GetCapabilities'

        #rules_results.append(GaTitle(service_pass).get_result())
        rules_results.append(WebServiceTitle(service_pass).get_result())

        # calculate if RuleSet passed
        for rule in rules_results:
            if not rule['passed']:
                passed = False

        #
        #   Call the base RuleSet constructor
        #
        RuleSet.__init__(self, ruleset_id, ruleset_name,
                         '*****@*****.**', rules_results, passed)
Пример #6
0
def filterWithExistingRules(existRulesFile, style, tcpRules, udpRules, icmpRules):
    existingRuleset = RuleSet()
    existingRuleset.initializeFromExistingRuleset(existRulesFile, "pass", style)
    print "Filtering Rules with existing ruleset"
    tcpRules = testRules(tcpRules, existingRuleset)
    udpRules = testRules(udpRules, existingRuleset)
    icmpRules = testRules(icmpRules, existingRuleset)
    return tcpRules, udpRules, icmpRules
Пример #7
0
    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(":")
Пример #8
0
 def __init__(self, id, ranges, rules, depth, partitions, manual_partition):
     self.id = id
     self.partitions = list(partitions or [])
     self.manual_partition = manual_partition
     self.ranges = ranges
     self.rules = RuleSet(rules) if isinstance(rules, list) else rules
     self.depth = depth
     self.children = []
     self.action = None
     self.pushup_rules = None
     self.num_rules = len(self.rules)
Пример #9
0
 def _filterRules(self, rules, checkList, proto, direction):        
     filteredRules = RuleSet()
     for s in checkList:
         if s[2] == proto or s[2] == "any":
             for r in rules.values():
                 for d in direction:
                     if r.direction == d \
                        and (s[0] in r.dIPs or s[0] == "any") \
                        and (s[1] in r.dPorts or s[1] == "any"):
                         rules.remove(r)
                         filteredRules.insert(r)
     return filteredRules 
Пример #10
0
    def test_ab_bc_toggle(self):
        rs = RuleSet()
        rs.addDep("a", "b")
        rs.addDep("b", "c")
        self.assertTrue(rs.isCoherent(), "rs.isCoherent failed")
        opts = Options(rs)
        opts.toggle("c")

        self.assertSetEqual(
            opts.selection(),
            set(["c"]),
            "toggle expected (c) got %s" % opts.selection(),
        )
Пример #11
0
    def __init__(self, tcpRules, udpRules, icmpRules, innerServicesList, outerServicesList, \
                 forbiddenInnerServicesList, restrictedNetworks):

        self.tcpRules = tcpRules
        self.udpRules = udpRules
        self.icmpRules = icmpRules
        self.innerServicesList = self._parseServiceList(innerServicesList)
        self.outerServicesList = self._parseServiceList(outerServicesList)
        self.forbiddenInnerServicesList = self._parseServiceList(forbiddenInnerServicesList)
        self.restrictedNetworksList = self._parseNetworkList(restrictedNetworks)
        self.filteredRules = RuleSet()
        self.innerServicesFiltered = RuleSet()
        self.outerServicesFiltered = RuleSet()
        self.forbiddenInnerServicesFiltered = RuleSet()
        self.restrictedNetworksFiltered = RuleSet()
Пример #12
0
    def __init__(
        self,
        rules,
        leaf_threshold,
        refinements={
            "node_merging": False,
            "rule_overlay": False,
            "region_compaction": False,
            "rule_pushup": False,
            "equi_dense": False
        }):
        # hyperparameters
        self.leaf_threshold = leaf_threshold
        self.refinements = refinements

        self.rules = RuleSet(rules) if isinstance(rules, list) else rules
        self.root = self.create_node(
            0, [0, 2**32, 0, 2**32, 0, 2**16, 0, 2**16, 0, 2**8], rules, 1,
            None, None)
        if (self.refinements["region_compaction"]):
            self.refinement_region_compaction(self.root)
        self.current_node = self.root
        self.nodes_to_cut = [self.root]
        self.depth = 1
        self.node_count = 1
Пример #13
0
def testRules(connections, rules, verbose=False):
    filtertConns = RuleSet()
    for c in connections:
        ruled = False
        for r in rules:
            if c.interface == r.interface and c.proto == r.proto:
                if _testPorts(c, r):
                    if _testIPs(c, r):
                        ruled = True
                        break
        if not ruled:
            if verbose:
                print "Was not matched"
                print c
            filtertConns.insert(c)   
    return filtertConns
Пример #14
0
    def _checkTcpForConns(self):
        """Checks tcp-set for connections.""" 
        print "Checking for Connections"
        tcpRuleSetConnsOnly = RuleSet()
        if self.p.linktype == self.PFLOG_DUMP:
            tcpRuleSetConnsOnly = self.tcpRuleSet
        else:
            for r in self.tcpRuleSet:
                connection = False
                for r2 in self.tcpRuleSet:
                    if (r == r2 and (r.flag[0]=="SYN") and (r2.flag[0]=="FIN")):
                        connection = True
                        break
                if connection:
                    tcpRuleSetConnsOnly.insert(r)

        self.tcpRuleSet = tcpRuleSetConnsOnly 
Пример #15
0
def main():
    '''Main entry point for module.'''

    config = load_config('test.conf')
    myrules = RuleSet()
    myrules.load_rules('syntax.yml')
    myresult = []

    for rule in myrules.rules:
        result = rule.apply(config)
        for element in result:
            if element.result == False:
                print "Rule evaluation failed:\n Cfgline: '{}'\n Rule: {}".format(
                    element.cfgline.text,
                    element.rule)
        myresult.append(result)
    return myresult
    def test_exclusive_ab(self):
        rs = RuleSet()

        rs.addDep("a", "b")
        rs.addConflict("a", "b")

        self.assertFalse(rs.isCoherent(), "rs.isCoherent failed")
Пример #17
0
 def __init__(self, pcapFile, action, style, direction, maxNumPortsAny, \
              connectionChecking, portscanChecking, printElements, \
              innerNetworks=None, ddosDetection=True): 
     self.p = pcapFile
     self.direction = direction 
     self.action = action
     self.style = style
     self.interface = "None"
     self.tcpRuleSet = RuleSet()
     self.udpRuleSet = RuleSet()
     self.icmpRuleSet = RuleSet()
     self.tcpRuleList = []
     self.udpRuleList = []
     self.icmpRuleList = []
     self.MAX_NUM_PORTS_ANY = maxNumPortsAny
     self.connectionChecking = connectionChecking
     self.ddosDetection = ddosDetection
     self.saveElements = portscanChecking or printElements
     self.PFLOG_DUMP = 117
     self.innerNetworks = innerNetworks
Пример #18
0
    def __init__(self, ruleSet, proto, style, numChecksP, numChecksIP, \
                 numAnyP, numAnyIP, distanceRange, slashSize, ipsPerSlash, \
                 numPortsPortscan, numIPsPortscan):

        RuleGenerator.__init__(self, ruleSet, proto, style, numChecksP, numChecksIP, \
                               numAnyP, numAnyIP, distanceRange, \
                               slashSize, ipsPerSlash)

        self.MAX_NUM_PORTS_PORTSCAN = numPortsPortscan
        self.MAX_NUM_IPS_PORTSCAN = numIPsPortscan
        self.MAX_DIST_RANGE_SCAN = 65535
        self.portscanSet = RuleSet()
Пример #19
0
    def createRuleSet(self, name):

        logging.info("Creating RuleSet: " + name)

        if (name is None or name == ""):
            raise ValueError("RuleSet name cannot be none or empty")

        rs = RuleSet(name)
        self.ruleSets[name] = rs

        logging.info("Created RuleSet: " + name)

        return rs
Пример #20
0
    def test_ab_ac(self):
        rs = RuleSet()
        rs.addDep("a", "b")
        rs.addDep("a", "c")
        rs.addConflict("b", "d")
        rs.addConflict("b", "e")
        self.assertTrue(rs.isCoherent(), "rs.isCoherent failed")

        opts = Options(rs)
        opts.toggle("d")
        opts.toggle("e")
        opts.toggle("a")
        self.assertSetEqual(
            opts.selection(),
            set(["a", "c", "b"]),
            "toggle expected (a, c, b) got %s" % opts.selection(),
        )
Пример #21
0
    def detectViolations(self):
        if self.innerServicesList != None:
            self.innerServicesFiltered.extend(self._filterRules(self.tcpRules, self.innerServicesList, "tcp", ["in",]))
            self.innerServicesFiltered.extend(self._filterRules(self.udpRules, self.innerServicesList, "udp", ["in",]))
            self.innerServicesFiltered.extend(self._filterRules(self.icmpRules, self.innerServicesList, "icmp", ["in",]))
        if self.outerServicesList != None:
           self.outerServicesFiltered.extend(self._filterRules(self.tcpRules, self.outerServicesList, "tcp", ["out",]))
           self.outerServicesFiltered.extend(self._filterRules(self.udpRules, self.outerServicesList, "udp", ["out",]))
           self.outerServicesFiltered.extend(self._filterRules(self.icmpRules, self.outerServicesList, "icmp", ["out",]))
        if self.forbiddenInnerServicesList != None:
           self.forbiddenInnerServicesFiltered.extend(self._filterRules(self.tcpRules, self.forbiddenInnerServicesList, "tcp", ["none-inner", "in"]))
           self.forbiddenInnerServicesFiltered.extend(self._filterRules(self.udpRules, self.forbiddenInnerServicesList, "udp", ["none-inner", "in"]))
           self.forbiddenInnerServicesFiltered.extend(self._filterRules(self.icmpRules, self.forbiddenInnerServicesList, "icmp", ["none-inner", "in"]))
        if self.restrictedNetworksList != None:
           self.restrictedNetworksFiltered.extend(self._filterRules(self.tcpRules, self.restrictedNetworksList, "tcp", ["none-inner", "in"]))
           self.restrictedNetworksFiltered.extend(self._filterRules(self.udpRules, self.restrictedNetworksList, "udp", ["none-inner", "in"]))
           self.restrictedNetworksFiltered.extend(self._filterRules(self.icmpRules, self.restrictedNetworksList, "icmp", ["none-inner", "in"]))

        mergedViolations = RuleSet()
        mergedViolations.extend(self.innerServicesFiltered)
        mergedViolations.extend(self.outerServicesFiltered)
        mergedViolations.extend(self.forbiddenInnerServicesFiltered)
        mergedViolations.extend(self.restrictedNetworksFiltered)
        return mergedViolations    
Пример #22
0
class Node:
    def __init__(self, id, ranges, rules, depth, partitions, manual_partition):
        self.id = id
        self.partitions = list(partitions or [])
        self.manual_partition = manual_partition
        self.ranges = ranges
        self.rules = RuleSet(rules) if isinstance(rules, list) else rules
        self.depth = depth
        self.children = []
        self.action = None
        self.pushup_rules = None
        self.num_rules = len(self.rules)

    def is_partition(self):
        """Returns if node was partitioned."""
        if not self.action:
            return False
        elif self.action[0] == "partition":
            return True
        elif self.action[0] == "cut":
            return False
        else:
            return False

    def match(self, packet):
        if self.is_partition():
            matches = []
            for c in self.children:
                match = c.match(packet)
                if match:
                    matches.append(match)
            if matches:
                matches.sort(key=lambda r: self.rules.index(r))
                return matches[0]
            return None
        elif self.children:
            for n in self.children:
                if n.contains(packet):
                    return n.match(packet)
            return None
        else:
            for r in self.rules:
                if r.matches(packet):
                    return r

    def is_intersect_multi_dimension(self, ranges):
        for i in range(5):
            if ranges[i*2] >= self.ranges[i*2+1] or \
                    ranges[i*2+1] <= self.ranges[i*2]:
                return False
        return True

    def contains(self, packet):
        assert len(packet) == 5, packet
        return self.is_intersect_multi_dimension([
            packet[0] + 0,  # src ip
            packet[0] + 1,
            packet[1] + 0,  # dst ip
            packet[1] + 1,
            packet[2] + 0,  # src port
            packet[2] + 1,
            packet[3] + 0,  # dst port
            packet[3] + 1,
            packet[4] + 0,  # protocol
            packet[4] + 1
        ])

    def is_useless(self):
        if not self.children:
            return False
        return max(len(c.rules) for c in self.children) == len(self.rules)

    def pruned_rules(self):
        return self.rules.prune(self.ranges)

    def get_state(self):
        state = []
        state.extend(to_bits(self.ranges[0], 32))
        state.extend(to_bits(self.ranges[1] - 1, 32))
        state.extend(to_bits(self.ranges[2], 32))
        state.extend(to_bits(self.ranges[3] - 1, 32))
        assert len(state) == 128, len(state)
        state.extend(to_bits(self.ranges[4], 16))
        state.extend(to_bits(self.ranges[5] - 1, 16))
        state.extend(to_bits(self.ranges[6], 16))
        state.extend(to_bits(self.ranges[7] - 1, 16))
        assert len(state) == 192, len(state)
        state.extend(to_bits(self.ranges[8], 8))
        state.extend(to_bits(self.ranges[9] - 1, 8))
        assert len(state) == 208, len(state)

        if self.manual_partition is None:
            # 0, 6 -> 0-64%
            # 6, 7 -> 64-100%
            partition_state = [
                0,
                7,  # [>=min, <max) -- 0%, 2%, 4%, 8%, 16%, 32%, 64%, 100%
                0,
                7,
                0,
                7,
                0,
                7,
                0,
                7,
            ]
            for (smaller, part_dim, part_size) in self.partitions:
                if smaller:
                    partition_state[part_dim * 2 + 1] = min(
                        partition_state[part_dim * 2 + 1], part_size + 1)
                else:
                    partition_state[part_dim * 2] = max(
                        partition_state[part_dim * 2], part_size + 1)
            state.extend(onehot_encode(partition_state, 7))
        else:
            partition_state = [0] * 70
            partition_state[self.manual_partition] = 1
            state.extend(partition_state)
        state.append(self.num_rules)
        return np.array(state)

    def __str__(self):
        result = "ID:%d\tAction:%s\tDepth:%d\tRange:\t%s\nChildren: " % (
            self.id, str(self.action), self.depth, str(self.ranges))
        for child in self.children:
            result += str(child.id) + " "
        result += "\nRules:\n"
        for rule in self.rules:
            result += str(rule) + "\n"
        if self.pushup_rules != None:
            result += "Pushup Rules:\n"
            for rule in self.pushup_rules:
                result += str(rule) + "\n"
        return result
Пример #23
0
class PcapParser():
    """
    PcapParser parses a pcap-file with dpkt.
    Every ip-paket is put into either the tcp or udp or icmp ruleset.
    Rulesets are sets, they contain every item only once.
    Concerning tcp: only full connections are kept (there must be a syn 
    and a fin paket).
    Non-ip-pakets are not concerned. 
    """
    def __init__(self, pcapFile, action, style, direction, maxNumPortsAny, \
                 connectionChecking, portscanChecking, printElements, \
                 innerNetworks=None, ddosDetection=True): 
        self.p = pcapFile
        self.direction = direction 
        self.action = action
        self.style = style
        self.interface = "None"
        self.tcpRuleSet = RuleSet()
        self.udpRuleSet = RuleSet()
        self.icmpRuleSet = RuleSet()
        self.tcpRuleList = []
        self.udpRuleList = []
        self.icmpRuleList = []
        self.MAX_NUM_PORTS_ANY = maxNumPortsAny
        self.connectionChecking = connectionChecking
        self.ddosDetection = ddosDetection
        self.saveElements = portscanChecking or printElements
        self.PFLOG_DUMP = 117
        self.innerNetworks = innerNetworks
    
    def parsePcapFile(self):
        """Parse a pcap file"""
        for ts, buf in self.p:
            self._packetHandler(buf, ts)
        if self.connectionChecking:
            self._checkTcpForConns()
        return self.tcpRuleSet, self.udpRuleSet, self.icmpRuleSet, \
               self.tcpRuleList, self.udpRuleList, self.icmpRuleList
        
    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

    def _checkTcpForConns(self):
        """Checks tcp-set for connections.""" 
        print "Checking for Connections"
        tcpRuleSetConnsOnly = RuleSet()
        if self.p.linktype == self.PFLOG_DUMP:
            tcpRuleSetConnsOnly = self.tcpRuleSet
        else:
            for r in self.tcpRuleSet:
                connection = False
                for r2 in self.tcpRuleSet:
                    if (r == r2 and (r.flag[0]=="SYN") and (r2.flag[0]=="FIN")):
                        connection = True
                        break
                if connection:
                    tcpRuleSetConnsOnly.insert(r)

        self.tcpRuleSet = tcpRuleSetConnsOnly 
Пример #24
0
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)
Пример #25
0
 def test_deep_deps(self):
     rs = RuleSet()
     rs.addDep("a", "b")
     rs.addDep("b", "c")
     rs.addDep("c", "d")
     rs.addDep("d", "e")
     rs.addDep("a", "f")
     rs.addConflict("e", "f")
     self.assertFalse(rs.isCoherent(), "rs.isCoherent failed")
Пример #26
0
class PortscanDetector(RuleGenerator):
    """
    PortscanDetector takes a ruleSet and tries to find portscans.
    """
    
    def __init__(self, ruleSet, proto, style, numChecksP, numChecksIP, \
                 numAnyP, numAnyIP, distanceRange, slashSize, ipsPerSlash, \
                 numPortsPortscan, numIPsPortscan):

        RuleGenerator.__init__(self, ruleSet, proto, style, numChecksP, numChecksIP, \
                               numAnyP, numAnyIP, distanceRange, \
                               slashSize, ipsPerSlash)

        self.MAX_NUM_PORTS_PORTSCAN = numPortsPortscan
        self.MAX_NUM_IPS_PORTSCAN = numIPsPortscan
        self.MAX_DIST_RANGE_SCAN = 65535
        self.portscanSet = RuleSet()

    def detectPortscans(self):
        self.generateRules()
        self._checkForPortscans()
        self.portscanSet.checkTables(self.NUM_CHECKS_P, self.MAX_DIST_RANGE_SCAN,\
                                     self.NUM_ANY_P, self.NUM_CHECKS_IP, \
                                     self.NUM_EXP, self.NUM_ANY_IP, \
                                     self.SLASH_SIZE, self.MIN_IPS_PER_SLASH)

    def _checkForPortscans(self):
        ruleList = self.ruleSet.values()
        for r in ruleList:
            if (len(r.dPorts.elements) > self.MAX_NUM_PORTS_PORTSCAN) and \
               (len(r.sIPs) == 1) or \
               (len(r.dIPs.elements) > self.MAX_NUM_IPS_PORTSCAN and \
               len(r.sIPs) == 1) and (len(r.dPorts.elements) == 1)\
               and not r.direction == "out":
                psr = PortscanRule(r.direction, r.sIPs, r.sPorts, r.dIPs, \
                                   r.dPorts, r.proto, r.interface, "block", \
                                   self.style, r.timeStamp, r.flag)
                self.portscanSet.insert(psr)
    
    def removeRulesContainingPortscanners(self, ruleSet):
        for r in ruleSet.values():
            for pr in self.portscanSet.values():
                for e in pr.sIPs.elements.values():   
                    if r.sIPs.values()[0] == e \
                       or r.dIPs.values()[0] == e:
                       try:
                           ruleSet.remove(r)
                       except KeyError:
                           #Is already removed
                           pass
                       break

    def generateRules(self):
        self.generateTables()
        del self.sortingDict
        del self.tablesDict

    def printRules(self):
        l = len(self.portscanSet)
        if l > 0:
            if l == 1:
                print "%d rule which results from traffic which looks like a portscan\n" % l
            else:
                print "%d rules which result from traffic which looks like portscans\n" % l
            print self.portscanSet 

    def generateTables(self):
        slashSizeBackup = self.SLASH_SIZE
        self.SLASH_SIZE = 32
        if not self.proto == "icmp":
            # 2. sport is the varying part
            sPort = True
            self._portsVary(sPort)

            # 3. dport is the varying part
            sPort = False
            self._portsVary(sPort)

        # 4. dIP is the varying part
        sIP = False
        self._ipsVary(sIP)
        self.SLASH_SIZE = slashSizeBackup
Пример #27
0
class ViolationDetector():
    """
    ViolationDetector takes a ruleSet and tries to find policy violations.
    """
    
    def __init__(self, tcpRules, udpRules, icmpRules, innerServicesList, outerServicesList, \
                 forbiddenInnerServicesList, restrictedNetworks):

        self.tcpRules = tcpRules
        self.udpRules = udpRules
        self.icmpRules = icmpRules
        self.innerServicesList = self._parseServiceList(innerServicesList)
        self.outerServicesList = self._parseServiceList(outerServicesList)
        self.forbiddenInnerServicesList = self._parseServiceList(forbiddenInnerServicesList)
        self.restrictedNetworksList = self._parseNetworkList(restrictedNetworks)
        self.filteredRules = RuleSet()
        self.innerServicesFiltered = RuleSet()
        self.outerServicesFiltered = RuleSet()
        self.forbiddenInnerServicesFiltered = RuleSet()
        self.restrictedNetworksFiltered = RuleSet()

    def _parseNetworkList(self, networkList):
        if networkList != "None":
            networkList = networkList.split(",")
            tmpList = []
            for n in networkList:
                tmp = n.split("/")
                tmp[0] = IPv4Network(tmp[0]+"/"+tmp[1])
                tmp[1] = "any"
                tmp.append("any")
                tmpList.append(tmp)
            return tmpList
        return None

    def _parseServiceList(self, serviceList):
        if serviceList != "None":
            servicesList = serviceList.split(",")
            tmpList = []
            for s in servicesList:
                tmp = s.split(":")
                tmp[0] = ("any" if tmp[0]=="any" else IPv4Address(tmp[0]))
                tmp[1] = ("any" if tmp[1]=="any" else Port(int(tmp[1])))
                tmpList.append(tmp)
            return tmpList
        return None

    def printViolations(self):
        if len(self.innerServicesFiltered) > 0:
            print "Violations detected for services, which should only be accessed by ips from the inner networks:"
            print self.innerServicesFiltered
        if len(self.outerServicesFiltered) > 0:
            print "Violations detected for services, which should not be accessed by ips from the inner networks:"
            print self.outerServicesFiltered
        if len(self.forbiddenInnerServicesFiltered) > 0:
            print "Violations detected for services, which should not be used in the inner networks:"
            print self.forbiddenInnerServicesFiltered
        if len(self.restrictedNetworksFiltered) > 0:
            print "Violations detected for networks, which should have no incoming traffic:"
            print self.restrictedNetworksFiltered

    def detectViolations(self):
        if self.innerServicesList != None:
            self.innerServicesFiltered.extend(self._filterRules(self.tcpRules, self.innerServicesList, "tcp", ["in",]))
            self.innerServicesFiltered.extend(self._filterRules(self.udpRules, self.innerServicesList, "udp", ["in",]))
            self.innerServicesFiltered.extend(self._filterRules(self.icmpRules, self.innerServicesList, "icmp", ["in",]))
        if self.outerServicesList != None:
           self.outerServicesFiltered.extend(self._filterRules(self.tcpRules, self.outerServicesList, "tcp", ["out",]))
           self.outerServicesFiltered.extend(self._filterRules(self.udpRules, self.outerServicesList, "udp", ["out",]))
           self.outerServicesFiltered.extend(self._filterRules(self.icmpRules, self.outerServicesList, "icmp", ["out",]))
        if self.forbiddenInnerServicesList != None:
           self.forbiddenInnerServicesFiltered.extend(self._filterRules(self.tcpRules, self.forbiddenInnerServicesList, "tcp", ["none-inner", "in"]))
           self.forbiddenInnerServicesFiltered.extend(self._filterRules(self.udpRules, self.forbiddenInnerServicesList, "udp", ["none-inner", "in"]))
           self.forbiddenInnerServicesFiltered.extend(self._filterRules(self.icmpRules, self.forbiddenInnerServicesList, "icmp", ["none-inner", "in"]))
        if self.restrictedNetworksList != None:
           self.restrictedNetworksFiltered.extend(self._filterRules(self.tcpRules, self.restrictedNetworksList, "tcp", ["none-inner", "in"]))
           self.restrictedNetworksFiltered.extend(self._filterRules(self.udpRules, self.restrictedNetworksList, "udp", ["none-inner", "in"]))
           self.restrictedNetworksFiltered.extend(self._filterRules(self.icmpRules, self.restrictedNetworksList, "icmp", ["none-inner", "in"]))

        mergedViolations = RuleSet()
        mergedViolations.extend(self.innerServicesFiltered)
        mergedViolations.extend(self.outerServicesFiltered)
        mergedViolations.extend(self.forbiddenInnerServicesFiltered)
        mergedViolations.extend(self.restrictedNetworksFiltered)
        return mergedViolations    

    def _filterRules(self, rules, checkList, proto, direction):        
        filteredRules = RuleSet()
        for s in checkList:
            if s[2] == proto or s[2] == "any":
                for r in rules.values():
                    for d in direction:
                        if r.direction == d \
                           and (s[0] in r.dIPs or s[0] == "any") \
                           and (s[1] in r.dPorts or s[1] == "any"):
                            rules.remove(r)
                            filteredRules.insert(r)
        return filteredRules 
Пример #28
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
Пример #29
0
    def test_exclusive_ab_bc_ca_de(self):
        rs = RuleSet()
        rs.addDep("a", "b")
        rs.addDep("b", "c")
        rs.addDep("c", "a")
        rs.addDep("d", "e")
        rs.addConflict("c", "e")
        self.assertTrue(rs.isCoherent(), "rs.isCoherent failed")

        opts = Options(rs)

        opts.toggle("a")
        self.assertSetEqual(
            opts.selection(),
            set(["a", "c", "b"]),
            "toggle expected (a, c, b) got %s" % opts.selection(),
        )

        rs.addDep("f", "f")
        opts.toggle("f")

        self.assertSetEqual(
            opts.selection(),
            set(["a", "c", "b", "f"]),
            "toggle expected (a, c, b, f) got %s" % opts.selection(),
        )

        opts.toggle("e")
        self.assertSetEqual(
            opts.selection(),
            set(["e", "f"]),
            "toggle expected (e, f) got %s" % opts.selection(),
        )

        opts.toggle("b")
        self.assertSetEqual(
            opts.selection(),
            set(["a", "c", "b", "f"]),
            "toggle expected (a, c, b, f) got %s" % opts.selection(),
        )

        rs.addDep("b", "g")
        opts.toggle("g")
        opts.toggle("b")
        self.assertSetEqual(
            opts.selection(),
            set(["g", "f"]),
            "toggle expected (g, f) got %s" % opts.selection(),
        )