Exemple #1
0
def load_pcap_file(filename, display=True):
    if display:
        pkts = []
        with PcapReader(filename) as plist:
            for pkt in tqdm(plist, desc="Loading Pcap   "):
                pkts.append(pkt)
            # filtering packets
            pkts = [
                pkt for pkt in pkts if (UDP in pkt) and (VideoProtocol in pkt)
            ]
            plist = PacketList(pkts, name=os.path.basename(filename))
            # IP defragment
            plist = ip_defragment(plist)
    else:
        plist = rdpcap(filename)
        plist = PacketList(
            [p for p in plist if (UDP in p) and (VideoProtocol in p)])
        plist = defragment(plist)

    # convert Video
    video = []
    parser = VideoProtocolParser()
    for pkt in plist:
        image = parser.toimage(pkt)
        if image is None:
            continue
        else:
            video.append(image)
    return video
    def __init__(self, packets, localport=50002, remoteport=4172, isUDP=True):
        '''
		Initialise a conversation from a pcap file or a list otherwise obtained from scapy 
		using scapy.rdpcap (also available as udpanal.rdpcap).
		
		Args:
		* packets - either string representing relative or absolute filename for pcap file
					or PacketList object returned by rdpcap
		* localport - the UDP port you communicated from
		* remoteport - the UDP port you are communicating with
		* isUDP - for future use when TCP & SCTP are also implemented
		'''
        if type(packets) == type(''):
            pktlist = rdpcap(packets)
        elif type(PacketList()) == type(packets):
            pktlist = packets  # re-initialise, take the penalty to kill that annoying 'filter multiplicity)
        else:
            self = packets

        self.lport = localport
        self.rport = remoteport

        if isUDP:
            pktlist = pktlist.filter(lambda x: x.haslayer(UDP))
            pktlist = pktlist.filter(
                lambda x: x.getlayer(UDP).dport == self.lport or x.getlayer(
                    UDP).sport == self.lport or x.getlayer(UDP).dport == self.
                rport or x.getlayer(UDP).sport == self.rport)
            self.pktlist = PacketList(pktlist)
        self.count = len(self.pktlist)
        return
Exemple #3
0
    def _run(self,
             store=False,
             prn=None,
             lfilter=None,
             refresh=.1,
             *args,
             **kwargs):
        s = conf.L2listen(type=ETH_P_ALL, *args, **kwargs)
        lst = []
        self.running = True
        try:
            while True:
                if self.stop_event and self.stop_event.is_set():
                    break
                sel = select([s], [], [], refresh)
                if s in sel[0]:
                    p = s.recv(MTU)
                    if p is None:
                        break
                    if lfilter and not lfilter(p):
                        continue
                    if store:
                        lst.append(p)
                    if prn:
                        r = prn(p)
                        if r is not None:
                            print(r)
        except KeyboardInterrupt:
            pass
        finally:
            s.close()

        self.results = PacketList(lst, "Sniffed")
Exemple #4
0
    def crypt2plain(self, pcapFile, encType, key):
        """Converts an encrypted stream to unencrypted stream
        Returns the unencrypted stream input as a scapy PacketList object
        
        Future plans involve offering a yield parameter so that pcapList,
        instead returns as a generated object; should save memory this way.
        
        Does not have the capability to diff between multiple keys encTypes
        Possible workaround for this is taking the try and using except,
        creating a return to let the user know which objs to retry on
        For now, skipping.
        """

        ## Use the generator of PcapReader for memory purposes
        pObj = PcapReader(pcapFile)
        pcapList = []

        ## Deal with WEP
        if encType == 'WEP':
            for i in pObj:
                try:
                    pkt, iv = pyDot11.wepDecrypt(i, key)
                except:
                    pkt = i
                pcapList.append(pkt)

        ## Return the stream like a normal Scapy PacketList
        return PacketList(res=pcapList)
Exemple #5
0
def __gen_send(
        s,  # type: SuperSocket
        x,  # type: _PacketIterable
        inter=0,  # type: int
        loop=0,  # type: int
        count=None,  # type: Optional[int]
        verbose=None,  # type: Optional[int]
        realtime=False,  # type: bool
        return_packets=False,  # type: bool
        *args,  # type: Any
        **kargs  # type: Any
):
    # type: (...) -> Optional[PacketList]
    """
    An internal function used by send/sendp to actually send the packets,
    implement the send logic...

    It will take care of iterating through the different packets
    """
    if isinstance(x, str):
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    if return_packets:
        sent_packets = PacketList()
    try:
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + float(p.time) - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - float(p.time)
                s.send(p)
                if return_packets:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, b".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    if verbose:
        print("\nSent %i packets." % n)
    if return_packets:
        return sent_packets
    return None
    def parse(self, plist):
        """Update the builder using the provided `plist`. `plist` can
        be either a Packet() or a PacketList().

        """
        if not isinstance(plist, PacketList):
            plist = PacketList(plist)
        for pkt in plist[LLTD]:
            if LLTDQueryLargeTlv in pkt:
                key = "%s:%s:%d" % (pkt.real_dst, pkt.real_src, pkt.seq)
                self.types_offsets[key] = (pkt[LLTDQueryLargeTlv].type,
                                           pkt[LLTDQueryLargeTlv].offset)
            elif LLTDQueryLargeTlvResp in pkt:
                try:
                    key = "%s:%s:%d" % (pkt.real_src, pkt.real_dst, pkt.seq)
                    content, offset = self.types_offsets[key]
                except KeyError:
                    continue
                loc = slice(offset, offset + pkt[LLTDQueryLargeTlvResp].len)
                key = "%s > %s [%s]" % (
                    pkt.real_src,
                    pkt.real_dst,
                    LLTDQueryLargeTlv.fields_desc[0].i2s.get(content, content),
                )
                data = self.data.setdefault(key, array("B"))
                datalen = len(data)
                if datalen < loc.stop:
                    data.extend(array("B", b"\x00" * (loc.stop - datalen)))
                data[loc] = array("B", pkt[LLTDQueryLargeTlvResp].value)
Exemple #7
0
    def __init__(self,
                 init_session=None,
                 init_security_level=None,
                 init_communication_control=None,
                 logging=True,
                 verbose=True,
                 store_supported_responses=True):
        """
        Initialize an Ecu object

        :param init_session: An initial session
        :param init_security_level: An initial security level
        :param init_communication_control: An initial communication control
                                           setting
        :param logging: Turn logging on or off. Default is on.
        :param verbose: Turn tracking on or off. Default is on.
        :param store_supported_responses: Turn creation of supported responses
                                          on or off. Default is on.
        """
        self.state = EcuState(session=init_session or 1,
                              security_level=init_security_level or 0,
                              communication_control=init_communication_control
                              or 0)
        self.verbose = verbose
        self.logging = logging
        self.store_supported_responses = store_supported_responses
        self.log = defaultdict(list)
        self._supported_responses = list()
        self._unanswered_packets = PacketList()
Exemple #8
0
    def make_reply(self, req):
        if self.supported_responses is not None:
            for resp in self.supported_responses:
                if not isinstance(resp, EcuResponse):
                    raise Scapy_Exception("Unsupported type for response. "
                                          "Please use `EcuResponse` objects. ")

                if not resp.in_correct_session(self.ecu_state.current_session):
                    continue

                if not resp.has_security_access(
                        self.ecu_state.current_security_level):
                    continue

                if not resp.answers(req):
                    continue

                for r in resp.responses:
                    for layer in r.layers():
                        if hasattr(layer, "modifies_ecu_state"):
                            layer.modifies_ecu_state(r, self.ecu_state)

                return resp.responses

        return PacketList([self.basecls(b"\x7f" + bytes(req)[0:1] + b"\x10")])
Exemple #9
0
    def make_reply(self, req):
        # type: (Packet) -> PacketList
        """
        Checks if a given request can be answered by the internal list of
        EcuResponses. First, it's evaluated if the internal EcuState of this
        AnsweringMachine is supported by an EcuResponse, next it's evaluated if
        a request answers the key_response of this EcuResponse object. The
        first fitting EcuResponse is used. If this EcuResponse modified the
        EcuState, the internal EcuState of this AnsweringMachine is updated,
        and the list of response Packets of the selected EcuResponse is
        returned. If no EcuResponse if found, a PacketList with a generic
        NegativeResponse is returned.
        :param req: A request packet
        :return: A list of response packets
        """
        if self._supported_responses is not None:
            for resp in self._supported_responses:
                if not isinstance(resp, EcuResponse):
                    raise TypeError("Unsupported type for response. "
                                    "Please use `EcuResponse` objects.")

                with self._ecu_state_mutex:
                    if not resp.supports_state(self._ecu_state):
                        continue

                    if not resp.answers(req):
                        continue

                    EcuState.get_modified_ecu_state(
                        resp.key_response, req, self._ecu_state, True)

                    return resp.responses

        return PacketList([self._basecls(
            b"\x7f" + bytes(req)[0:1] + b"\x10")])
Exemple #10
0
 def toEthernet(self):
     data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
     r2 = []
     for p in data:
         q = p.copy()
         q.unwep()
         r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
     return PacketList(r2,name="Ether from %s"%self.listname)
 def toEthernet(self):
     data = [x[Dot11] for x in self.res if Dot11 in x and x.type == 2]
     r2 = []
     for p in data:
         q = p.copy()
         q.unwep()
         r2.append(Ether() / q.payload.payload.payload)  # Dot11/LLC/SNAP/IP
     return PacketList(r2, name="Ether from %s" % self.listname)
Exemple #12
0
 def refresh():
     Vault.__threading_packet_list = PacketList()
     Vault.__mapping = Counter()
     Vault.__packet_count = 0
     Vault.__session_dict = {}
     Vault.__session_header = []
     Vault.__flagged_dict = {}
     Vault.__carved_files = []
Exemple #13
0
    def get_capture(self,
                    expected_count=None,
                    remark=None,
                    timeout=1,
                    filter_out_fn=is_ipv6_misc):
        """ Get captured packets

        :param expected_count: expected number of packets to capture, if None,
                               then self.test.packet_count_for_dst_pg_idx is
                               used to lookup the expected count
        :param remark: remark printed into debug logs
        :param timeout: how long to wait for packets
        :param filter_out_fn: filter applied to each packet, packets for which
                              the filter returns True are removed from capture
        :returns: iterable packets
        """
        remaining_time = timeout
        capture = None
        name = self.name if remark is None else "%s (%s)" % (self.name, remark)
        based_on = "based on provided argument"
        if expected_count is None:
            expected_count = \
                self.test.get_packet_count_for_if_idx(self.sw_if_index)
            based_on = "based on stored packet_infos"
            if expected_count == 0:
                raise Exception(
                    "Internal error, expected packet count for %s is 0!" %
                    name)
        self.test.logger.debug("Expecting to capture %s (%s) packets on %s" %
                               (expected_count, based_on, name))
        while remaining_time > 0:
            before = time.time()
            capture = self._get_capture(remaining_time, filter_out_fn)
            elapsed_time = time.time() - before
            if capture:
                if len(capture.res) == expected_count:
                    # bingo, got the packets we expected
                    return capture
                elif len(capture.res) > expected_count:
                    self.test.logger.error(
                        ppc("Unexpected packets captured:", capture))
                    break
                else:
                    self.test.logger.debug("Partial capture containing %s "
                                           "packets doesn't match expected "
                                           "count %s (yet?)" %
                                           (len(capture.res), expected_count))
            elif expected_count == 0:
                # bingo, got None as we expected - return empty capture
                return PacketList()
            remaining_time -= elapsed_time
        if capture:
            self.generate_debug_aid("count-mismatch")
            raise Exception("Captured packets mismatch, captured %s packets, "
                            "expected %s packets on %s" %
                            (len(capture.res), expected_count, name))
        else:
            raise Exception("No packets captured on %s" % name)
Exemple #14
0
    def _do_control(self, ready, *args, **kargs):
        with self.started:
            self.threadid = threading.currentThread().ident

            # Update default parameters
            a = args + self.init_args[len(args):]
            k = self.init_kargs.copy()
            k.update(kargs)
            self.parse_args(*a, **k)

            # Start the automaton
            self.state = self.initial_states[0](self)
            self.send_sock = self.send_sock_class(**self.socket_kargs)
            self.listen_sock = self.recv_sock_class(**self.socket_kargs)
            self.packets = PacketList(name="session[%s]" % self.__class__.__name__)  # noqa: E501

            singlestep = True
            iterator = self._do_iter()
            self.debug(3, "Starting control thread [tid=%i]" % self.threadid)
            # Sync threads
            ready.set()
            try:
                while True:
                    c = self.cmdin.recv()
                    self.debug(5, "Received command %s" % c.type)
                    if c.type == _ATMT_Command.RUN:
                        singlestep = False
                    elif c.type == _ATMT_Command.NEXT:
                        singlestep = True
                    elif c.type == _ATMT_Command.FREEZE:
                        continue
                    elif c.type == _ATMT_Command.STOP:
                        break
                    while True:
                        state = next(iterator)
                        if isinstance(state, self.CommandMessage):
                            break
                        elif isinstance(state, self.Breakpoint):
                            c = Message(type=_ATMT_Command.BREAKPOINT, state=state)  # noqa: E501
                            self.cmdout.send(c)
                            break
                        if singlestep:
                            c = Message(type=_ATMT_Command.SINGLESTEP, state=state)  # noqa: E501
                            self.cmdout.send(c)
                            break
            except StopIteration as e:
                c = Message(type=_ATMT_Command.END,
                            result=self.final_state_output)
                self.cmdout.send(c)
            except Exception as e:
                exc_info = sys.exc_info()
                self.debug(3, "Transferring exception from tid=%i:\n%s" % (self.threadid, traceback.format_exception(*exc_info)))  # noqa: E501
                m = Message(type=_ATMT_Command.EXCEPTION, exception=e, exc_info=exc_info)  # noqa: E501
                self.cmdout.send(m)
            self.debug(3, "Stopping control thread (tid=%i)" % self.threadid)
            self.threadid = None
Exemple #15
0
def __sr_loop(srfunc, pkts, prn=lambda x: x[1].summary(),
              prnfail=lambda x: x.summary(),
              inter=1, timeout=None, count=None, verbose=None, store=1,
              *args, **kargs):
    n = 0
    r = 0
    ct = conf.color_theme
    if verbose is None:
        verbose = conf.verb
    parity = 0
    ans = []
    unans = []
    if timeout is None:
        timeout = min(2 * inter, 5)
    try:
        while True:
            parity ^= 1
            col = [ct.even, ct.odd][parity]
            if count is not None:
                if count == 0:
                    break
                count -= 1
            start = time.time()
            if verbose > 1:
                print("\rsend...\r", end=' ')
            res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=True, *args, **kargs)  # noqa: E501
            n += len(res[0]) + len(res[1])
            r += len(res[0])
            if verbose > 1 and prn and len(res[0]) > 0:
                msg = "RECV %i:" % len(res[0])
                print("\r" + ct.success(msg), end=' ')
                for p in res[0]:
                    print(col(prn(p)))
                    print(" " * len(msg), end=' ')
            if verbose > 1 and prnfail and len(res[1]) > 0:
                msg = "fail %i:" % len(res[1])
                print("\r" + ct.fail(msg), end=' ')
                for p in res[1]:
                    print(col(prnfail(p)))
                    print(" " * len(msg), end=' ')
            if verbose > 1 and not (prn or prnfail):
                print("recv:%i  fail:%i" % tuple(map(len, res[:2])))
            if store:
                ans += res[0]
                unans += res[1]
            end = time.time()
            if end - start < inter:
                time.sleep(inter + start - end)
    except KeyboardInterrupt:
        pass

    if verbose and n > 0:
        print(ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n, r, 100.0 * r / n)))  # noqa: E501
    return SndRcvList(ans), PacketList(unans)
Exemple #16
0
 def __init__(self, logging=True, verbose=True,
              store_supported_responses=True, lookahead=10):
     # type: (bool, bool, bool, int) -> None
     self.state = EcuState()
     self.verbose = verbose
     self.logging = logging
     self.store_supported_responses = store_supported_responses
     self.lookahead = lookahead
     self.log = defaultdict(list)  # type: Dict[str, List[Any]]
     self.__supported_responses = list()  # type: List[EcuResponse]
     self.__unanswered_packets = PacketList()
Exemple #17
0
    def __init__(self,
                 session=1,
                 security_level=0,
                 responses=Raw(b"\x7f\x10"),
                 answers=None):
        """
        Initialize an EcuResponse capsule

        :param session: Defines the session in which this response is valid.
                        A integer, a callable or any iterable object can be
                        provided.
        :param security_level: Defines the security_level in which this
                               response is valid. A integer, a callable or any
                               iterable object can be provided.
        :param responses: A Packet or a list of Packet objects. By default the
                          last packet is asked if it answers a incoming packet.
                          This allows to send for example
                          `requestCorrectlyReceived-ResponsePending` packets.
        :param answers: Optional argument to provide a custom answer here:
                        `lambda resp, req: return resp.answers(req)`
                        This allows the modification of a response depending
                        on a request. Custom SecurityAccess mechanisms can
                        be implemented in this way or generic NegativeResponse
                        messages which answers to everything can be realized
                        in this way.
        """
        self.__session = session \
            if hasattr(session, "__iter__") or callable(session) else [session]
        self.__security_level = security_level \
            if hasattr(security_level, "__iter__") or callable(security_level)\
            else [security_level]
        if isinstance(responses, PacketList):
            self.responses = responses
        elif isinstance(responses, Packet):
            self.responses = PacketList([responses])
        elif hasattr(responses, "__iter__"):
            self.responses = PacketList(responses)
        else:
            self.responses = PacketList([responses])

        self.__custom_answers = answers
Exemple #18
0
def arpleak(target, plen=255, hwlen=255, **kargs):
    # type: (str, int, int, **Any) -> Tuple[SndRcvList, PacketList]
    """Exploit ARP leak flaws, like NetBSD-SA2017-002.

https://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2017-002.txt.asc

    """
    # We want explicit packets
    pkts_iface = {}  # type: Dict[str, List[Ether]]
    for pkt in ARP(pdst=target):
        # We have to do some of Scapy's work since we mess with
        # important values
        iface = conf.route.route(pkt.pdst)[0]
        psrc = get_if_addr(iface)
        hwsrc = get_if_hwaddr(iface)
        pkt.plen = plen
        pkt.hwlen = hwlen
        if plen == 4:
            pkt.psrc = psrc
        else:
            pkt.psrc = inet_aton(psrc)[:plen]
            pkt.pdst = inet_aton(pkt.pdst)[:plen]
        if hwlen == 6:
            pkt.hwsrc = hwsrc
        else:
            pkt.hwsrc = mac2str(hwsrc)[:hwlen]
        pkts_iface.setdefault(iface, []).append(
            Ether(src=hwsrc, dst=ETHER_BROADCAST) / pkt
        )
    ans, unans = SndRcvList(), PacketList(name="Unanswered")
    for iface, pkts in viewitems(pkts_iface):
        ans_new, unans_new = srp(pkts, iface=iface, filter="arp", **kargs)
        ans += ans_new
        unans += unans_new
        ans.listname = "Results"
        unans.listname = "Unanswered"
    for _, rcv in ans:
        if ARP not in rcv:
            continue
        rcv = rcv[ARP]
        psrc = rcv.get_field('psrc').i2m(rcv, rcv.psrc)
        if plen > 4 and len(psrc) > 4:
            print("psrc")
            hexdump(psrc[4:])
            print()
        hwsrc = rcv.get_field('hwsrc').i2m(rcv, rcv.hwsrc)
        if hwlen > 6 and len(hwsrc) > 6:
            print("hwsrc")
            hexdump(hwsrc[6:])
            print()
    return ans, unans
Exemple #19
0
def __gen_send(s,
               x,
               inter=0,
               loop=0,
               count=None,
               verbose=None,
               realtime=None,
               return_packets=False,
               *args,
               **kargs):  # noqa: E501
    if isinstance(x, str):
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    if return_packets:
        sent_packets = PacketList()
    try:
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + float(p.time) - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - float(p.time)
                s.send(p)
                if return_packets:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, b".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    if verbose:
        print("\nSent %i packets." % n)
    if return_packets:
        return sent_packets
Exemple #20
0
 def read_all(self, count=-1):
     """return a list of all packets in the candump file
     """
     res = []
     while count != 0:
         try:
             p = self.read_packet()
             if p is None:
                 continue
         except EOFError:
             break
         count -= 1
         res.append(p)
     return PacketList(res, name=os.path.basename(self.filename))
Exemple #21
0
    def convert_packet_list_to_data_frame(self, pcap):
        """Convert scapy packet list to pandas data frame.

        :param pcap: scapy packet list
        """
        try:
            pcap = PacketList(pcap)
        except TypeError as err:
            print(f"Convert to PacketList failed...error is: {err}")

        # Create blank DataFrame
        df = pd.DataFrame(columns=self.dataframe_fields)
        for packet in pcap[IP]:
            # Field array for each row of DataFrame
            field_values = []
            # Add all IP fields to dataframe
            for field in self.ip_fields:
                if field == 'options':
                    # Retrieving number of options defined in IP Header
                    field_values.append(len(packet[IP].fields[field]))
                else:
                    field_values.append(packet[IP].fields[field])

            field_values.append(str(packet.time))

            layer_type = type(packet[IP].payload)
            for field in self.tcp_fields:
                try:
                    if field == 'options':
                        field_values.append(len(packet[layer_type].fields[field]))
                    else:
                        field_values.append(packet[layer_type].fields[field])
                except:
                    field_values.append(None)

            # Append payload
            field_values.append(len(packet[layer_type].payload))
            field_values.append(packet[layer_type].payload.original)
            field_values.append(binascii.hexlify(packet[layer_type].payload.original))
            # Add row to DF
            df_append = pd.DataFrame([field_values],
                                     columns=self.dataframe_fields)
            df = pd.concat([df, df_append], axis=0)

        # Reset Index
        df = df.reset_index()
        # Drop old index column
        df = df.drop(columns="index")

        self.df = df
Exemple #22
0
    def __init__(self, state=None, responses=Raw(b"\x7f\x10"), answers=None):
        # type: (Optional[Union[EcuState, Iterable[EcuState]]], Union[Iterable[Packet], PacketList, Packet], Optional[Callable[[Packet, Packet], bool]]) -> None  # noqa: E501
        if state is None:
            self.__states = None  # type: Optional[List[EcuState]]
        else:
            if hasattr(state, "__iter__"):
                state = cast(List[EcuState], state)
                self.__states = state
            else:
                state = cast(EcuState, state)
                self.__states = [state]

        if isinstance(responses, PacketList):
            self.__responses = responses  # type: PacketList
        elif isinstance(responses, Packet):
            self.__responses = PacketList([responses])
        elif hasattr(responses, "__iter__"):
            responses = cast(List[Packet], responses)
            self.__responses = PacketList(responses)
        else:
            raise TypeError(
                "Can't handle type %s as response" % type(responses))

        self.__custom_answers = answers
Exemple #23
0
    def __init__(self, *args, **kargs):
        # type: (Any, Any) -> None
        external_fd = kargs.pop("external_fd", {})
        self.send_sock_class = kargs.pop("ll", conf.L3socket)
        self.recv_sock_class = kargs.pop("recvsock", conf.L2listen)
        self.is_atmt_socket = kargs.pop("is_atmt_socket", False)
        self.started = threading.Lock()
        self.threadid = None                # type: Optional[int]
        self.breakpointed = None
        self.breakpoints = set()            # type: Set[_StateWrapper]
        self.interception_points = set()    # type: Set[_StateWrapper]
        self.intercepted_packet = None      # type: Union[None, Packet]
        self.debug_level = 0
        self.init_args = args
        self.init_kargs = kargs
        self.io = type.__new__(type, "IOnamespace", (), {})
        self.oi = type.__new__(type, "IOnamespace", (), {})
        self.cmdin = ObjectPipe[Message]("cmdin")
        self.cmdout = ObjectPipe[Message]("cmdout")
        self.ioin = {}
        self.ioout = {}
        self.packets = PacketList()                 # type: PacketList
        for n in self.__class__.ionames:
            extfd = external_fd.get(n)
            if not isinstance(extfd, tuple):
                extfd = (extfd, extfd)
            ioin, ioout = extfd
            if ioin is None:
                ioin = ObjectPipe("ioin")
            else:
                ioin = self._IO_fdwrapper(ioin, None)
            if ioout is None:
                ioout = ObjectPipe("ioout")
            else:
                ioout = self._IO_fdwrapper(None, ioout)

            self.ioin[n] = ioin
            self.ioout[n] = ioout
            ioin.ioname = n
            ioout.ioname = n
            setattr(self.io, n, self._IO_mixer(ioout, ioin))
            setattr(self.oi, n, self._IO_mixer(ioin, ioout))

        for stname in self.states:
            setattr(self, stname,
                    _instance_state(getattr(self, stname)))

        self.start()
Exemple #24
0
    def _update_supported_responses(self, pkt):
        self._unanswered_packets += PacketList([pkt])
        answered, unanswered = self._unanswered_packets.sr()
        for _, resp in answered:
            ecu_resp = EcuResponse(session=self.current_session,
                                   security_level=self.current_security_level,
                                   responses=resp)

            if ecu_resp not in self._supported_responses:
                if self.verbose:
                    print("[+] ", repr(ecu_resp))
                self._supported_responses.append(ecu_resp)
            else:
                if self.verbose:
                    print("[-] ", repr(ecu_resp))
        self._unanswered_packets = unanswered
Exemple #25
0
    def read_all(self, count=-1):
        # type: (int) -> PacketList
        """Read a specific number or all packets from a candump file.

        :param count: Specify a specific number of packets to be read.
                      All packets can be read by count=-1.
        :return: A PacketList object containing read CAN messages
        """
        res = []
        while count != 0:
            try:
                p = self.read_packet()
                if p is None:
                    continue
            except EOFError:
                break
            count -= 1
            res.append(p)
        return PacketList(res, name=os.path.basename(self.filename))
Exemple #26
0
def ip_defragment(plist):
    """defrag(plist) -> plist defragmented as much as possible """
    frags = defaultdict(lambda: [])
    final = []

    pos = 0
    for p in plist:
        p._defrag_pos = pos
        pos += 1
        if IP in p:
            ip = p[IP]
            if ip.frag != 0 or ip.flags & 1:
                ip = p[IP]
                uniq = (ip.id, ip.src, ip.dst, ip.proto)
                frags[uniq].append(p)
                continue
        final.append(p)

    pbar = tqdm(total=len(frags), desc="IP defrag(1/2) ")
    defrag = []
    missfrag = []
    for lst in six.itervalues(frags):
        pbar.update(1)
        lst.sort(key=lambda x: x.frag)
        p = lst[0]
        lastp = lst[-1]
        if p.frag > 0 or lastp.flags & 1 != 0:  # first or last fragment missing
            missfrag += lst
            continue
        p = p.copy()
        if conf.padding_layer in p:
            del (p[conf.padding_layer].underlayer.payload)
        ip = p[IP]
        if ip.len is None or ip.ihl is None:
            clen = len(ip.payload)
        else:
            clen = ip.len - (ip.ihl << 2)
        txt = conf.raw_layer()
        for q in lst[1:]:
            if clen != q.frag << 3:  # Wrong fragmentation offset
                if clen > q.frag << 3:
                    warning("Fragment overlap (%i > %i) %r || %r ||  %r" %
                            (clen, q.frag << 3, p, txt, q))
                missfrag += lst
                break
            if q[IP].len is None or q[IP].ihl is None:
                clen += len(q[IP].payload)
            else:
                clen += q[IP].len - (q[IP].ihl << 2)
            if conf.padding_layer in q:
                del (q[conf.padding_layer].underlayer.payload)
            txt.add_payload(q[IP].payload.copy())
        else:
            ip.flags &= ~1  # !MF
            del (ip.chksum)
            del (ip.len)
            p = p / txt
            p._defrag_pos = max(x._defrag_pos for x in lst)
            defrag.append(p)
    pbar.close()
    defrag2 = []
    for p in tqdm(defrag, desc="IP defrag(2/2) "):
        q = p.__class__(raw(p))
        q._defrag_pos = p._defrag_pos
        defrag2.append(q)
    final += defrag2
    final += missfrag
    final.sort(key=lambda x: x._defrag_pos)
    for p in final:
        del (p._defrag_pos)

    if hasattr(plist, "listname"):
        name = "Defragmented %s" % plist.listname
    else:
        name = "Defragmented"

    return PacketList(final, name=name)
Exemple #27
0
 def toPacketList(self):
     # type: () -> PacketList
     if self._supersession:
         return PacketList(self._supersession.lst, "Sniffed")
     else:
         return PacketList(self.lst, "Sniffed")
Exemple #28
0
    def __init__(self,
                 pks,
                 pkt,
                 timeout=None,
                 inter=0,
                 verbose=None,
                 chainCC=False,
                 retry=0,
                 multi=False,
                 rcv_pks=None,
                 prebuild=False,
                 _flood=None):
        # Instantiate all arguments
        if verbose is None:
            verbose = conf.verb
        if conf.debug_match:
            debug.recv = PacketList([], "Received")
            debug.sent = PacketList([], "Sent")
            debug.match = SndRcvList([], "Matched")
        self.nbrecv = 0
        self.ans = []
        self.pks = pks
        self.rcv_pks = rcv_pks or pks
        self.inter = inter
        self.verbose = verbose
        self.chainCC = chainCC
        self.multi = multi
        self.timeout = timeout
        # Instantiate packet holders
        if _flood:
            self.tobesent = pkt
            self.notans = _flood[0]
        else:
            if isinstance(pkt, types.GeneratorType) or prebuild:
                self.tobesent = [p for p in pkt]
                self.notans = len(self.tobesent)
            else:
                self.tobesent = (SetGen(pkt)
                                 if not isinstance(pkt, Gen) else pkt)
                self.notans = self.tobesent.__iterlen__()

        if retry < 0:
            autostop = retry = -retry
        else:
            autostop = 0

        if timeout is not None and timeout < 0:
            self.timeout = None

        while retry >= 0:
            self.hsent = {}

            # Send packets in thread.
            # https://github.com/secdev/scapy/issues/1791
            snd_thread = Thread(target=self._sndrcv_snd)
            snd_thread.setDaemon(True)

            # Start routine with callback
            self._sndrcv_rcv(snd_thread.start)

            # Ended. Let's close gracefully
            if _flood:
                # Flood: stop send thread
                _flood[1]()
            snd_thread.join()

            if multi:
                remain = [
                    p for p in itertools.chain(*six.itervalues(self.hsent))
                    if not hasattr(p, '_answered')
                ]
            else:
                remain = list(itertools.chain(*six.itervalues(self.hsent)))

            if autostop and len(remain) > 0 and \
               len(remain) != len(self.tobesent):
                retry = autostop

            self.tobesent = remain
            if len(self.tobesent) == 0:
                break
            retry -= 1

        if conf.debug_match:
            debug.sent = PacketList(remain[:], "Sent")
            debug.match = SndRcvList(self.ans[:])

        # Clean the ans list to delete the field _answered
        if multi:
            for snd, _ in self.ans:
                if hasattr(snd, '_answered'):
                    del snd._answered

        if verbose:
            print("\nReceived %i packets, got %i answers, "
                  "remaining %i packets" %
                  (self.nbrecv + len(self.ans), len(self.ans), self.notans))

        self.ans_result = SndRcvList(self.ans)
        self.unans_result = PacketList(remain, "Unanswered")
Exemple #29
0
class debug:
    recv = PacketList([], "Received")
    sent = PacketList([], "Sent")
    match = SndRcvList([], "Matched")
    crashed_on = None  # type: Optional[Tuple[Type[Packet], bytes]]
Exemple #30
0
    def __init__(self,
                 pks,  # type: SuperSocket
                 pkt,  # type: _PacketIterable
                 timeout=None,  # type: Optional[int]
                 inter=0,  # type: int
                 verbose=None,  # type: Optional[int]
                 chainCC=False,  # type: bool
                 retry=0,  # type: int
                 multi=False,  # type: bool
                 rcv_pks=None,  # type: Optional[SuperSocket]
                 prebuild=False,  # type: bool
                 _flood=None,  # type: Optional[Tuple[int, Callable[[], None]]]  # noqa: E501
                 threaded=False,  # type: bool
                 session=None  # type: Optional[_GlobSessionType]
                 ):
        # type: (...) -> None
        # Instantiate all arguments
        if verbose is None:
            verbose = conf.verb
        if conf.debug_match:
            debug.recv = PacketList([], "Received")
            debug.sent = PacketList([], "Sent")
            debug.match = SndRcvList([], "Matched")
        self.nbrecv = 0
        self.ans = []  # type: List[QueryAnswer]
        self.pks = pks
        self.rcv_pks = rcv_pks or pks
        self.inter = inter
        self.verbose = verbose
        self.chainCC = chainCC
        self.multi = multi
        self.timeout = timeout
        self.session = session
        # Instantiate packet holders
        if _flood:
            self.tobesent = pkt  # type: Union[_PacketIterable, SetGen[Packet]]
            self.notans = _flood[0]
        else:
            if isinstance(pkt, types.GeneratorType) or prebuild:
                self.tobesent = list(pkt)
                self.notans = len(self.tobesent)
            else:
                self.tobesent = (
                    SetGen(pkt) if not isinstance(pkt, Gen) else pkt
                )
                self.notans = self.tobesent.__iterlen__()

        if retry < 0:
            autostop = retry = -retry
        else:
            autostop = 0

        if timeout is not None and timeout < 0:
            self.timeout = None

        while retry >= 0:
            self.hsent = {}  # type: Dict[bytes, List[Packet]]

            if threaded or _flood:
                # Send packets in thread.
                # https://github.com/secdev/scapy/issues/1791
                snd_thread = Thread(
                    target=self._sndrcv_snd
                )
                snd_thread.setDaemon(True)

                # Start routine with callback
                self._sndrcv_rcv(snd_thread.start)

                # Ended. Let's close gracefully
                if _flood:
                    # Flood: stop send thread
                    _flood[1]()
                snd_thread.join()
            else:
                self._sndrcv_rcv(self._sndrcv_snd)

            if multi:
                remain = [
                    p for p in itertools.chain(*six.itervalues(self.hsent))
                    if not hasattr(p, '_answered')
                ]
            else:
                remain = list(itertools.chain(*six.itervalues(self.hsent)))

            if autostop and len(remain) > 0 and \
               len(remain) != len(self.tobesent):
                retry = autostop

            self.tobesent = remain
            if len(self.tobesent) == 0:
                break
            retry -= 1

        if conf.debug_match:
            debug.sent = PacketList(remain[:], "Sent")
            debug.match = SndRcvList(self.ans[:])

        # Clean the ans list to delete the field _answered
        if multi:
            for snd, _ in self.ans:
                if hasattr(snd, '_answered'):
                    del snd._answered

        if verbose:
            print(
                "\nReceived %i packets, got %i answers, "
                "remaining %i packets" % (
                    self.nbrecv + len(self.ans), len(self.ans), self.notans
                )
            )

        self.ans_result = SndRcvList(self.ans)
        self.unans_result = PacketList(remain, "Unanswered")