예제 #1
0
 def register_sensitivity(bpcls, pkttype):
     "Register that class 'cls' wants to see packet of type 'pkttype'"
     if pkttype not in BestPractices.wantedpackets:
         BestPractices.wantedpackets.append(pkttype)
         Drone.add_json_processor(BestPractices)
     if pkttype not in BestPractices.evaluators:
         BestPractices.evaluators[pkttype] = []
     if bpcls not in BestPractices.evaluators[pkttype]:
         BestPractices.evaluators[pkttype].append(bpcls)
예제 #2
0
 def register_sensitivity(bpcls, pkttype):
     "Register that class 'bpcls' wants to see packet of type 'pkttype'"
     #print >> sys.stderr, '%s is looking for packet of type %s' % (bpcls, pkttype)
     if pkttype not in BestPractices.wantedpackets:
         BestPractices.wantedpackets.append(pkttype)
         Drone.add_json_processor(BestPractices)
     if pkttype not in BestPractices.eval_classes:
         BestPractices.eval_classes[pkttype] = []
     if bpcls not in BestPractices.eval_classes[pkttype]:
         BestPractices.eval_classes[pkttype].append(bpcls)
예제 #3
0
 def decorator(cls):
     '''Register our class with the packet types given to 'register' above.
     Return value: Class that we registered.
     '''
     for pkttype in pkttypes:
         if pkttype not in BestPractices.wantedpackets:
             BestPractices.wantedpackets.append(pkttype)
             Drone.add_json_processor(BestPractices)
         if pkttype not in BestPractices.evaluators:
             BestPractices.evaluators[pkttype] = []
         if cls not in BestPractices.evaluators[pkttype]:
             BestPractices.evaluators[pkttype].append(cls)
     return cls
예제 #4
0
 def decorator(cls):
     '''Register our class with the packet types given to 'register' above.
     Return value: Class that we registered.
     '''
     for pkttype in pkttypes:
         if pkttype not in BestPractices.wantedpackets:
             BestPractices.wantedpackets.append(pkttype)
             Drone.add_json_processor(BestPractices)
         if pkttype not in BestPractices.evaluators:
             BestPractices.evaluators[pkttype] = []
         if cls not in BestPractices.evaluators[pkttype]:
             BestPractices.evaluators[pkttype].append(cls)
     return cls
예제 #5
0
 def log_rule_results(self, results, drone, _srcaddr, discoveryobj, discovertype, rulesobj):
     '''Log the results of this set of rule evaluations'''
     status_name = Drone.bp_discoverytype_result_attrname(discovertype)
     if hasattr(drone, status_name):
         oldstats = pyConfigContext(getattr(drone, status_name))
     else:
         oldstats = {'pass': [], 'fail': [], 'ignore': [], 'NA': [], 'score': 0.0}
     for stat in ('pass', 'fail', 'ignore', 'NA'):
         logmethod = self.log.info if stat == 'pass' else self.log.warning
         for ruleid in results[stat]:
             oldstat = None
             for statold in ('pass', 'fail', 'ignore', 'NA'):
                 if ruleid in oldstats[statold]:
                     oldstat = statold
                     break
             if oldstat == stat or stat == 'NA':
                 # No change
                 continue
             BestPractices.send_rule_event(oldstat, stat, drone, ruleid, rulesobj)
             thisrule = rulesobj[ruleid]
             rulecategory = thisrule['category']
             logmethod('%s %sED %s rule %s: %s [%s]' % (drone,
                              stat.upper(), rulecategory, ruleid,
                              self.url(drone, ruleid, rulesobj[ruleid]),
                              thisrule['rule']))
     self.compute_score_updates(discoveryobj, drone, rulesobj, results, oldstats)
     setattr(drone, status_name, str(results))
예제 #6
0
    def auditadrone(self, droneid):
        designation = dronedesignation(droneid)
        droneip = droneipaddress(droneid)
        droneipstr = str(droneip)
        # Did the drone get put in the Drone table?
        drone = Drone.find(designation)
        self.assertTrue(drone is not None)
        # Did the drone's list of addresses get updated?
        ipnodes = drone.get_owned_ips()
        ipnodes = [ip for ip in ipnodes]
        self.assertEqual(len(ipnodes), 1)
        ipnode = ipnodes[0]
        ipnodeaddr = pyNetAddr(ipnode.ipaddr)
        json = drone.JSON_netconfig
        jsobj = pyConfigContext(init=json)
        jsdata = jsobj['data']
        eth0obj = jsdata['eth0']
        eth0addrcidr = eth0obj['ipaddrs'].keys()[0]
        eth0addrstr, cidrmask = eth0addrcidr.split('/')
        eth0addr = pyNetAddr(eth0addrstr)
        self.assertTrue(eth0addr == ipnodeaddr)

        # Do we know that eth0 is the default gateway?
        self.assertEqual(eth0obj['default_gw'], True)

        # the JSON should have exactly 5 top-level keys
        self.assertEqual(len(jsobj.keys()), 5)
        # Was the JSON host name saved away correctly?
        self.assertEqual(jsobj['host'], designation)
예제 #7
0
    def auditadrone(self, droneid):
        designation = dronedesignation(droneid)
        droneip = droneipaddress(droneid)
        droneipstr = str(droneip)
        # Did the drone get put in the Drone table?
        drone=Drone.find(designation)
        self.assertTrue(drone is not None)
        # Did the drone's list of addresses get updated?
        ipnodes = drone.get_owned_ips()
        ipnodes = [ip for ip in ipnodes]
        self.assertEqual(len(ipnodes), 1)
        ipnode = ipnodes[0]
        ipnodeaddr = pyNetAddr(ipnode.ipaddr)
        json = drone['netconfig']
        jsobj = pyConfigContext(init=json)
        jsdata = jsobj['data']
        eth0obj = jsdata['eth0']
        eth0addrcidr = eth0obj['ipaddrs'].keys()[0]
        eth0addrstr, cidrmask = eth0addrcidr.split('/')
        eth0addr = pyNetAddr(eth0addrstr)
        self.assertTrue(eth0addr == ipnodeaddr)

        # Do we know that eth0 is the default gateway?
        self.assertEqual(eth0obj['default_gw'], True)

        # the JSON should have exactly 6 top-level keys
        self.assertEqual(len(jsobj.keys()), 6)
        # Was the JSON host name saved away correctly?
        self.assertEqual(jsobj['host'], designation)
        assert drone.get_active_nic_count() == 1
예제 #8
0
 def maintest():
     'test main program'
     from cmainit import CMAinit
     from droneinfo import Drone
     from systemnode import SystemNode
     print >> sys.stderr, 'Starting'
     CMAinit(None, cleanoutdb=True, debug=True)
     if CMAdb.store.transaction_pending:
         print 'Transaction pending in:', CMAdb.store
         print 'Results:', CMAdb.store.commit()
     print ProcessNode.__meta_labels__()
     print SystemNode.__meta_labels__()
     print Drone.__meta_labels__()
     print 'keys:', Drone.__meta_keyattrs__()
     print >> sys.stderr, 'Init done'
     return 0
예제 #9
0
 def maintest():
     'test main program'
     from cmainit import CMAinit
     from droneinfo import Drone
     from systemnode import SystemNode
     print >> sys.stderr, 'Starting'
     CMAinit(None, cleanoutdb=True, debug=True)
     if CMAdb.store.transaction_pending:
         print 'Transaction pending in:', CMAdb.store
         print 'Results:', CMAdb.store.commit()
     print ProcessNode.__meta_labels__()
     print SystemNode.__meta_labels__()
     print Drone.__meta_labels__()
     print 'keys:', Drone.__meta_keyattrs__()
     print >> sys.stderr, 'Init done'
     return 0
예제 #10
0
    def compute_score_updates(discovery_json, drone, rulesobj, newstats, oldstats):
        '''We compute the score updates for the rules and results we've been given.
        The drone is a Drone (or host), the 'rulesobj' contains the rules and their categories.
        Statuses contains the results of evaluating the rules.
        Our job is to compute the scores for each of the categories of rules in the
        statuses, issue events for score changes, and update the category scores in the host.

        We're storing the successes, failures, etc, for this discovery object for this drone.

        Note that this can fail if we change our algorithm - because we don't know the values
            the old algorithm gave us, only what the current algorithm gives us on the old results.

        @TODO: We eventually want to update the scores for the domain to which this drone
        belongs.


        '''
        _, oldcatscores, _ = BestPractices.compute_scores(drone, rulesobj, oldstats)
        _, newcatscores, _ = BestPractices.compute_scores(drone, rulesobj, newstats)
        keys = set(newcatscores)
        keys |= set(oldcatscores)
        # I have no idea why "keys = set(newcatscores) | set(oldcatscores)" did not work...
        # It worked fine in an interactive python session...

        diffs = {}

        for category in keys:
            newscore = newcatscores.get(category, 0.0)
            oldscore = oldcatscores.get(category, 0.0)
            catattr = Drone.bp_category_score_attrname(category)
            # I just compare two floating point numbers without a lot of formality.
            # This should be OK because they're both computed by the same algorithm
            # And at this level algorithms mostly produce integers
            # This is not a numerical analysis problem ;-)
            if newscore != oldscore:
                diff = newscore - oldscore
                if category in diffs:
                    diffs[category] += diff
                else:
                    diffs[category] = diff
                eventtype = AssimEvent.OBJWARN if newscore > oldscore else AssimEvent.OBJUNWARN
                extrainfo = {'category':    category,
                             'oldscore': str(oldscore),
                             'newscore': str(newscore),
                             'discovery_type': discovery_json['discovertype'],
                             'discovery_description': discovery_json['description']
                             }
                # POTENTIALCONCURRENCY
                # As long as no one else is updating this attribute for this drone
                # we shouldn't have concurrency problems.
                oldval = getattr(drone, catattr) if hasattr(drone, catattr) else 0.0
                setattr(drone, catattr, oldval + diff)
                print >> sys.stderr, 'Setting %s.%s to %d' % (drone, catattr, oldval+diff)
                AssimEvent(drone, eventtype, extrainfo=extrainfo)
        return newcatscores, diffs
def grab_category_scores(store, categories=None, debug=False):
    '''Program to create and return some python Dicts with security scores and totals by category
    and totals by drone/category
    Categories is None or a list of desired categories.
    '''
    cypher = '''START drone=node:Drone('*:*') RETURN drone'''

    BestPractices(CMAdb.io.config, CMAdb.io, store, CMAdb.log, debug=debug)
    dtype_totals = {} # scores organized by (category, discovery-type)
    drone_totals = {} # scores organized by (category, discovery-type, drone)
    rule_totals = {} # scores organized by (category, discovery-type, rule)

    for drone in store.load_cypher_nodes(cypher, Drone):
        designation = drone.designation
        discoverytypes = drone.bp_discoverytypes_list()
        for dtype in discoverytypes:
            dattr = Drone.bp_discoverytype_result_attrname(dtype)
            statuses = getattr(drone, dattr)
            for rule_obj in BestPractices.eval_objects[dtype]:
                rulesobj = rule_obj.fetch_rules(drone, None, dtype)
                _, scores, rulescores = BestPractices.compute_scores(drone, rulesobj, statuses)
                for category in scores:
                    if category not in categories and categories:
                        continue
                    # Accumulate scores by (category, discovery_type)
                    setup_dict2(dtype_totals, category, dtype)
                    dtype_totals[category][dtype] += scores[category]
                    # Accumulate scores by (category, discovery_type, drone)
                    setup_dict3(drone_totals, category, dtype, designation)
                    drone_totals[category][dtype][designation] += scores[category]
                    # Accumulate scores by (category, discovery_type, ruleid)
                    for ruleid in rulescores[category]:
                        setup_dict3(rule_totals, category, dtype, ruleid)
                        rule_totals[category][dtype][ruleid] += rulescores[category][ruleid]

    return dtype_totals, drone_totals, rule_totals
예제 #12
0
        'Iterate over self.keys() - giving the names of all our *top level* attributes.'
        for key in self.keys():
            yield key

    def __contains__(self, key):
        return key in self.map()

    def __len__(self):
        return len(self.map())

    @staticmethod
    def __meta_keyattrs__():
        'Return our key attributes in order of significance'
        return ['jhash']


if __name__ == '__main__':
    from cmainit import CMAinit
    print >> sys.stderr, 'Starting'
    CMAinit(None, cleanoutdb=True, debug=True)
    if CMAdb.store.transaction_pending:
        print 'Transaction pending in:', CMAdb.store
        print 'Results:', CMAdb.store.commit()
    print CMAclass.__meta_labels__()
    print ProcessNode.__meta_labels__()
    print SystemNode.__meta_labels__()
    from droneinfo import Drone
    print Drone.__meta_labels__()
    print 'keys:', Drone.__meta_keyattrs__()
    print >> sys.stderr, 'Init done'
예제 #13
0
        'Delete a role from our GraphNode'
        if isinstance(roles, tuple) or isinstance(roles, list):
            for role in roles:
                self.delrole(role)
            return self.roles
        assert isinstance(roles, str) or isinstance(roles, unicode)
        if roles in self.roles:
            self.roles.remove(roles)
        return self.roles

    @staticmethod
    def __meta_keyattrs__():
        'Return our key attributes in order of significance'
        return ['processname', 'domain']

if __name__ == '__main__':
    from cmainit import CMAinit
    from cmadb import CMAdb
    print >> sys.stderr, 'Starting'
    CMAinit(None, cleanoutdb=True, debug=True)
    if CMAdb.store.transaction_pending:
        print 'Transaction pending in:', CMAdb.store
        print 'Results:', CMAdb.store.commit()
    print CMAclass.__meta_labels__()
    print ProcessNode.__meta_labels__()
    print SystemNode.__meta_labels__()
    from droneinfo import Drone
    print Drone.__meta_labels__()
    print 'keys:', Drone.__meta_keyattrs__()
    print >> sys.stderr, 'Init done'
            yield key

    def __contains__(self, key):
        return key in self.map()

    def __len__(self):
        return len(self.map())

    @staticmethod
    def __meta_keyattrs__():
        "Return our key attributes in order of significance"
        return ["jhash"]


if __name__ == "__main__":
    from cmainit import CMAinit

    print >> sys.stderr, "Starting"
    CMAinit(None, cleanoutdb=True, debug=True)
    if CMAdb.store.transaction_pending:
        print "Transaction pending in:", CMAdb.store
        print "Results:", CMAdb.store.commit()
    print CMAclass.__meta_labels__()
    print ProcessNode.__meta_labels__()
    print SystemNode.__meta_labels__()
    from droneinfo import Drone

    print Drone.__meta_labels__()
    print "keys:", Drone.__meta_keyattrs__()
    print >> sys.stderr, "Init done"