def __init__( self, res=None, # type: Optional[Union[_PacketList[QueryAnswer], List[QueryAnswer]]] # noqa: E501 name="ARPing", # type: str stats=None # type: Optional[List[Type[Packet]]] ): SndRcvList.__init__(self, res, name, stats)
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
def arpleak(target, plen=255, hwlen=255, **kargs): """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 = {} 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
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)
def __init__(self, res=None, name="ARPing", stats=None): SndRcvList.__init__(self, res, name, stats)
class debug: recv = PacketList([], "Received") sent = PacketList([], "Sent") match = SndRcvList([], "Matched") crashed_on = None # type: Optional[Tuple[Type[Packet], bytes]]
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")
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")
def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, store_unanswered=True, process=None, timeout=None): if not verbose: verbose = conf.verb listable = (isinstance(pkt, Packet) and pkt.__iterlen__() == 1) or isinstance(pkt, list) # noqa: E501 tobesent = pkt use_prn_mode = False _storage_policy = None if process is not None: use_prn_mode = True _storage_policy = lambda x, y: process(x, y) stopevent = threading.Event() count_packets = six.moves.queue.Queue() hsent = {} timessent = {} if listable else None def send_in_loop(tobesent, stopevent, count_packets=count_packets): """Infinite generator that produces the same packet until stopevent is triggered.""" # noqa: E501 while True: for p in tobesent: if stopevent.is_set(): return count_packets.put(0) yield p infinite_gen = send_in_loop(tobesent, stopevent) def _timeout(timeout): stopevent.wait(timeout) stopevent.set() timeout_thread = threading.Thread(target=_timeout, args=(timeout, )) timeout_thread.setDaemon(True) timeout_thread.start() # We don't use _sndrcv_snd verbose (it messes the logs up as in a thread that ends after receiving) # noqa: E501 thread = threading.Thread(target=_sndrcv_snd, args=(pks, None, inter, False, infinite_gen, hsent, timessent, stopevent)) thread.setDaemon(True) thread.start() hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, hsent, stopevent, 0, len(tobesent), verbose, chainCC, False, _storage_policy=_storage_policy) thread.join() # Restore time_sent to original packets if listable: i = 0 for p in (pkt if isinstance(pkt, list) else [pkt]): p.sent_time = timessent[i] i += 1 if process is not None: ans = [(x, process(y)) for (x, y) in ans] # Apply process if store_unanswered: if use_prn_mode: remain = [ process(x, None) for x in itertools.chain(*six.itervalues(hsent)) ] # noqa: E501 else: remain = list(itertools.chain(*six.itervalues(hsent))) if verbose: print( "\nReceived %i packets, got %i answers, remaining %i packets. Sent a total of %i packets." % (nbrecv + len(ans), len(ans), notans, count_packets.qsize())) # noqa: E501 count_packets.empty() del count_packets ans_result = ans if use_prn_mode else SndRcvList(ans) unans_result = remain if use_prn_mode else ( None if not store_unanswered else PacketList(remain, "Unanswered") ) # noqa: E501 return ans_result, unans_result
def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False, retry=0, multi=False, rcv_pks=None, store_unanswered=True, process=None, prebuild=False): """Scapy raw function to send a packet and receive its answer. WARNING: This is an internal function. Using sr/srp/sr1/srp is more appropriate in many cases. """ if verbose is None: verbose = conf.verb use_prn_mode = False _storage_policy = None if process is not None: use_prn_mode = True _storage_policy = lambda x, y: process(x, y) debug.recv = PacketList([], "Unanswered") debug.sent = PacketList([], "Sent") debug.match = SndRcvList([]) nbrecv = 0 ans = [] listable = (isinstance(pkt, Packet) and pkt.__iterlen__() == 1) or isinstance(pkt, list) # noqa: E501 # do it here to fix random fields, so that parent and child have the same if isinstance(pkt, types.GeneratorType) or prebuild: tobesent = [p for p in pkt] notans = len(tobesent) else: tobesent = SetGen(pkt) if not isinstance(pkt, Gen) else pkt notans = tobesent.__iterlen__() if retry < 0: autostop = retry = -retry else: autostop = 0 while retry >= 0: if timeout is not None and timeout < 0: timeout = None stopevent = threading.Event() hsent = {} timessent = {} if listable else None _sndrcv_snd(pks, timeout, inter, verbose, tobesent, hsent, timessent, stopevent) hsent, newans, nbrecv, notans = _sndrcv_rcv( (rcv_pks or pks), hsent, stopevent, nbrecv, notans, verbose, chainCC, multi, _storage_policy=_storage_policy, ) ans.extend(newans) # Restore time_sent to original packets if listable: i = 0 for p in (pkt if isinstance(pkt, list) else [pkt]): p.sent_time = timessent[i] i += 1 if store_unanswered: remain = list(itertools.chain(*six.itervalues(hsent))) if multi: remain = [p for p in remain if not hasattr(p, '_answered')] if autostop and len(remain) > 0 and len(remain) != len(tobesent): retry = autostop tobesent = remain if len(tobesent) == 0: break else: remain = [] retry -= 1 if conf.debug_match: debug.sent = PacketList(remain[:], "Sent") debug.match = SndRcvList(ans[:]) # Clean the ans list to delete the field _answered if multi: for snd, _ in ans: if hasattr(snd, '_answered'): del snd._answered if verbose: print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv + len(ans), len(ans), notans)) # noqa: E501 if store_unanswered and use_prn_mode: remain = [process(x, None) for x in remain] ans_result = ans if use_prn_mode else SndRcvList(ans) unans_result = remain if use_prn_mode else ( None if not store_unanswered else PacketList(remain, "Unanswered") ) # noqa: E501 return ans_result, unans_result
def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False, retry=0, multi=False, rcv_pks=None, store_unanswered=True, process=None, prebuild=False): """Scapy raw function to send a packet and receive its answer. WARNING: This is an internal function. Using sr/srp/sr1/srp is more appropriate in many cases. pks: SuperSocket instance to send/receive packets pkt: the packet to send rcv_pks: if set, will be used instead of pks to receive packets. packets will still # noqa: E501 be sent through pks nofilter: put 1 to avoid use of BPF filters retry: if positive, how many times to resend unanswered packets if negative, how many times to retry when no more packets are answered # noqa: E501 timeout: how much time to wait after the last packet has been sent verbose: set verbosity level multi: whether to accept multiple answers for the same stimulus store_unanswered: whether to store not-answered packets or not. Default True. # noqa: E501 setting it to False will increase speed, and will return None # noqa: E501 as the unans list. process: if specified, only result from process(pkt) will be stored. the function should follow the following format: lambda sent, received: (func(sent), func2(received)) if the packet is unanswered, `received` will be None. if `store_unanswered` is False, the function won't be called on un-answered packets. # noqa: E501 prebuild: pre-build the packets before starting to send them. Default to False. Automatically used # noqa: E501 when a generator is passed as the packet """ if verbose is None: verbose = conf.verb use_prn_mode = False _storage_policy = None if process is not None: use_prn_mode = True _storage_policy = lambda x, y: process(x, y) debug.recv = PacketList([], "Unanswered") debug.sent = PacketList([], "Sent") debug.match = SndRcvList([]) nbrecv = 0 ans = [] listable = (isinstance(pkt, Packet) and pkt.__iterlen__() == 1) or isinstance(pkt, list) # noqa: E501 # do it here to fix random fields, so that parent and child have the same if isinstance(pkt, types.GeneratorType) or prebuild: tobesent = [p for p in pkt] notans = len(tobesent) else: tobesent = SetGen(pkt) if not isinstance(pkt, Gen) else pkt notans = tobesent.__iterlen__() if retry < 0: autostop = retry = -retry else: autostop = 0 while retry >= 0: if timeout is not None and timeout < 0: timeout = None stopevent = threading.Event() hsent = {} timessent = {} if listable else None thread = threading.Thread( target=_sndrcv_snd, args=(pks, timeout, inter, verbose, tobesent, hsent, timessent, stopevent), # noqa: E501 ) thread.setDaemon(True) thread.start() hsent, newans, nbrecv, notans = _sndrcv_rcv( (rcv_pks or pks), hsent, stopevent, nbrecv, notans, verbose, chainCC, multi, # noqa: E501 _storage_policy=_storage_policy, ) thread.join() ans.extend(newans) # Restore time_sent to original packets if listable: i = 0 for p in (pkt if isinstance(pkt, list) else [pkt]): p.sent_time = timessent[i] i += 1 if store_unanswered: remain = list(itertools.chain(*six.itervalues(hsent))) if multi: remain = [p for p in remain if not hasattr(p, '_answered')] if autostop and len(remain) > 0 and len(remain) != len(tobesent): retry = autostop tobesent = remain if len(tobesent) == 0: break else: remain = [] retry -= 1 if conf.debug_match: debug.sent = PacketList(remain[:], "Sent") debug.match = SndRcvList(ans[:]) # Clean the ans list to delete the field _answered if multi: for snd, _ in ans: if hasattr(snd, '_answered'): del snd._answered if verbose: print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv + len(ans), len(ans), notans)) # noqa: E501 if store_unanswered and use_prn_mode: remain = [process(x, None) for x in remain] ans_result = ans if use_prn_mode else SndRcvList(ans) unans_result = remain if use_prn_mode else ( None if not store_unanswered else PacketList(remain, "Unanswered") ) # noqa: E501 return ans_result, unans_result