Esempio n. 1
0
class SnifferEngine(object):
    """docstring for SnifferEngine"""

    def __init__(self, setup):
        super(SnifferEngine, self).__init__()
        self.setup = setup
        sys.stderr.write("[+] Starting sniffer...\n")

        # check if sniffer directory exists
        if not os.path.isdir(self.setup['SNIFFER_DIR']):
            sys.stderr.write("Could not load directory specified in sniffer_dir: {}\n".format(self.setup['SNIFFER_DIR']))
            exit()

        sys.stderr.write("[+] Successfully loaded sniffer directory: {}\n".format(self.setup['SNIFFER_DIR']))

        if setup['TLS_PROXY_PORT'] > 0:
            from Malcom.sniffer.tlsproxy.tlsproxy import MalcomTLSProxy
            sys.stderr.write("[+] Starting TLS proxy on port {}\n".format(setup['TLS_PROXY_PORT']))
            self.tls_proxy = MalcomTLSProxy(setup['TLS_PROXY_PORT'])
            self.tls_proxy.engine = self
            self.tls_proxy.start()
        else:
            self.tls_proxy = None

        self.sessions = {}

        self.model = Model(self.setup)
        self.db_lock = threading.Lock()

        self.messenger = SnifferMessenger()
        self.messenger.snifferengine = self


    def fetch_sniffer_session(self, session_id):
        try:
            debug_output("Fetching session {} from memory".format(session_id))
            session = self.sessions.get(ObjectId(session_id))
        except Exception as e:
            debug_output("An {} error occurred when fetching session '{}': {}".format(type(e).__name__, session_id, e), 'error')
            return

        # if not found, recreate it from the DB
        if not session:
            debug_output("Fetching session {} from DB".format(session_id))
            s = self.model.get_sniffer_session(session_id)
            if not s:
                return None
            # TLS interception only possible if PCAP hasn't been generated yet
            intercept_tls = s['intercept_tls'] and not s['pcap']

            if s:
                session = SnifferSession(s['name'],
                                         None,
                                         None,
                                         self,
                                         id=s['_id'],
                                         filter_restore=s['filter'],
                                         intercept_tls=intercept_tls)
                session.pcap = s['pcap']
                session.public = s['public']
                session.date_created = s['date_created']
                self.sessions[session.id] = session
                session_data = bson_loads(s['session_data'])
                session.nodes = session_data['nodes']
                session.edges = session_data['edges']
                session.packet_count = s['packet_count']
                session.flows = {}
                for flow in session_data['flows']:
                    f = Flow.load_flow(flow)
                    session.flows[f.fid] = f

        return session

    def new_session(self, params):
        session_name = params['session_name']
        remote_addr = params['remote_addr']
        filter = params['filter']
        intercept_tls = params['intercept_tls']

        sniffer_session = SnifferSession(session_name, remote_addr, filter, self, None, intercept_tls)
        sniffer_session.pcap = params['pcap']
        sniffer_session.public = params['public']

        return self.model.save_sniffer_session(sniffer_session)

    def delete_session(self, session_id):
        session = self.fetch_sniffer_session(session_id)

        if not session:
            return 'notfound'

        if session.status():
            return "running"

        else:
            self.model.del_sniffer_session(session, self.setup['SNIFFER_DIR'])
            return "removed"

    def commit_to_db(self, session):
        with self.db_lock:
            session.save_pcap()
            self.model.save_sniffer_session(session)
        debug_output("[+] Sniffing session {} saved".format(session.name))
        return True