Пример #1
0
    def add_client(self, event):
        edata = event.data

        ip = edata.get('ip')

        client = self.data.clients.get(ip)
        if not client:
            client = utils.Data()
            client.ip = ip
            client.ip_country = self.geoip_country(ip)
            client.agents = {}
            client.session_count = 0
            client.environment = {}
            self.data.clients[ip] = client

        client.email = edata.get('email')

        env = edata.get('environment')
        if env:
            client.environment.update(env)

        user_agent = self.get_user_agent(edata)
        if not user_agent:
            return

        os, browser = parse_agent(user_agent)

        agent = client.agents.get(user_agent)
        if not agent:
            agent = utils.Data()
            agent.name = user_agent
            agent._browser = browser
            agent.browser = ' '.join(browser)
            agent._os = os
            agent.os = ' '.join(os)
            agent.plugins = {}
            client.agents[user_agent] = agent

        recon = edata.get('recon')
        if not recon:
            return

        plugins = recon.get('plugins')
        if plugins:
            plugins.pop('AGENT', None)
            agent.language = plugins.pop('language', None)
            agent.cpu = plugins.pop('CPU', None)
            agent.platform = plugins.pop('platform', None)

            plugins = utils.dict_fix_unicode(plugins)
            agent.plugins.update(plugins)
Пример #2
0
 def process_event(self, event):
     if event.module != 'canvas':
         return
     
     ename = event.name
     if ename == 'new host':
         ip = event.data['ip']
         self.add_host(ip, event)
     elif ename == 'new node':
         node = utils.Data(event.data)
         node.exploit = utils.Data(node.exploit) if node.exploit else None
         node.time = event.time
         node.session_id = event.session_id
         self.data._nodes.append(node)
     elif ename.startswith('exploit'):
         self.add_exploit_event(event)
Пример #3
0
    def add_session(self, event):
        edata = event.data

        sid = edata.get('sid')
        if not sid:
            return

        session = self.data.sessions.get(sid)
        if session:
            return

        session = utils.Data()
        session.sid = sid
        self.data.sessions[sid] = session

        session.email = edata.get('email')
        session.ip = edata.get('ip')
        session.time = utils.format_datetime(event.time)
        session.agent = edata.get('user agent')

        ip = edata.get('ip')
        client = self.data.clients.get(ip)
        client.session_count += 1

        stats = self.data.stats
        stats.session_count += 1
Пример #4
0
 def collect(self, data_file):
     # set up the data structure
     data = self.data
     
     data.hosts = {}
     data._nodes = []
     data._exploits = {}
     data.attacks = []
     data.exploits = {}
     
     stats = data.stats = utils.Data()
     stats.hosts_discovered = 0
     stats.hosts_attacked = set()
     stats.exploits_attempted = collections.defaultdict(int)
     stats.hosts_compromised = set()
     stats.successful_exploits = collections.defaultdict(int)
     stats.timeline = collections.defaultdict(lambda: [0, 0])
     
     # process the pickle file
     self.process_report_pickle(data_file)
     
     # add attacks from collected data
     self.add_attacks()
     
     # calc some stats
     stats.hosts_attacked = len(stats.hosts_attacked)
     stats.hosts_compromised = len(stats.hosts_compromised)
     stats.total_exploits_attempted = sum(stats.exploits_attempted.values())
     stats.total_exploits_successful = sum(stats.successful_exploits.values())
     stats.exploits_attempted = len(stats.exploits_attempted)
     stats.exploits_successful = len(stats.successful_exploits)
     
     return self.data
Пример #5
0
    def __init__(self):
        self.data = utils.Data()

        self._geoip = None
        geoip_path = utils.get_canvas_path('gui', 'WorldMap',
                                           'GeoLiteCity.dat')
        if os.path.exists(geoip_path):
            self._geoip = pygeoip.GeoIP(geoip_path, pygeoip.MMAP_CACHE)
Пример #6
0
    def add_exploit_to_data(self, name):
        """Add exploit details to a *Data* object.
        
        Returns a new or existing *Data* object for the exploit.
        """
        import canvasengine

        # see if it has already been added
        exploit = self.data.exploits.get(name)
        if exploit:
            return exploit

        # helper func
        def attach_docs(exploit, module):
            def process_value(value):
                if isinstance(value, list):
                    return '\n'.join([process_value(v) for v in value])
                elif isinstance(value, bool):
                    return 'Yes' if value else 'No'
                else:
                    return value

            exploit.title = module.NAME
            exploit.version = getattr(module, 'VERSION', '')
            exploit.description = getattr(module, 'DESCRIPTION',
                                          'No description available.')
            exploit.cve = self.get_exploit_cve(module)

            p = getattr(module, 'PROPERTY', {})
            p.update(getattr(module, 'DOCUMENTATION', {}))

            props = exploit.properties = {}
            for k, v in p.iteritems():
                lk = k.lower()
                v = str(process_value(v)).strip()
                if not v:
                    continue
                elif lk == 'notes':
                    continue
                elif lk in ['cve', 'cve name']:
                    k = 'CVE'
                    v = exploit.cve
                elif re.search('cve|cvss|mfsa|msadv|osvdb', lk):
                    k = k.upper()
                else:
                    k = k.title()
                props[k] = v

        # collect the exploit details
        exploit = utils.Data()
        self.data.exploits[name] = exploit

        # get exploit description from canvas
        mod = canvasengine.getModule(name)
        exploit.name = name
        attach_docs(exploit, mod)

        return exploit
Пример #7
0
 def add_host(self, ip, event=None):
     data = self.data
     host = data.hosts.get(ip)
     if not host:
         host = utils.Data(event.data if event else {})
         host.ip = ip
         host.attacks = []
         host.commands = []
         data.hosts[ip] = host
         data.stats.hosts_discovered += 1
     return host
Пример #8
0
 def add_exploit_event(self, event):
     edata = event.data
     key = (event.session_id, edata['id'], edata['name'])
     exploit = self.data._exploits.get(key)
     if not exploit:
         exploit = utils.Data(edata)
         self.data._exploits[key] = exploit
     else:
         exploit.update(edata)
     
     start_time = event.time if event.name == 'exploit started' else None
     exploit.started = start_time
     
     # prefer finished, but take whichever is available
     if event.name == 'exploit finished':
         exploit.ended = event.time
     elif event.name == 'exploit returned':
         exploit.ended = event.time
Пример #9
0
    def add_attacks(self, event, successful=False):
        edata = event.data

        names = edata.get('attacks')
        if not names:
            name = edata.get('attack')
            if name:
                names = [name]
        sid = edata.get('sid')
        if not (names and sid):
            return

        data = self.data
        session = data.sessions[sid]

        for name in names:
            attack = data.attacks.get((name, sid))
            if not attack:
                attack = utils.Data()
                data.attacks[(name, sid)] = attack

            attack.name = name
            attack.sid = sid
            attack.successful = successful

            exploit = self.add_exploit_to_data(name)
            attack.exploit = exploit

            attack.agent = session.agent
            attack.time = utils.format_datetime(event.time)
            # raw time for sorting
            attack._time = event.time
            attack.ip = edata.get('ip')
            attack.email = edata.get('email')

            stats = data.stats
            stats.attacks[name] += 1
            if successful:
                stats.exploited_clients[(attack.ip, attack.agent)] += 1
                stats.successful_attacks[name] += 1
Пример #10
0
    def collect(self, data_file):
        data = self.data

        # set up the data structure
        data.sessions = {}
        data.clients = {}
        data.attacks = {}
        data.exploits = {}

        data.stats = stats = utils.Data()
        stats.session_count = 0
        stats.recon_sessions = collections.defaultdict(int)
        stats.attack_sessions = collections.defaultdict(int)

        stats.exploited_clients = collections.defaultdict(int)

        stats.attacks = collections.defaultdict(int)
        stats.successful_attacks = collections.defaultdict(int)

        # process the pickle file
        self.process_report_pickle(data_file)

        # calc some stats
        stats.client_count = len(data.clients)
        stats.recon_session_count = len(stats.recon_sessions)
        stats.attack_session_count = len(stats.attack_sessions)
        stats.exploited_client_count = len(stats.exploited_clients)

        # plugins
        plugins = stats.plugins = collections.defaultdict(int)
        for client in data.clients.itervalues():
            for agent in client.agents.itervalues():
                for name, version in agent.plugins.iteritems():
                    plugins[(name, version)] += 1

        return self.data
Пример #11
0
 def add_attacks(self):
     data = self.data
     
     seen = set()
     
     # use nodes as a more reliable way to find successful attacks
     for node in data._nodes:
         attack = utils.Data()
         attack.target = node.ip
         attack.successful = True
         attack.node_type = node.type
         attack.node_time = utils.format_datetime(node.time)
         # raw time for sorting
         attack.raw_node_time = node.time
         
         key = None
         if node.exploit:
             attack.name = node.exploit['name']
             key = (node.session_id, node.exploit['id'], attack.name)
             
             exploit = self.add_exploit_to_data(attack.name)
             if exploit:
                 attack.title = exploit.title
                 attack.cve = exploit.cve
         else:
             attack.name = '<unknown>'
             attack.title = 'Unknown Exploit'
         
         event_data = data._exploits.get(key)
         if event_data:
             seen.add(key)
             attack.logdata = event_data.get('logdata', [])
         else:
             attack.logdata = []
         
         self._set_times(attack, event_data)
         
         self.add_attack(attack)
     
     # now check any left over exploit events
     for key, event_data in data._exploits.iteritems():
         if key in seen:
             continue
         
         name = key[2]
         exploit = self.add_exploit_to_data(name)
         exploit_type = exploit.properties['Type'].lower()
         if exploit_type == 'commands':
             continue
         elif exploit_type != 'exploit':
             continue
         
         attack = utils.Data()
         attack.name = name
         attack.target = event_data.get('target')
         attack.successful = event_data.get('success')
         attack.title = exploit.title
         attack.cve = exploit.cve
         attack.logdata = event_data.get('logdata', [])
         
         self._set_times(attack, event_data)
         
         self.add_attack(attack)