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 = plist.PacketList() try: while loop: dt0 = None for p in x: if realtime: ct = time.time() if dt0: st = dt0 + p.time - ct if st > 0: time.sleep(st) else: dt0 = ct - 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 s.close() if verbose: print("\nSent %i packets." % n) if return_packets: return sent_packets
def _show_or_dump(self, dump=False, indent=3, lvl="", label_lvl="", first_call=True): """ Internal method that shows or dumps a hierachical view of a packet. Called by show. """ if dump: from scapy.themes import AnsiColorTheme ct = AnsiColorTheme() # No color for dump output else: ct = conf.color_theme s = "%s%s %s %s \n" % (label_lvl, ct.punct("###["), ct.layer_name(self.name), ct.punct("]###")) for f in self.fields_desc: if isinstance(f, ConditionalField) and not f._evalcond(self): continue if isinstance(f, Emph) or f in conf.emph: ncol = ct.emph_field_name vcol = ct.emph_field_value else: ncol = ct.field_name vcol = ct.field_value fvalue = self.getfieldval(f.name) if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list): s += "%s \\%-10s\\\n" % (label_lvl + lvl, ncol(f.name)) fvalue_gen = SetGen(fvalue, _iterpacket=0) for fvalue in fvalue_gen: s += fvalue._show_or_dump(dump=dump, indent=indent, label_lvl=label_lvl + lvl + " |", first_call=False) else: begn = "%s %-10s%s " % (label_lvl + lvl, ncol(f.name), ct.punct("="),) reprval = f.i2repr(self, fvalue) if type(reprval) is str: reprval = reprval.replace("\n", "\n" + " " * (len(label_lvl) + len(lvl) + len(f.name) + 4)) s += "%s%s\n" % (begn, vcol(reprval)) if self.payload: s += self.payload._show_or_dump(dump=dump, indent=indent, lvl=lvl + ( " " * indent * self.show_indent), label_lvl=label_lvl, first_call=False) if first_call and not dump: print s else: return s
def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, prn=lambda x: x): if not verbose: verbose = conf.verb if not isinstance(pkt, Gen): pkt = SetGen(pkt) tobesent = [p for p in pkt] stopevent = threading.Event() count_packets = six.moves.queue.Queue() def send_in_loop(tobesent, stopevent, count_packets=count_packets): """Infinite generator that produces the same packet until stopevent is triggered.""" while True: for p in tobesent: if stopevent.is_set(): raise StopIteration() count_packets.put(0) yield p infinite_gen = send_in_loop(tobesent, stopevent) # We don't use _sndrcv_snd verbose (it messes the logs up as in a thread that ends after recieving) thread = threading.Thread( target=_sndrcv_snd, args=(pks, None, inter, False, infinite_gen, stopevent), ) thread.start() hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, tobesent, stopevent, 0, len(tobesent), verbose, chainCC, False) thread.join() remain = list(itertools.chain(*six.itervalues(hsent))) # Apply prn ans = [(x, prn(y)) for (x, y) in ans] 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())) count_packets.empty() del count_packets return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
def __kb_send(kb, x, channel=None, inter=0, loop=0, count=None, verbose=None, realtime=None, *args, **kargs): if type(x) is str: x = Raw(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 dt0 = None try: while loop: for p in x: if realtime: ct = time.time() if dt0: st = dt0 + p.time - ct if st > 0: time.sleep(st) else: dt0 = ct - p.time # Make sure the packet has 2 bytes for FCS before TX if not p.haslayer(Dot15d4FCS): p /= Raw("\x00\x00") kb.inject(p.do_build()[:-2], channel=None, count=1, delay=0) # [:-2] because the firmware adds the FCS n += 1 if verbose: os.write(1, ".") time.sleep(inter) if loop < 0: loop += 1 except KeyboardInterrupt: pass return n
def haslayer(self, cls): """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax.""" if self.__class__ == cls or self.__class__.__name__ == cls: return 1 for f in self.packetfields: fvalue_gen = self.getfieldval(f.name) if fvalue_gen is None: continue if not f.islist: fvalue_gen = SetGen(fvalue_gen,_iterpacket=0) for fvalue in fvalue_gen: if isinstance(fvalue, Packet): ret = fvalue.haslayer(cls) if ret: return ret return self.payload.haslayer(cls)
def __kb_send(kb, x, channel=None, inter=0, loop=0, count=None, verbose=None, realtime=None, *args, **kargs): if type(x) is str: x = Raw(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 dt0 = None try: while loop: for p in x: if realtime: ct = time.time() if dt0: st = dt0 + p.time - ct if st > 0: time.sleep(st) else: dt0 = ct - p.time # Soteria: changed setting the channel to None to the input channel # kb.inject(p.do_build()[:-2], channel = None, count = 1, delay = 0) # [:-2] because the firmware adds the FCS kb.inject(p.do_build()[:-2], channel, count=1, delay=0) # [:-2] because the firmware adds the FCS n += 1 if verbose: os.write(1, ".") time.sleep(inter) if loop < 0: loop += 1 except KeyboardInterrupt: pass return n
def pkt_as_dict(pkt, indent=3, lvl="", label_lvl="", first_call=True): # based on scapy show() method # returns: dict of pkt attributes normally printed by show() plus time if first_call is True: ret = {} else: ret = first_call for f in pkt.fields_desc: if isinstance(f, ConditionalField) and not f._evalcond(pkt): continue fvalue = pkt.getfieldval(f.name) if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and isinstance(fvalue, list)): # noqa: E501 key = "{}_{}".format(label_lvl + lvl, f.name) fvalue_gen = SetGen(fvalue, _iterpacket=0) # type: SetGen[Packet] for fvalue in fvalue_gen: if key in keep_features: ret[key] = pkt_as_dict(fvalue, indent=indent, label_lvl=label_lvl + lvl + " |", first_call=ret) # noqa: E501 else: key = "{}_{}_{}".format(pkt.name, label_lvl + lvl, f.name) if isinstance(fvalue, str): fvalue = fvalue.replace( "\n", "\n" + " " * ( len(label_lvl) + # noqa: E501 len(lvl) + len(f.name) + 4)) if key in keep_features: ret[key] = fvalue if pkt.payload: pkt_as_dict( pkt.payload, indent=indent, lvl=lvl, # + (" " * indent * pkt.show_indent), label_lvl=label_lvl, first_call=ret) ret["time"] = float(pkt.time) return ret
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 sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False, retry=0, multi=False): if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.SndRcvList([]) nbrecv = 0 ans = [] # do it here to fix random fields, so that parent and child have the same tobesent = [p for p in pkt] notans = len(tobesent) hsent = {} for i in tobesent: h = i.hashret() hsent.setdefault(i.hashret(), []).append(i) if retry < 0: retry = -retry autostop = retry else: autostop = 0 if WINDOWS: def _get_pkt(): return pks.recv(MTU) elif conf.use_bpf: from scapy.arch.bpf.supersocket import bpf_select def _get_pkt(): if bpf_select([pks]): return pks.recv() elif conf.use_pcap or (not isinstance(pks, StreamSocket) and (DARWIN or FREEBSD or OPENBSD)): def _get_pkt(): res = pks.nonblock_recv() if res is None: time.sleep(0.05) return res else: def _get_pkt(): try: inp, _, _ = select([pks], [], [], 0.05) except (IOError, select_error) as exc: # select.error has no .errno attribute if exc.args[0] != errno.EINTR: raise else: if inp: return pks.recv(MTU) if stopevent.is_set(): raise _BreakException() while retry >= 0: if timeout < 0: timeout = None stopevent = threading.Event() thread = threading.Thread( target=_sndrcv_snd, args=(pks, timeout, inter, verbose, tobesent, stopevent), ) thread.start() try: try: while True: r = _get_pkt() if r is None: if stopevent.is_set(): break continue ok = False h = r.hashret() if h in hsent: hlst = hsent[h] for i, sentpkt in enumerate(hlst): if r.answers(sentpkt): ans.append((sentpkt, r)) if verbose > 1: os.write(1, b"*") ok = True if not multi: del hlst[i] notans -= 1 else: if not hasattr(sentpkt, '_answered'): notans -= 1 sentpkt._answered = 1 break if notans == 0 and not multi: break if not ok: if verbose > 1: os.write(1, b".") nbrecv += 1 if conf.debug_match: debug.recv.append(r) except KeyboardInterrupt: if chainCC: raise except _BreakException: pass finally: stopevent.set() thread.join() pks.close() 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 retry -= 1 if conf.debug_match: debug.sent = plist.PacketList(remain[:], "Sent") debug.match = plist.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)) return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
def sndrcvflood(pks, pkt, prn=lambda s_r: s_r[1].summary(), chainCC=0, store=1, unique=0): if not isinstance(pkt, Gen): pkt = SetGen(pkt) tobesent = [p for p in pkt] received = plist.SndRcvList() seen = {} hsent = {} for i in tobesent: h = i.hashret() if h in hsent: hsent[h].append(i) else: hsent[h] = [i] def send_in_loop(tobesent): while True: for p in tobesent: yield p packets_to_send = send_in_loop(tobesent) ssock = rsock = pks.fileno() try: while True: if conf.use_bpf: from scapy.arch.bpf.supersocket import bpf_select readyr = bpf_select([rsock]) _, readys, _ = select([], [ssock], []) else: readyr, readys, _ = select([rsock], [ssock], []) if ssock in readys: pks.send(packets_to_send.next()) if rsock in readyr: p = pks.recv(MTU) if p is None: continue h = p.hashret() if h in hsent: hlst = hsent[h] for i in hlst: if p.answers(i): res = prn((i, p)) if unique: if res in seen: continue seen[res] = None if res is not None: print(res) if store: received.append((i, p)) except KeyboardInterrupt: if chainCC: raise return received
def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0): if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([],"Unanswered") debug.sent = plist.PacketList([],"Sent") debug.match = plist.SndRcvList([]) nbrecv=0 ans = [] # do it here to fix random fields, so that parent and child have the same all_stimuli = tobesent = [p for p in pkt] notans = len(tobesent) hsent={} for i in tobesent: h = i.hashret() if h in hsent: hsent[h].append(i) else: hsent[h] = [i] if retry < 0: retry = -retry autostop=retry else: autostop=0 while retry >= 0: found=0 if timeout < 0: timeout = None pid=1 try: if WINDOWS or pid == 0: try: try: i = 0 if verbose: print("Begin emission:") for p in tobesent: pks.send(p) i += 1 time.sleep(inter) if verbose: print("Finished to send %i packets." % i) except SystemExit: pass except KeyboardInterrupt: pass except: log_runtime.exception("--- Error sending packets") log_runtime.info("--- Error sending packets") finally: try: sent_times = [p.sent_time for p in all_stimuli if p.sent_time] except: pass if WINDOWS or pid > 0: # Timeout starts after last packet is sent (as in Unix version) if timeout: stoptime = time.time()+timeout else: stoptime = 0 remaintime = None # inmask = [pks.ins.fd] try: try: while 1: if stoptime: remaintime = stoptime-time.time() if remaintime <= 0: break r = pks.recv(MTU) if r is None: continue ok = 0 h = r.hashret() if h in hsent: hlst = hsent[h] for i in range(len(hlst)): if r.answers(hlst[i]): ans.append((hlst[i],r)) if verbose > 1: os.write(1, b"*") ok = 1 if not multi: del(hlst[i]) notans -= 1; else: if not hasattr(hlst[i], '_answered'): notans -= 1; hlst[i]._answered = 1; break if notans == 0 and not multi: break if not ok: if verbose > 1: os.write(1, b".") nbrecv += 1 if conf.debug_match: debug.recv.append(r) except KeyboardInterrupt: if chainCC: raise finally: if WINDOWS: for p,t in zip(all_stimuli, sent_times): p.sent_time = t finally: pass # remain = reduce(list.__add__, hsent.values(), []) remain = list(itertools.chain(*[ i for i in hsent.values() ])) if multi: #remain = filter(lambda p: not hasattr(p, '_answered'), remain); 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 retry -= 1 if conf.debug_match: debug.sent=plist.PacketList(remain[:],"Sent") debug.match=plist.SndRcvList(ans[:]) #clean the ans list to delete the field _answered if (multi): for s,r in ans: if hasattr(s, '_answered'): del(s._answered) if verbose: print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)) return plist.SndRcvList(ans),plist.PacketList(remain,"Unanswered")
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 = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.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 = plist.PacketList(remain[:], "Sent") debug.match = plist.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 plist.SndRcvList(ans) unans_result = remain if use_prn_mode else ( None if not store_unanswered else plist.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): """Scapy raw function to send a packet and recieve its answer. WARNING: This is an internal function. Using sr/srp/sr1/srp is more appropriate in many cases. pks: SuperSocket instance to send/recieve packets pkt: the packet to send rcv_pks: if set, will be used instead of pks to recieve packets. packets will still 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 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""" if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.SndRcvList([]) nbrecv = 0 ans = [] # do it here to fix random fields, so that parent and child have the same tobesent = [p for p in pkt] notans = len(tobesent) if retry < 0: retry = -retry autostop = retry else: autostop = 0 while retry >= 0: if timeout is not None and timeout < 0: timeout = None stopevent = threading.Event() thread = threading.Thread( target=_sndrcv_snd, args=(pks, timeout, inter, verbose, tobesent, stopevent), ) thread.start() hsent, newans, nbrecv, notans = _sndrcv_rcv( (rcv_pks or pks), tobesent, stopevent, nbrecv, notans, verbose, chainCC, multi, ) thread.join() ans.extend(newans) 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 retry -= 1 if conf.debug_match: debug.sent = plist.PacketList(remain[:], "Sent") debug.match = plist.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)) return plist.SndRcvList(ans), plist.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 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 = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.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 = plist.PacketList(remain[:], "Sent") debug.match = plist.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 plist.SndRcvList(ans) unans_result = remain if use_prn_mode else (None if not store_unanswered else plist.PacketList(remain, "Unanswered")) # noqa: E501 return ans_result, unans_result
def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=0, retry=0, multi=0): if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.SndRcvList([]) nbrecv = 0 ans = [] # do it here to fix random fields, so that parent and child have the same all_stimuli = tobesent = [p for p in pkt] notans = len(tobesent) hsent = {} for i in tobesent: h = i.hashret() if h in hsent: hsent[h].append(i) else: hsent[h] = [i] if retry < 0: retry = -retry autostop = retry else: autostop = 0 while retry >= 0: found = 0 if timeout < 0: timeout = None rdpipe, wrpipe = os.pipe() rdpipe = os.fdopen(rdpipe) wrpipe = os.fdopen(wrpipe, "w") pid = 1 try: pid = os.fork() if pid == 0: try: sys.stdin.close() rdpipe.close() try: i = 0 if verbose: print "Begin emission:" for p in tobesent: pks.send(p) i += 1 time.sleep(inter) if verbose: print "Finished to send %i packets." % i except SystemExit: pass except KeyboardInterrupt: pass except: log_runtime.exception("--- Error in child %i" % os.getpid()) log_runtime.info("--- Error in child %i" % os.getpid()) finally: try: os.setpgrp() # Chance process group to avoid ctrl-C sent_times = [ p.sent_time for p in all_stimuli if p.sent_time ] cPickle.dump((conf.netcache, sent_times), wrpipe) wrpipe.close() except: pass elif pid < 0: log_runtime.error("fork error") else: wrpipe.close() stoptime = 0 remaintime = None inmask = [rdpipe, pks] try: try: while 1: if stoptime: remaintime = stoptime - time.time() if remaintime <= 0: break r = None if not isinstance( pks, StreamSocket) and (FREEBSD or DARWIN): inp, out, err = select(inmask, [], [], 0.05) if len(inp) == 0 or pks in inp: r = pks.nonblock_recv() else: inp = [] try: inp, out, err = select( inmask, [], [], remaintime) except IOError, exc: if exc.errno != errno.EINTR: raise if len(inp) == 0: break if pks in inp: r = pks.recv(MTU) if rdpipe in inp: if timeout: stoptime = time.time() + timeout del (inmask[inmask.index(rdpipe)]) if r is None: continue ok = 0 h = r.hashret() if h in hsent: hlst = hsent[h] for i, sentpkt in enumerate(hlst): if r.answers(sentpkt): ans.append((sentpkt, r)) if verbose > 1: os.write(1, "*") ok = 1 if not multi: del hlst[i] notans -= 1 else: if not hasattr( sentpkt, '_answered'): notans -= 1 sentpkt._answered = 1 break if notans == 0 and not multi: break if not ok: if verbose > 1: os.write(1, ".") nbrecv += 1 if conf.debug_match: debug.recv.append(r) except KeyboardInterrupt: if chainCC: raise finally: try: nc, sent_times = cPickle.load(rdpipe) except EOFError: warning( "Child died unexpectedly. Packets may have not been sent %i" % os.getpid()) else: conf.netcache.update(nc) for p, t in zip(all_stimuli, sent_times): p.sent_time = t os.waitpid(pid, 0) finally: if pid == 0: os._exit(0) remain = list(itertools.chain(*hsent.itervalues())) 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 retry -= 1 if conf.debug_match: debug.sent = plist.PacketList(remain[:], "Sent") debug.match = plist.SndRcvList(ans[:]) #clean the ans list to delete the field _answered if (multi): for s, r in ans: if hasattr(s, '_answered'): del (s._answered) if verbose: print "\nReceived %i packets, got %i answers, remaining %i packets" % ( nbrecv + len(ans), len(ans), notans) return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
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 __gen_send_mod(s, x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, port_random_flag=False, size_random_flag=False, src_random_flag=False, specific_subnet_random=False, source_addr='Default', pcktcount=None, log=None, *args, **kargs): # noqa: E501 totaltimeelapsedns = 0.0 totaltimeelapseds = 0.0 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: startVelkoSec = time.time() while loop: dt0 = None for p in x: if realtime: ct = time.time() if dt0: st = dt0 + p.time - ct if st > 0: time.sleep(st) else: dt0 = ct - p.time if (p.proto == 1): p.type = int(random.randrange(0, 255)) p.code = int(random.randrange(0, 255)) if (port_random_flag): targ_port = int(random.randrange(0, 65535)) p.dport = targ_port if (size_random_flag): packet_size = int( random.randrange(0, 6550) ) # 7 I removed 7 because there seems to be some boundary crossing(bleeding) p.add_payload((str(_generatePacket(packet_size))).encode()) if (src_random_flag): p.src = socket.inet_ntoa( struct.pack('>I', random.randint(1, 0xffffffff))) elif (specific_subnet_random): try: subnet = IPv4Network(source_addr) bits = random.getrandbits(subnet.max_prefixlen - subnet.prefixlen) p.src = str(IPv4Address(subnet.network_address + bits)) except ValueError: print("Something is wrong!sendrcv ") if ((n % int(pcktcount)) == 0): endVelkoSec = time.time() totaltimeelapseds += (endVelkoSec - startVelkoSec) print("\n+++TIMESTAMP+++\nTimestamp taken after:", n, "packets") #print('{:%Y-%m-%d_%H:%M:%S}'.format(datetime.datetime.now())+"\n") print((datetime.datetime.now() ).strftime('%Y-%m-%d %H:%M:%S.%f')[:-2] + " (UTC)\n") print("TIME(s): ", (endVelkoSec - startVelkoSec)) print("TIME(ns): ", (endVelkoSec - startVelkoSec) * 1000000000) print("TOTAL TIME(s): ", totaltimeelapseds) print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++\n" ) #LOG SECTION # file_name=log # f = open(file_name, 'a+') # f.write("\n+++TIMESTAMP+++\nTimestamp taken after: "+str(n)+"\n") # f.write(datetime.datetime.utcnow().strftime('%Y-%m-%d %H-%M-%S_%f')[:-2]+" (UTC)\n") # f.write("TIME(ns): "+str((endVelkoSec - startVelkoSec)*1000000000)+"\n") # f.write("TIME(s): "+ str(endVelkoSec-startVelkoSec)+"\n") # f.write("TOTAL TIME ELAPSED(s): "+str(totaltimeelapseds)+"\n") # f.write("\n===WholePacket===\n") # tmp=p.show(dump=True) # f.write(str(tmp)) # f.close() # TODO: Should log only if log is activated #log_packet(p,log) #END LOG SECTION s.send(p) if (p.proto == 1): print( datetime.datetime.utcnow().strftime( '%Y-%m-%d_%H-%M-%S_%f')[:-2] + "(UTC)\t", "proto", p.proto, "\tsrc", p.src, "\tdst", p.dst, "\tcode", p.code, "\ttype", p.type, "\tLength(b)", len(p)) else: print( datetime.datetime.utcnow().strftime( '%Y-%m-%d_%H-%M-%S_%f')[:-2] + "(UTC)\t", "proto", p.proto, "\tsrc", p.src, "\tsport", p.sport, "\tdst", p.dst, "\tdport", p.dport, "\tLength(b)", len(p)) # time.sleep(5) 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
def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False, retry=0, multi=False): if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.SndRcvList([]) nbrecv = 0 ans = [] # do it here to fix random fields, so that parent and child have the same tobesent = [p for p in pkt] notans = len(tobesent) if retry < 0: retry = -retry autostop = retry else: autostop = 0 while retry >= 0: if timeout is not None and timeout < 0: timeout = None stopevent = threading.Event() thread = threading.Thread( target=_sndrcv_snd, args=(pks, timeout, inter, verbose, tobesent, stopevent), ) thread.start() hsent, newans, nbrecv, notans = _sndrcv_rcv( pks, tobesent, stopevent, nbrecv, notans, verbose, chainCC, multi, ) thread.join() ans.extend(newans) 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 retry -= 1 if conf.debug_match: debug.sent = plist.PacketList(remain[:], "Sent") debug.match = plist.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)) return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
def kbgetnetworkkey(pkts): """ Search packets for a plaintext key exchange returns the first one found. """ if not isinstance(pkts, Gen): pkts = SetGen(pkts) for packet in pkts: packet = str(packet) zmac = Dot154PacketParser() znwk = ZigBeeNWKPacketParser() zaps = ZigBeeAPSPacketParser() try: # Process MAC layer details zmacpayload = zmac.pktchop(packet)[-1] if zmacpayload == None: continue # Process NWK layer details znwkpayload = znwk.pktchop(zmacpayload)[-1] if znwkpayload == None: continue # Process the APS layer details zapschop = zaps.pktchop(znwkpayload) if zapschop == None: continue # See if this is an APS Command frame apsfc = ord(zapschop[0]) if (apsfc & ZBEE_APS_FCF_FRAME_TYPE) != ZBEE_APS_FCF_CMD: continue # Delivery mode is Normal Delivery (0) apsdeliverymode = (apsfc & ZBEE_APS_FCF_DELIVERY_MODE) >> 2 if apsdeliverymode != 0: continue # Ensure Security is Disabled if (apsfc & ZBEE_APS_FCF_SECURITY) == 1: continue zapspayload = zapschop[-1] # Check payload length, must be at least 35 bytes # APS cmd | key type | key | sequence number | dest addr | src addr if len(zapspayload) < 35: continue # Check for APS command identifier Transport Key (0x05) if ord(zapspayload[0]) != 5: continue # Transport Key Frame, get the key type. Network Key is 0x01, no # other keys should be sent in plaintext if ord(zapspayload[1]) != 1: continue # Reverse these fields networkkey = zapspayload[2:18][::-1] destaddr = zapspayload[19:27][::-1] srcaddr = zapspayload[27:35][::-1] key_bytes = [] dst_mac_bytes = [] src_mac_bytes = [] key = {} key['key'] = ':'.join("%02x" % ord(networkkey[x]) for x in xrange(16)) key['dst'] = ':'.join("%02x" % ord(destaddr[x]) for x in xrange(8)) key['src'] = ':'.join("%02x" % ord(srcaddr[x]) for x in xrange(8)) return key except: continue return {}
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 sent_packets = PacketList() if return_packets else None p = None 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 sent_packets is not None: sent_packets.append(p) n += 1 if verbose: os.write(1, b".") time.sleep(inter) if loop < 0: loop += 1 except KeyboardInterrupt: pass finally: try: cast(Packet, x).sent_time = cast(Packet, p).sent_time except AttributeError: pass if verbose: print("\nSent %i packets." % n) return sent_packets