def __repr__(self): if len(self.val) <= 16: v = plain_str(self.val) return "<%s[%s] (%d unused bit%s)>" % (self.__dict__.get("name", self.__class__.__name__), v, self.unused_bits, "s" if self.unused_bits > 1 else "") # noqa: E501 else: s = self.val_readable if len(s) > 20: s = s[:10] + b"..." + s[-10:] v = plain_str(self.val) return "<%s[%s] (%d unused bit%s)>" % (self.__dict__.get("name", self.__class__.__name__), v, self.unused_bits, "s" if self.unused_bits > 1 else "") # noqa: E501
def _parse_tcpreplay_result(stdout, stderr, argv): """ Parse the output of tcpreplay and modify the results_dict to populate output information. # noqa: E501 Tested with tcpreplay v3.4.4 Tested with tcpreplay v4.1.2 :param stdout: stdout of tcpreplay subprocess call :param stderr: stderr of tcpreplay subprocess call :param argv: the command used in the subprocess call :return: dictionary containing the results """ try: results = {} stdout = plain_str(stdout).lower() stderr = plain_str(stderr).strip().split("\n") elements = { "actual": (int, int, float), "rated": (float, float, float), "flows": (int, float, int, int), "attempted": (int,), "successful": (int,), "failed": (int,), "truncated": (int,), "retried packets (eno": (int,), "retried packets (eag": (int,), } multi = { "actual": ("packets", "bytes", "time"), "rated": ("bps", "mbps", "pps"), "flows": ("flows", "fps", "flow_packets", "non_flow"), "retried packets (eno": ("retried_enobufs",), "retried packets (eag": ("retried_eagain",), } float_reg = r"([0-9]*\.[0-9]+|[0-9]+)" int_reg = r"([0-9]+)" any_reg = r"[^0-9]*" r_types = {int: int_reg, float: float_reg} for line in stdout.split("\n"): line = line.strip() for elt, _types in elements.items(): if line.startswith(elt): regex = any_reg.join([r_types[x] for x in _types]) matches = re.search(regex, line) for i, typ in enumerate(_types): name = multi.get(elt, [elt])[i] results[name] = typ(matches.group(i + 1)) results["command"] = " ".join(argv) results["warnings"] = stderr[:-1] return results except Exception as parse_exception: if not conf.interactive: raise log_runtime.error("Error parsing output: " + str(parse_exception)) return {}
def _parse_whois(self, txt): asn, desc = None, b"" for line in txt.splitlines(): if not asn and line.startswith(b"origin:"): asn = plain_str(line[7:].strip()) if line.startswith(b"descr:"): if desc: desc += r"\n" desc += line[6:].strip() if asn is not None and desc: break return asn, plain_str(desc.strip())
def lazy_init(self): try: fdesc = open(conf.nmap_base if self.filename is None else self.filename, "rb") except (IOError, TypeError): warning("Cannot open nmap database [%s]", self.filename) self.filename = None return self.base = [] name = None sig = {} for line in fdesc: line = plain_str(line) line = line.split('#', 1)[0].strip() if not line: continue if line.startswith("Fingerprint "): if name is not None: self.base.append((name, sig)) name = line[12:].strip() sig = {} continue if line.startswith("Class "): continue line = _NMAP_LINE.search(line) if line is None: continue test, values = line.groups() sig[test] = dict(val.split('=', 1) for val in (values.split('%') if values else [])) if name is not None: self.base.append((name, sig)) fdesc.close()
def in6_getifaddr(): """ Returns a list of 3-tuples of the form (addr, scope, iface) where 'addr' is the address of scope 'scope' associated to the interface 'ifcace'. This is the list of all addresses of all interfaces available on the system. """ ret = [] try: fdesc = open("/proc/net/if_inet6", "rb") except IOError: return ret for line in fdesc: # addr, index, plen, scope, flags, ifname tmp = plain_str(line).split() addr = scapy.utils6.in6_ptop( b':'.join( struct.unpack('4s4s4s4s4s4s4s4s', tmp[0].encode()) ).decode() ) # (addr, scope, iface) ret.append((addr, int(tmp[3], 16), tmp[5])) fdesc.close() return ret
def get_subject(self): attrs = self.subject attrsDict = {} for attr in attrs: # we assume there is only one name in each rdn ASN1_SET attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501 return attrsDict
def network_stats(self): """Return a dictionary containing a summary of the Dot11 elements fields """ summary = {} crypto = set() p = self.payload while isinstance(p, Dot11Elt): if p.ID == 0: summary["ssid"] = plain_str(p.info) elif p.ID == 3: summary["channel"] = ord(p.info) elif isinstance(p, Dot11EltRates): summary["rates"] = p.rates elif isinstance(p, Dot11EltRSN): crypto.add("WPA2") elif p.ID == 221: if isinstance(p, Dot11EltMicrosoftWPA) or \ p.info.startswith('\x00P\xf2\x01\x01\x00'): crypto.add("WPA") p = p.payload if not crypto: if self.cap.privacy: crypto.add("WEP") else: crypto.add("OPN") summary["crypto"] = crypto return summary
def load_winpcapy(): """This functions calls Winpcap/Npcap pcap_findalldevs function, and extracts and parse all the data scapy will need to use it: - the Interface List This data is stored in their respective conf.cache_* subfields: conf.cache_iflist """ err = create_string_buffer(PCAP_ERRBUF_SIZE) devs = POINTER(pcap_if_t)() if_list = {} if pcap_findalldevs(byref(devs), err) < 0: return try: p = devs # Iterate through the different interfaces while p: name = plain_str(p.contents.name) # GUID description = plain_str(p.contents.description) # NAME ips = [] a = p.contents.addresses while a: # IPv4 address family = a.contents.addr.contents.sa_family ap = a.contents.addr if family == socket.AF_INET: val = cast(ap, POINTER(sockaddr_in)) val = val.contents.sin_addr[:] elif family == socket.AF_INET6: val = cast(ap, POINTER(sockaddr_in6)) val = val.contents.sin6_addr[:] else: # Unknown address family # (AF_LINK isn't a thing on Windows) a = a.contents.next continue addr = inet_ntop(family, bytes(bytearray(val))) if addr != "0.0.0.0": ips.append(addr) a = a.contents.next if_list[description] = (name, ips) p = p.contents.next conf.cache_iflist = if_list except Exception: raise finally: pcap_freealldevs(devs)
def load_manuf(filename): manufdb = ManufDA(_name=filename) with open(filename, "rb") as fdesc: for line in fdesc: try: line = line.strip() if not line or line.startswith(b"#"): continue oui, shrt = line.split()[:2] i = line.find(b"#") if i < 0: lng = shrt else: lng = line[i + 2:] manufdb[oui] = plain_str(shrt), plain_str(lng) except Exception: log_loading.warning("Couldn't parse one line from [%s] [%r]", filename, line, exc_info=True) return manufdb
def load_manuf(filename): """Load manuf file from Wireshark. param: - filename: the file to load the manuf file from""" manufdb = ManufDA(_name=filename) with open(filename, "rb") as fdesc: for line in fdesc: try: line = line.strip() if not line or line.startswith(b"#"): continue parts = line.split(None, 2) oui, shrt = parts[:2] lng = parts[2].lstrip(b"#").strip() if len(parts) > 2 else "" lng = lng or shrt manufdb[oui] = plain_str(shrt), plain_str(lng) except Exception: log_loading.warning("Couldn't parse one line from [%s] [%r]", filename, line, exc_info=True) return manufdb
def read_routes6(): try: f = open("/proc/net/ipv6_route", "rb") except IOError: return [] # 1. destination network # 2. destination prefix length # 3. source network displayed # 4. source prefix length # 5. next hop # 6. metric # 7. reference counter (?!?) # 8. use counter (?!?) # 9. flags # 10. device name routes = [] def proc2r(p): ret = struct.unpack('4s4s4s4s4s4s4s4s', raw(p)) ret = b':'.join(ret).decode() return scapy.utils6.in6_ptop(ret) lifaddr = in6_getifaddr() for line in f.readlines(): line = plain_str(line) d, dp, s, sp, nh, metric, rc, us, fl, dev = line.split() metric = int(metric, 16) fl = int(fl, 16) if fl & RTF_UP == 0: continue if fl & RTF_REJECT: continue d = proc2r(d) dp = int(dp, 16) s = proc2r(s) sp = int(sp, 16) nh = proc2r(nh) cset = [] # candidate set (possible source addresses) if dev == LOOPBACK_NAME: if d == '::': continue cset = ['::1'] else: devaddrs = (x for x in lifaddr if x[2] == dev) cset = scapy.utils6.construct_source_candidate_set(d, dp, devaddrs) if len(cset) != 0: routes.append((d, dp, nh, dev, cset, metric)) f.close() return routes
def get_iface_mode(iface): """Return the interface mode. params: - iface: the iwconfig interface """ p = subprocess.Popen(["iwconfig", iface], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output, err = p.communicate() match = re.search(br"mode:([a-zA-Z]*)", output.lower()) if match: return plain_str(match.group(1)) return "unknown"
def m2i(self, pkt, s): ret_s = "" tmp_s = plain_str(s) while tmp_s: tmp_len = orb(tmp_s[0]) + 1 if tmp_len > len(tmp_s): warning("APN prematured end of character-string (size=%i, remaining bytes=%i)" % (tmp_len, len(tmp_s))) ret_s += tmp_s[1:tmp_len] tmp_s = tmp_s[tmp_len:] if len(tmp_s) : ret_s += "." s = ret_s return s
def load_winpcapy(): err = create_string_buffer(PCAP_ERRBUF_SIZE) devs = POINTER(pcap_if_t)() if_list = [] ip_addresses = {} ip6_addresses = [] if pcap_findalldevs(byref(devs), err) < 0: return try: p = devs # Iterate through the different interfaces while p: if_list.append(plain_str(p.contents.name)) a = p.contents.addresses while a: # IPv4 address if a.contents.addr.contents.sa_family == socket.AF_INET: # noqa: E501 ap = a.contents.addr val = cast(ap, POINTER(sockaddr_in)) if_raw_addr = b"".join(chb(x) for x in val.contents.sin_addr[:4]) # noqa: E501 if if_raw_addr != b'\x00\x00\x00\x00': ip_addresses[plain_str(p.contents.name)] = if_raw_addr # noqa: E501 # IPv6 address if a.contents.addr.contents.sa_family == socket.AF_INET6: # noqa: E501 ap = a.contents.addr val = cast(ap, POINTER(sockaddr_in6)) addr = inet_ntop(socket.AF_INET6, b"".join(chb(x) for x in val.contents.sin6_addr[:])) # noqa: E501 scope = scapy.utils6.in6_getscope(addr) ip6_addresses.append((addr, scope, plain_str(p.contents.name))) # noqa: E501 a = a.contents.next p = p.contents.next conf.cache_iflist = if_list conf.cache_ipaddrs = ip_addresses conf.cache_in6_getifaddr = ip6_addresses except Exception: raise finally: pcap_freealldevs(devs)
def parse(self, data): """Parse bulk cymru data""" ASNlist = [] for line in data.splitlines()[1:]: line = plain_str(line) if "|" not in line: continue asn, ip, desc = [elt.strip() for elt in line.split('|')] if asn == "NA": continue asn = "AS%s" % asn ASNlist.append((ip, asn, desc)) return ASNlist
def get_alias_address(iface_name, ip_mask, gw_str, metric): """ Get the correct source IP address of an interface alias """ # Detect the architecture if scapy.consts.IS_64BITS: offset, name_len = 16, 40 else: offset, name_len = 32, 32 # Retrieve interfaces structures sck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) names = array.array('B', b'\0' * 4096) ifreq = ioctl(sck.fileno(), SIOCGIFCONF, struct.pack("iL", len(names), names.buffer_info()[0])) # Extract interfaces names out = struct.unpack("iL", ifreq)[0] names = names.tobytes() if six.PY3 else names.tostring() names = [names[i:i + offset].split(b'\0', 1)[0] for i in range(0, out, name_len)] # noqa: E501 # Look for the IP address for ifname in names: # Only look for a matching interface name if not ifname.decode("utf8").startswith(iface_name): continue # Retrieve and convert addresses ifreq = ioctl(sck, SIOCGIFADDR, struct.pack("16s16x", ifname)) ifaddr = struct.unpack(">I", ifreq[20:24])[0] ifreq = ioctl(sck, SIOCGIFNETMASK, struct.pack("16s16x", ifname)) msk = struct.unpack(">I", ifreq[20:24])[0] # Get the full interface name ifname = plain_str(ifname) if ':' in ifname: ifname = ifname[:ifname.index(':')] else: continue # Check if the source address is included in the network if (ifaddr & msk) == ip_mask: sck.close() return (ifaddr & msk, msk, gw_str, ifname, scapy.utils.ltoa(ifaddr), metric) sck.close() return
def get_if_list(): try: f = open("/proc/net/dev", "rb") except IOError: f.close() warning("Can't open /proc/net/dev !") return [] lst = [] f.readline() f.readline() for line in f: line = plain_str(line) lst.append(line.split(":")[0].strip()) f.close() return lst
def __setattr__(self, name, value): if isinstance(value, bytes): value = plain_str(value) if name == "val": pretty_time = None if (isinstance(value, str) and len(value) == 15 and value[-1] == "Z"): dt = datetime.strptime(value[:-1], "%Y%m%d%H%M%S") pretty_time = dt.strftime("%b %d %H:%M:%S %Y GMT") else: pretty_time = "%s [invalid generalized_time]" % value super(ASN1_GENERALIZED_TIME, self).__setattr__("pretty_time", pretty_time) # noqa: E501 super(ASN1_GENERALIZED_TIME, self).__setattr__(name, value) elif name == "pretty_time": print("Invalid operation: pretty_time rewriting is not supported.") else: super(ASN1_GENERALIZED_TIME, self).__setattr__(name, value)
def __setattr__(self, name, value): if isinstance(value, bytes): value = plain_str(value) if name == "val": pretty_time = None if (isinstance(value, str) and len(value) == 13 and value[-1] == "Z"): dt = datetime.strptime(value[:-1], "%y%m%d%H%M%S") pretty_time = dt.strftime("%b %d %H:%M:%S %Y GMT") else: pretty_time = "%s [invalid utc_time]" % value super(ASN1_UTC_TIME, self).__setattr__("pretty_time", pretty_time) super(ASN1_UTC_TIME, self).__setattr__(name, value) elif name == "pretty_time": print("Invalid operation: pretty_time rewriting is not supported.") else: super(ASN1_UTC_TIME, self).__setattr__(name, value)
def run_test(test, get_interactive_session, theme, verb=3, ignore_globals=None, my_globals=None): """An internal UTScapy function to run a single test""" start_time = time.time() test.output, res = get_interactive_session(test.test.strip(), ignore_globals=ignore_globals, verb=verb, my_globals=my_globals) test.result = "failed" try: if res is None or res: test.result = "passed" if test.output.endswith('KeyboardInterrupt\n'): test.result = "interrupted" raise KeyboardInterrupt except Exception: test.output += "UTscapy: Error during result interpretation:\n" test.output += "".join( traceback.format_exception( sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], )) finally: test.duration = time.time() - start_time if test.result == "failed": from scapy.sendrecv import debug # Add optional debugging data to log if debug.crashed_on: cls, val = debug.crashed_on test.output += "\n\nPACKET DISSECTION FAILED ON:\n %s(hex_bytes('%s'))" % ( cls.__name__, plain_str(bytes_hex(val))) debug.crashed_on = None test.prepare(theme) if verb > 2: print("%(fresult)6s %(crc)s %(duration)06.2fs %(name)s" % test, file=sys.stderr) elif verb > 1: print("%(fresult)6s %(crc)s %(name)s" % test, file=sys.stderr) return bool(test)
def get_if_list(): try: f = open("/proc/net/dev", "rb") except IOError: try: f.close() except Exception: pass warning("Can't open /proc/net/dev !") return [] lst = [] f.readline() f.readline() for line in f: line = plain_str(line) lst.append(line.split(":")[0].strip()) f.close() return lst
def recvall(self, size=8192 * 4, timeout=None): """Receive all data available during timeout from DTLS connection.""" resp = [] if timeout: self._sock.settimeout(timeout) while True: try: data = self._sock.recvfrom(size) if not data: break plain_data = plain_str(data[0]) resp.append(plain_data) # print("recvall - chunk size = {}".format(len(data[0]))) except socket.timeout: break # print(resp) resp_packet = DTLS("".join(resp)) # resp_packet.show() return resp_packet
def __setattr__(self, name, value): str_value = None if isinstance(value, str): str_value = value value = raw(value) if name == "val_readable": if isinstance(value, bytes): val = b"".join( binrepr(orb(x)).zfill(8).encode("utf8") for x in value) # noqa: E501 else: val = "<invalid val_readable>" super(ASN1_Object, self).__setattr__("val", val) super(ASN1_Object, self).__setattr__(name, value) super(ASN1_Object, self).__setattr__("unused_bits", 0) elif name == "val": if not str_value: str_value = plain_str(value) if isinstance(value, bytes): if any(c for c in str_value if c not in ["0", "1"]): print("Invalid operation: 'val' is not a valid bit string." ) # noqa: E501 return else: if len(value) % 8 == 0: unused_bits = 0 else: unused_bits = 8 - (len(value) % 8) padded_value = str_value + ("0" * unused_bits) bytes_arr = zip(*[iter(padded_value)] * 8) val_readable = b"".join( chb(int("".join(x), 2)) for x in bytes_arr) # noqa: E501 else: val_readable = "<invalid val>" unused_bits = 0 super(ASN1_Object, self).__setattr__("val_readable", val_readable) super(ASN1_Object, self).__setattr__(name, value) super(ASN1_Object, self).__setattr__("unused_bits", unused_bits) elif name == "unused_bits": print("Invalid operation: unused_bits rewriting is not supported.") else: super(ASN1_Object, self).__setattr__(name, value)
def __setattr__(self, name, value): # type: (str, Any) -> None if name == "val_readable": if isinstance(value, (str, bytes)): val = "".join(binrepr(orb(x)).zfill(8) for x in value) else: warning("Invalid val: should be bytes") val = "<invalid val_readable>" object.__setattr__(self, "val", val) object.__setattr__(self, name, bytes_encode(value)) object.__setattr__(self, "unused_bits", 0) elif name == "val": value = plain_str(value) if isinstance(value, str): if any(c for c in value if c not in ["0", "1"]): warning( "Invalid operation: 'val' is not a valid bit string." ) # noqa: E501 return else: if len(value) % 8 == 0: unused_bits = 0 else: unused_bits = 8 - (len(value) % 8) padded_value = value + ("0" * unused_bits) bytes_arr = zip(*[iter(padded_value)] * 8) val_readable = b"".join( chb(int("".join(x), 2)) for x in bytes_arr) # noqa: E501 else: warning("Invalid val: should be str") val_readable = b"<invalid val>" unused_bits = 0 object.__setattr__(self, "val_readable", val_readable) object.__setattr__(self, name, value) object.__setattr__(self, "unused_bits", unused_bits) elif name == "unused_bits": warning("Invalid operation: unused_bits rewriting " "is not supported.") else: object.__setattr__(self, name, value)
def _extcap_call(prog, args, keyword, values): """Function used to call a program using the extcap format, then parse the results""" p = subprocess.Popen( [prog] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) data, err = p.communicate() if p.returncode != 0: raise OSError("%s returned with error code %s: %s" % (prog, p.returncode, err)) data = plain_str(data) res = [] for ifa in data.split("\n"): ifa = ifa.strip() if not ifa.startswith(keyword): continue res.append(tuple([re.search(r"{%s=([^}]*)}" % val, ifa).group(1) for val in values])) return res
def _get_if_list(): """ Function to read the interfaces from /proc/net/dev """ try: f = open("/proc/net/dev", "rb") except IOError: try: f.close() except Exception: pass log_loading.critical("Can't open /proc/net/dev !") return [] lst = [] f.readline() f.readline() for line in f: line = plain_str(line) lst.append(line.split(":")[0].strip()) f.close() return lst
def _mib_register(ident, value, the_mib, unresolved): """Internal function used to register an OID and its name in a MIBDict""" if ident in the_mib or ident in unresolved: return ident in the_mib resval = [] not_resolved = 0 for v in value: if _mib_re_integer.match(v): resval.append(v) else: v = fixname(plain_str(v)) if v not in the_mib: not_resolved = 1 if v in the_mib: v = the_mib[v] elif v in unresolved: v = unresolved[v] if isinstance(v, list): resval += v else: resval.append(v) if not_resolved: unresolved[ident] = resval return False else: the_mib[ident] = resval keys = list(unresolved) i = 0 while i < len(keys): k = keys[i] if _mib_register(k, unresolved[k], the_mib, {}): del (unresolved[k]) del (keys[i]) i = 0 else: i += 1 return True
def __setattr__(self, name, value): str_value = None if isinstance(value, str): str_value = value value = raw(value) if name == "val_readable": if isinstance(value, bytes): val = b"".join(binrepr(orb(x)).zfill(8).encode("utf8") for x in value) # noqa: E501 else: val = "<invalid val_readable>" super(ASN1_Object, self).__setattr__("val", val) super(ASN1_Object, self).__setattr__(name, value) super(ASN1_Object, self).__setattr__("unused_bits", 0) elif name == "val": if not str_value: str_value = plain_str(value) if isinstance(value, bytes): if any(c for c in str_value if c not in ["0", "1"]): print("Invalid operation: 'val' is not a valid bit string.") # noqa: E501 return else: if len(value) % 8 == 0: unused_bits = 0 else: unused_bits = 8 - (len(value) % 8) padded_value = str_value + ("0" * unused_bits) bytes_arr = zip(*[iter(padded_value)] * 8) val_readable = b"".join(chb(int("".join(x), 2)) for x in bytes_arr) # noqa: E501 else: val_readable = "<invalid val>" unused_bits = 0 super(ASN1_Object, self).__setattr__("val_readable", val_readable) super(ASN1_Object, self).__setattr__(name, value) super(ASN1_Object, self).__setattr__("unused_bits", unused_bits) elif name == "unused_bits": print("Invalid operation: unused_bits rewriting is not supported.") else: super(ASN1_Object, self).__setattr__(name, value)
def _mib_register(ident, value, the_mib, unresolved): """Internal function used to register an OID and its name in a MIBDict""" if ident in the_mib or ident in unresolved: return ident in the_mib resval = [] not_resolved = 0 for v in value: if _mib_re_integer.match(v): resval.append(v) else: v = fixname(plain_str(v)) if v not in the_mib: not_resolved = 1 if v in the_mib: v = the_mib[v] elif v in unresolved: v = unresolved[v] if isinstance(v, list): resval += v else: resval.append(v) if not_resolved: unresolved[ident] = resval return False else: the_mib[ident] = resval keys = list(unresolved) i = 0 while i < len(keys): k = keys[i] if _mib_register(k, unresolved[k], the_mib, {}): del(unresolved[k]) del(keys[i]) i = 0 else: i += 1 return True
def in6_getifaddr(): """ Returns a list of 3-tuples of the form (addr, scope, iface) where 'addr' is the address of scope 'scope' associated to the interface 'iface'. This is the list of all addresses of all interfaces available on the system. """ ret = [] try: fdesc = open("/proc/net/if_inet6", "rb") except IOError: return ret for line in fdesc: # addr, index, plen, scope, flags, ifname tmp = plain_str(line).split() addr = scapy.utils6.in6_ptop(b':'.join( struct.unpack('4s4s4s4s4s4s4s4s', tmp[0].encode())).decode()) # (addr, scope, iface) ret.append((addr, int(tmp[3], 16), tmp[5])) fdesc.close() return ret
def lazy_init(self): try: fdesc = open( conf.nmap_base if self.filename is None else self.filename, "rb") except (IOError, TypeError): warning("Cannot open nmap database [%s]", self.filename) self.filename = None return self.base = [] name = None sig = {} for line in fdesc: line = plain_str(line) line = line.split('#', 1)[0].strip() if not line: continue if line.startswith("Fingerprint "): if name is not None: self.base.append((name, sig)) name = line[12:].strip() sig = {} continue if line.startswith("Class "): continue line = _NMAP_LINE.search(line) if line is None: continue test, values = line.groups() sig[test] = dict( val.split('=', 1) for val in (values.split('%') if values else [])) if name is not None: self.base.append((name, sig)) fdesc.close()
def __setattr__(self, name, value): if isinstance(value, bytes): value = plain_str(value) if name == "val": pretty_time = None if isinstance(self, ASN1_GENERALIZED_TIME): _len = 15 self._format = "%Y%m%d%H%M%S" else: _len = 13 self._format = "%y%m%d%H%M%S" _nam = self.tag._asn1_obj.__name__[4:].lower() if (isinstance(value, str) and len(value) == _len and value[-1] == "Z"): dt = datetime.strptime(value[:-1], self._format) pretty_time = dt.strftime("%b %d %H:%M:%S %Y GMT") else: pretty_time = "%s [invalid %s]" % (value, _nam) ASN1_STRING.__setattr__(self, "pretty_time", pretty_time) ASN1_STRING.__setattr__(self, name, value) elif name == "pretty_time": print("Invalid operation: pretty_time rewriting is not supported.") else: ASN1_STRING.__setattr__(self, name, value)
def _inet6_ntop(addr): """Convert an IPv6 address from binary form into text representation, used when socket.inet_pton is not available. """ # IPv6 addresses have 128bits (16 bytes) if len(addr) != 16: raise ValueError("invalid length of packed IP address string") # Decode to hex representation address = ":".join(plain_str(bytes_hex(addr[idx:idx + 2])).lstrip('0') or '0' # noqa: E501 for idx in range(0, 16, 2)) try: # Get the longest set of zero blocks. We need to take a look # at group 1 regarding the length, as 0:0:1:0:0:2:3:4 would # have two matches: 0:0: and :0:0: where the latter is longer, # though the first one should be taken. Group 1 is in both # cases 0:0. match = max(_IP6_ZEROS.finditer(address), key=lambda m: m.end(1) - m.start(1)) return '{}::{}'.format(address[:match.start()], address[match.end():]) except ValueError: return address
def __setattr__(self, name, value): if isinstance(value, bytes): value = plain_str(value) if name == "val": pretty_time = None if isinstance(self, ASN1_GENERALIZED_TIME): _len = 15 _format = "%Y%m%d%H%M%S" else: _len = 13 _format = "%y%m%d%H%M%S" _nam = self.tag._asn1_obj.__name__[4:].lower() if (isinstance(value, str) and len(value) == _len and value[-1] == "Z"): dt = datetime.strptime(value[:-1], _format) pretty_time = dt.strftime("%b %d %H:%M:%S %Y GMT") else: pretty_time = "%s [invalid %s]" % (value, _nam) ASN1_STRING.__setattr__(self, "pretty_time", pretty_time) ASN1_STRING.__setattr__(self, name, value) elif name == "pretty_time": print("Invalid operation: pretty_time rewriting is not supported.") else: ASN1_STRING.__setattr__(self, name, value)
def _npcap_get(self, key): res, code = _exec_cmd(" ".join([_WlanHelper, self.guid[1:-1], key])) _windows_title() # Reset title of the window if code != 0: raise OSError(res.decode("utf8", errors="ignore")) return plain_str(res.strip())
def __str__(self): return plain_str(self._fix())
def fixname(self, val): return plain_str(val)
def _strip_header_name(name): """Takes a header key (i.e., "Host" in "Host: www.google.com", and returns a stripped representation of it """ return plain_str(name.strip()).replace("-", "_")
def __init__(self, val): val = conf.mib._oid(plain_str(val)) ASN1_Object.__init__(self, val) self.oidname = conf.mib._oidname(val)
def h2i(self, pkt, x): from scapy.compat import plain_str return plain_str(x).encode('utf-8')
def h2i(self, pkt, x): """ Description: transform a string uuid in uuid type object """ self.default = uuid.UUID(plain_str(x or "")) return self.default
def modulation(self): """Get the 802.11 modulation of the interface. Only available with Npcap.""" # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 self._check_npcap_requirement() return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "modu"], stdout=sp.PIPE).communicate()[0].strip())
def availablemodes(self): """Get all available interface modes. Only available with Npcap.""" # According to https://nmap.org/npcap/guide/npcap-devguide.html#npcap-feature-dot11 self._check_npcap_requirement() return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "modes"], stdout=sp.PIPE).communicate()[0].strip()).split(",")
def read_routes(): try: f = open("/proc/net/route", "rb") except IOError: warning("Can't open /proc/net/route !") return [] routes = [] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", scapy.consts.LOOPBACK_NAME.encode("utf8"))) # noqa: E501 addrfamily = struct.unpack("h", ifreq[16:18])[0] if addrfamily == socket.AF_INET: ifreq2 = ioctl(s, SIOCGIFNETMASK, struct.pack("16s16x", scapy.consts.LOOPBACK_NAME.encode("utf8"))) # noqa: E501 msk = socket.ntohl(struct.unpack("I", ifreq2[20:24])[0]) dst = socket.ntohl(struct.unpack("I", ifreq[20:24])[0]) & msk ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) routes.append((dst, msk, "0.0.0.0", scapy.consts.LOOPBACK_NAME, ifaddr, 1)) # noqa: E501 else: warning("Interface %s: unknown address family (%i)" % (scapy.consts.LOOPBACK_NAME, addrfamily)) # noqa: E501 except IOError as err: if err.errno == 99: warning("Interface %s: no address assigned" % scapy.consts.LOOPBACK_NAME) # noqa: E501 else: warning("Interface %s: failed to get address config (%s)" % (scapy.consts.LOOPBACK_NAME, str(err))) # noqa: E501 for line in f.readlines()[1:]: line = plain_str(line) iff, dst, gw, flags, _, _, metric, msk, _, _, _ = line.split() flags = int(flags, 16) if flags & RTF_UP == 0: continue if flags & RTF_REJECT: continue try: ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", iff.encode("utf8"))) # noqa: E501 except IOError: # interface is present in routing tables but does not have any assigned IP # noqa: E501 ifaddr = "0.0.0.0" ifaddr_int = 0 else: addrfamily = struct.unpack("h", ifreq[16:18])[0] if addrfamily == socket.AF_INET: ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) ifaddr_int = struct.unpack("!I", ifreq[20:24])[0] else: warning("Interface %s: unknown address family (%i)", iff, addrfamily) # noqa: E501 continue # Attempt to detect an interface alias based on addresses inconsistencies # noqa: E501 dst_int = socket.htonl(int(dst, 16)) & 0xffffffff msk_int = socket.htonl(int(msk, 16)) & 0xffffffff gw_str = scapy.utils.inet_ntoa(struct.pack("I", int(gw, 16))) metric = int(metric) if ifaddr_int & msk_int != dst_int: tmp_route = get_alias_address(iff, dst_int, gw_str, metric) if tmp_route: routes.append(tmp_route) else: routes.append((dst_int, msk_int, gw_str, iff, ifaddr, metric)) else: routes.append((dst_int, msk_int, gw_str, iff, ifaddr, metric)) f.close() s.close() return routes
def network_stats(self): """Return a dictionary containing a summary of the Dot11 elements fields """ summary = {} crypto = set() p = self.payload while isinstance(p, Dot11Elt): if p.ID == 0: summary["ssid"] = plain_str(p.info) elif p.ID == 3: summary["channel"] = ord(p.info) elif isinstance(p, Dot11EltCountry): summary["country"] = plain_str(p.country_string[:2]) country_descriptor_types = { b"I": "Indoor", b"O": "Outdoor", b"X": "Non-country", b"\xff": "Ignored" } summary["country_desc_type"] = country_descriptor_types.get( p.country_string[-1:]) elif isinstance(p, Dot11EltRates): summary["rates"] = p.rates elif isinstance(p, Dot11EltRSN): wpa_version = "WPA2" # WPA3-only: # - AP shall at least enable AKM suite selector 00-0F-AC:8 # - AP shall not enable AKM suite selector 00-0F-AC:2 and # 00-0F-AC:6 # - AP shall set MFPC and MFPR to 1 # - AP shall not enable WEP and TKIP # WPA3-transition: # - AP shall at least enable AKM suite selector 00-0F-AC:2 # and 00-0F-AC:8 # - AP shall set MFPC to 1 and MFPR to 0 if any(x.suite == 8 for x in p.akm_suites) and \ all(x.suite not in [2, 6] for x in p.akm_suites) and \ p.mfp_capable and p.mfp_required and \ all(x.cipher not in [1, 2, 5] for x in p.pairwise_cipher_suites): # WPA3 only mode wpa_version = "WPA3" elif any(x.suite == 8 for x in p.akm_suites) and \ any(x.suite == 2 for x in p.akm_suites) and \ p.mfp_capable and not p.mfp_required: # WPA3 transition mode wpa_version = "WPA3-transition" # Append suite if p.akm_suites: auth = p.akm_suites[0].sprintf("%suite%") crypto.add(wpa_version + "/%s" % auth) else: crypto.add(wpa_version) elif p.ID == 221: if isinstance(p, Dot11EltMicrosoftWPA) or \ p.info.startswith(b'\x00P\xf2\x01\x01\x00'): if p.akm_suites: auth = p.akm_suites[0].sprintf("%suite%") crypto.add("WPA/%s" % auth) else: crypto.add("WPA") p = p.payload if not crypto: if self.cap.privacy: crypto.add("WEP") else: crypto.add("OPN") summary["crypto"] = crypto return summary
def __init__(self, val): # type: (str) -> None val = plain_str(val) val = conf.mib._oid(val) ASN1_Object.__init__(self, val) self.oidname = conf.mib._oidname(val)
def __str__(self): # type: () -> str return plain_str(self.enc(conf.ASN1_default_codec))
def __init__(self, val): val = plain_str(val) val = conf.mib._oid(val) ASN1_Object.__init__(self, val) self.oidname = conf.mib._oidname(val)
def __setattr__(self, name, value): # type: (str, Any) -> None if isinstance(value, bytes): value = plain_str(value) if name == "val": formats = {10: "%Y%m%d%H", 12: "%Y%m%d%H%M", 14: "%Y%m%d%H%M%S"} dt = None # type: Optional[datetime] try: if value[-1] == "Z": str, ofs = value[:-1], value[-1:] elif value[-5] in ("+", "-"): str, ofs = value[:-5], value[-5:] elif isinstance(self, ASN1_UTC_TIME): raise ValueError() else: str, ofs = value, "" if isinstance(self, ASN1_UTC_TIME) and len(str) >= 10: fmt = "%y" + formats[len(str) + 2][2:] elif str[-4] == ".": fmt = formats[len(str) - 4] + ".%f" else: fmt = formats[len(str)] dt = datetime.strptime(str, fmt) if ofs == 'Z': dt = dt.replace(tzinfo=timezone.utc) elif ofs: sign = -1 if ofs[0] == "-" else 1 ofs = datetime.strptime(ofs[1:], "%H%M") delta = timedelta(hours=ofs.hour * sign, minutes=ofs.minute * sign) dt = dt.replace(tzinfo=timezone(delta)) except Exception: dt = None pretty_time = None if dt is None: _nam = self.tag._asn1_obj.__name__[5:] _nam = _nam.lower().replace("_", " ") pretty_time = "%s [invalid %s]" % (value, _nam) else: pretty_time = dt.strftime("%Y-%m-%d %H:%M:%S") if dt.microsecond: pretty_time += dt.strftime(".%f")[:4] if dt.tzinfo == timezone.utc: pretty_time += dt.strftime(" UTC") elif dt.tzinfo is not None: if dt.tzinfo.utcoffset(dt) is not None: pretty_time += dt.strftime(" %z") ASN1_STRING.__setattr__(self, "pretty_time", pretty_time) ASN1_STRING.__setattr__(self, "datetime", dt) ASN1_STRING.__setattr__(self, name, value) elif name == "pretty_time": print("Invalid operation: pretty_time rewriting is not supported.") elif name == "datetime": ASN1_STRING.__setattr__(self, name, value) if isinstance(value, datetime): yfmt = "%y" if isinstance(self, ASN1_UTC_TIME) else "%Y" if value.microsecond: str = value.strftime(yfmt + "%m%d%H%M%S.%f")[:-3] else: str = value.strftime(yfmt + "%m%d%H%M%S") if value.tzinfo == timezone.utc: str = str + "Z" else: str = str + value.strftime("%z") # empty if naive ASN1_STRING.__setattr__(self, "val", str) else: ASN1_STRING.__setattr__(self, "val", None) else: ASN1_STRING.__setattr__(self, name, value)
def mode(self): """Get the interface operation mode. Only available with Npcap.""" self._check_npcap_requirement() return plain_str(sp.Popen([_WlanHelper, self.guid[1:-1], "mode"], stdout=sp.PIPE).communicate()[0].strip())
def read_routes(): try: f = open("/proc/net/route", "rb") except IOError: log_loading.critical("Can't open /proc/net/route !") return [] routes = [] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", conf.loopback_name.encode("utf8"))) # noqa: E501 addrfamily = struct.unpack("h", ifreq[16:18])[0] if addrfamily == socket.AF_INET: ifreq2 = ioctl(s, SIOCGIFNETMASK, struct.pack("16s16x", conf.loopback_name.encode("utf8"))) # noqa: E501 msk = socket.ntohl(struct.unpack("I", ifreq2[20:24])[0]) dst = socket.ntohl(struct.unpack("I", ifreq[20:24])[0]) & msk ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) routes.append((dst, msk, "0.0.0.0", conf.loopback_name, ifaddr, 1)) # noqa: E501 else: warning("Interface %s: unknown address family (%i)" % (conf.loopback_name, addrfamily)) # noqa: E501 except IOError as err: if err.errno == 99: warning("Interface %s: no address assigned" % conf.loopback_name) # noqa: E501 else: warning("Interface %s: failed to get address config (%s)" % (conf.loopback_name, str(err))) # noqa: E501 for line in f.readlines()[1:]: line = plain_str(line) iff, dst, gw, flags, _, _, metric, msk, _, _, _ = line.split() flags = int(flags, 16) if flags & RTF_UP == 0: continue if flags & RTF_REJECT: continue try: ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x", iff.encode("utf8"))) # noqa: E501 except IOError: # interface is present in routing tables but does not have any assigned IP # noqa: E501 ifaddr = "0.0.0.0" ifaddr_int = 0 else: addrfamily = struct.unpack("h", ifreq[16:18])[0] if addrfamily == socket.AF_INET: ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) ifaddr_int = struct.unpack("!I", ifreq[20:24])[0] else: warning("Interface %s: unknown address family (%i)", iff, addrfamily) # noqa: E501 continue # Attempt to detect an interface alias based on addresses inconsistencies # noqa: E501 dst_int = socket.htonl(int(dst, 16)) & 0xffffffff msk_int = socket.htonl(int(msk, 16)) & 0xffffffff gw_str = scapy.utils.inet_ntoa(struct.pack("I", int(gw, 16))) metric = int(metric) route = [dst_int, msk_int, gw_str, iff, ifaddr, metric] if ifaddr_int & msk_int != dst_int: tmp_route = get_alias_address(iff, dst_int, gw_str, metric) if tmp_route: route = tmp_route routes.append(tuple(route)) f.close() s.close() return routes
def __str__(self): # type: () -> str return plain_str(self._fix())