Beispiel #1
0
    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
Beispiel #2
0
    def handlePacket(self, pkt):

        IP_layer = IP if IP in pkt else IPv6  # add IPv6 support another night...
        if IP_layer == IPv6:
            return

        self.pkts.append(pkt)
        self.packet_count += 1

        elts = []
        edges = []

        # FLOW ANALYSIS - reconstruct TCP flow if possible
        # do flow analysis here, if necessary - this will be replaced by dpkt's magic

        if TCP in pkt or UDP in pkt:

            Flow.pkt_handler(pkt, self.flows)
            flow = self.flows[Flow.flowid(pkt)]
            self.send_flow_statistics(flow)

            new_elts, new_edges = self.checkHTTP(flow)

            if new_elts:
                elts += new_elts
            if new_edges:
                edges += new_edges

        # end flow analysis

        # STANDARD PACKET ANALYSIS - extract IP addresses and domain names
        # the magic for extracting elements from packets happens here

        new_elts, new_edges = self.checkIP(pkt)  # pass decode information if found
        if new_elts:
            elts += new_elts
        if new_edges:
            edges += new_edges

        new_elts, new_edges = self.checkDNS(pkt)
        if new_elts:
            elts += new_elts
        if new_edges:
            edges += new_edges

        # TLS MITM - intercept TLS communications and send cleartext to malcom
        # We want to be protocol agnostic (HTTPS, FTPS, ***S). For now, we choose which
        # connections to intercept based on destination port number

        # We could also catch ALL connections and MITM only those which start with
        # a TLS handshake

        tlsports = [443]
        if TCP in pkt and pkt[TCP].flags & 0x02 and pkt[TCP].dport in tlsports and not self.pcap and self.intercept_tls:  # of course, interception doesn't work with pcaps
            # mark flow as tls
            flow.tls = True

            # add host / flow tuple to the TLS connection list
            debug_output("TLS SYN: {}:{} -> {}:{}".format(pkt[IP].src, pkt[TCP].sport, pkt[IP].dst, pkt[TCP].dport))
            # this could actually be replaced by only flow
            self.tls_proxy.hosts[(pkt[IP].src, pkt[TCP].sport)] = (pkt[IP].dst, pkt[TCP].dport, flow.fid)
            self.tls_proxy.factory.flows[flow.fid] = flow

        if elts != [] or edges != []:
            self.send_nodes(elts, edges)

        # send individual packets to modules in case they use them
        for mod in self.modules.values():
            mod.on_packet(pkt)