def _filter_packet(self, packet: scapy.Packet) -> bool: if not self._filter_clauses: return True clause_evals = [] for ((layer, attribute), value) in self._filter_clauses: truthy_clause = True try: if layer[0] == '!': truthy_clause = False layer = layer[1:] layer_reference = getattr(scapy, layer) if attribute == 'exists': clause_evals.append( str(int(packet.haslayer(layer_reference))) == value) else: if packet.haslayer(layer_reference): packet_layer = packet[layer_reference] packet_attribute = str(getattr(packet_layer, attribute)) clause_evals.append(( packet_attribute == value) if truthy_clause else ( packet_attribute != value)) else: clause_evals.append(False) except AttributeError as exc: clause_evals.append(False) return all(clause_evals)
def _callback(self, pkt: Packet) -> None: log.debug(pkt.summary()) if pkt.haslayer(DNS) and pkt.getlayer(DNS).qr == 0: if IP in pkt: return self._disect_dns(pkt.getlayer(DNS), pkt[IP].src) elif IPv6 in pkt: return self._disect_dns(pkt.getlayer(DNS), pkt[IPv6].src, True)
def __init__(self, *args, **kwargs): """Constructor.""" self._anno = {} self.__priv = {} Packet.__init__(self, *args, **kwargs) self.hide_defaults() self._setup()
def handle_packet(self, packet: Packet) -> None: try: if packet.haslayer(Dot11) or packet.haslayer(Dot11FCS): self.in_pkcs_queue.put(packet) except Exception as e: self.cmd.perror( "[!] Exception while handling packet: {}\n{}".format( e, packet.show(dump=True)))
def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, config=None, **fields): # noqa: E501 """ length=None means that the length must be managed by the user. If it's defined, the field will always be length-long (padded with b"\\x00" if needed) """ self._config = config Packet.__init__(self, _pkt=_pkt, post_transform=post_transform, _internal=_internal, _underlayer=_underlayer, **fields)
def __init__(self, *args, **kwargs): # VERY IMPORTANT: Do this first, because the superclass will call back in # to do_dissect(). self.fields_by_id = {f.pb_id: f for f in self.fields_desc} self.fields_seen = [] self.dummy_count = 0 self.repr_output_suppressed = 0 Packet.__init__(self, *args, **kwargs) return
def detect_ip_version_DNS(self, packet: Packet) -> Packet: """ This function crafts the DNS response. """ if packet.haslayer(IP): return self.craft_MDNS_IP(packet) elif packet.haslayer(IPv6): return self.craft_MDNS_IPv6(packet)
def __init__(self, _pkt="", post_transform=None, _internal=0, _underlayer=None, config=None, **fields): """ length=None means that the length must be managed by the user. If it's defined, the field will always be length-long (padded with b"\\x00" if needed) """ self._config = config Packet.__init__(self, _pkt=_pkt, post_transform=post_transform, _internal=_internal, _underlayer=_underlayer, **fields)
def get_ips(pkt: Packet) -> Tuple[Optional[str], Optional[str]]: if pkt.haslayer(ARP): return (pkt[ARP].psrc, pkt[ARP].pdst) if pkt.haslayer(IP): return (pkt[IP].src, pkt[IP].dst) if pkt.haslayer(IPv6): return (pkt[IPv6].src, pkt[IPv6].dst) return (None, None)
def get_app_protocol(pkt: Packet) -> Optional[str]: if pkt.haslayer(ARP): return "ARP" if pkt.haslayer(ICMP): return "ICMP" else: for layer in reversed(pkt.layers()): name = layer.__name__ if name != "Raw": return name return pkt.lastlayer().__name__
def process_packet(pkt: scapy.Packet): if pkt.haslayer(HTTPRequest): url = pkt[HTTPRequest].Host.decode() + pkt[HTTPRequest].Path.decode() method = pkt[HTTPRequest].Method.decode() print('[{t}][{m}] HTTP Request >> {u}'.format( t=dt.now().strftime('%Y-%m-%d %H:%M:%S'), u=url, m=method)) if show_raw and pkt.haslayer(scapy.Raw) and method == 'POST': raw = pkt[scapy.Raw] print(f'[*] Raw data: {raw.load}') time.sleep(1)
def guess_payload_class(self, payload): ''' Decides if the payload is an ICAP Request or Response, or something else ''' try: icap_req = payload[:payload.index("\r\n")] s1,s2,s3 = icap_req.split(" ") # @UnusedVariable s2 except: return Packet.guess_payload_class(self, payload) icap_versions = ["ICAP/0.9","ICAP/1.0","ICAP/1.1"] for icap_version in icap_versions: if s3 == icap_version: return ICAPRequest if s1 == icap_version: return ICAPResponse return Packet.guess_payload_class(self, payload)
def post_build(self, pkt, pay): # add padding to ensure min packet length padding = MIN_PACKET_LENGTH - (len(pkt + pay)) pay += b"\0" * padding return Packet.post_build(self, pkt, pay)
def identify_packet(self, packet: Packet) -> None: """ This function detects the request type and send the response. """ if packet.haslayer(NBNSQueryRequest) and packet[IP].src != self.ip: responses, ip_src, name, style = self.craft_NBNS_response(packet) elif packet.haslayer(LLMNRQuery): responses, ip_src, name, style = self.detect_LLMNR_type(packet) elif packet.haslayer(DNS) and packet.haslayer(DNSQR): responses, ip_src, name, style = self.detect_ip_version_DNS(packet) else: return None for response in responses: send(response, verbose=0, iface=self.iface) logger.info(f"Protocol {style}, spoof {name} for {ip_src}")
def test_ip_tsb(ipval, tsbval, expected): f0 = InstantPowerField('test', 0) f1 = TSBField('test', 0) pkt = Packet() pay = f0.addfield(pkt, b'', ipval) pay = f1.addfield(pkt, pay, tsbval) assert pay == expected
def guess_payload_class(self, payload): if self.setID == 2: return Template elif self.setID > 255: return Data else: return Packet.guess_payload_class(self, payload)
def detect_LLMNR_type(self, packet: Packet) -> Packet: """ This function detects the IP version and DNSQR type to forge the LLMNR response. """ if packet.haslayer(IP): if packet[DNSQR].qtype == 28: return self.craft_LLMNR_IP_type_28(packet) else: return self.craft_LLMNR_IP(packet) elif packet.haslayer(IPv6): if packet[DNSQR].qtype == 28: return self.craft_LLMNR_IPv6_type_28(packet) else: return self.craft_LLMNR_IPv6(packet)
def __call__(self, packet: Packet): is_TCP = packet.haslayer(TCP) is_UDP = packet.haslayer(UDP) # Perform TCP and UDP checks if is_TCP or is_UDP: proto_type = TCP if is_TCP else UDP # Scan for using port 80 and the plaintext for privacy leaks if (packet[proto_type].dport == 80) or (packet[proto_type].sport == 80): alert_port_80 = Alert(None, "Sending data over unencrypted port.", ALERT_TYPE.PRIVACY, SEVERITY.ALERT) alert_port_80.alert() self.__scan_plaintext(packet, proto_type) # Monitor suspicious ports print("Monitoring suspicious ports") if packet[proto_type].dport in suspicious_ports: alert_suspicious_ports = Alert( None, "Suspicious destination port used: " + packet[proto_type].dport, ALERT_TYPE.PRIVACY, SEVERITY.WARN) alert_suspicious_ports.alert() print("Alert on bad port")
def guess_payload_class(self, payload): # For frameID in the RT_CLASS_* range, use the RTC packet as payload if (self.frameID >= 0x0100 and self.frameID < 0x1000) or \ (self.frameID >= 0x8000 and self.frameID < 0xFC00): from scapy.contrib.pnio_rtc import PNIORealTime return PNIORealTime else: return Packet.guess_payload_class(self, payload)
def __handle_pkt(self, packet: Packet) -> str: '''Callback method to be executed by Scapy for every sniffed packet.''' stat_key = None message = {} message['is_enip'] = packet.haslayer(ENIP_TCP) or packet.haslayer( ENIP_UDP) if packet.haslayer(ENIP_SendRRData) and packet[ 'ENIP_SendRRData'].items[1]['CIP'].direction == 1: # Response message['src'] = {} message['dst'] = {} message['src']['MAC'] = str.upper(packet['Ethernet'].src) message['dst']['MAC'] = str.upper(packet['Ethernet'].dst) message['src']['IP'] = packet['IP'].src message['dst']['IP'] = packet['IP'].dst message['rawdata'] = bytes( packet['ENIP_SendRRData'].items[1]['Raw']) message['data'] = self.read_cip_tag(message['rawdata'][0], message['rawdata'][2:]) message['rawdata'] = hexlify(message['rawdata']).decode('utf-8') if packet.haslayer(TCP): stat_key = '{0:s}:{1:d}/{2:s}:{3:d}/TCP'.format( packet['IP'].src, packet['TCP'].sport, packet['IP'].dst, packet['TCP'].dport) elif packet.haslayer(UDP): stat_key = '{0:s}:{1:d}/{2:s}:{3:d}/UDP'.format( packet['IP'].src, packet['UDP'].sport, packet['IP'].dst, packet['UDP'].dport) self.__messages.append(message) elif packet.haslayer(IP): message['src'] = {} message['dst'] = {} message['src']['MAC'] = str.upper(packet['Ethernet'].src) message['dst']['MAC'] = str.upper(packet['Ethernet'].dst) message['src']['IP'] = packet['IP'].src message['dst']['IP'] = packet['IP'].dst message['rawippayload'] = packet['IP'].payload if packet.haslayer('TCP'): stat_key = '{0:s}:{1:d}/{2:s}:{3:d}/TCP'.format( packet['IP'].src, packet['TCP'].sport, packet['IP'].dst, packet['TCP'].dport) elif packet.haslayer('UDP'): stat_key = '{0:s}:{1:d}/{2:s}:{3:d}/UDP'.format( packet['IP'].src, packet['UDP'].sport, packet['IP'].dst, packet['UDP'].dport) else: stat_key = '{0:s}/{1:s}/{2:s}'.format( packet['IP'].src, packet['IP'].dst, LOCAL_PROTOS[packet['IP'].proto]) self.__messages.append(message) if stat_key is not None: if stat_key in self.__packet_stats.keys(): self.__packet_stats[stat_key] += 1 else: self.__packet_stats[stat_key] = 1 return None
def test_instant_power(ipval, expected): f = InstantPowerField('test', 0) pkt = Packet() pay = f.addfield(pkt, b'', ipval) assert pay == expected rem, val = f.getfield(pkt, expected) assert rem == expected[1:] assert val == ipval & 0xFFF
def test_tsb(tsbval, expected): f = TSBField('test', 0) pkt = Packet() pay = f.addfield(pkt, b'\x00\x00', tsbval) assert pay == expected rem, val = f.getfield(pkt, expected[1:]) assert rem == b'' assert val == tsbval
def add_packet(self, packet: scapy.Packet) -> None: packet_item = QtWidgets.QListWidgetItem(packet.summary()) packet_item.setData(QtCore.Qt.UserRole, packet) self._packet_list.addItem(packet_item) if self._filter_packet(packet) and \ self.parent.parent.auto_select_action.isChecked(): self._packet_list.clearSelection() self._packet_list.setCurrentItem(packet_item) self._packet_list.scrollToBottom() self.refresh_filter()
def guess_payload_class(self, payload): #to match the payload in the regular expression groups = IRC().regex(payload) command = groups[1] if command != None: if command in IRC.commands: # to check if it's a irc command return IRC return Packet.guess_payload_class(self, payload) #return default guess
def get_ttl(pkt: Packet) -> Optional[int]: if IP in pkt: return pkt.ttl if IPv6 in pkt: return pkt.hlim for layer in reversed(pkt.layers()): ttl = getattr(pkt[layer.__name__], "ttl", None) if ttl: return ttl
def guess_payload_class(self, payload): prog = re.compile("^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT)") result = prog.search(payload) if result: return HTTPrequest else: prog = re.compile("^HTTP/((0\.9)|(1\.0)|(1\.1))\ [0-9]{3}.*") result = prog.search(payload) if result: return HTTPresponse return Packet.guess_payload_class(self, payload)
def build_pkt_dict(self, No, pkt: Packet): SingelRow = { 'No.': str(No), 'Time': str(time.time() - self.startTime)[0:6], 'Protocal': SnifferThread.get_packet_proto(pkt), 'Length': str(len(pkt)), 'Info': pkt.summary(), } SingelRow['Source'], SingelRow[ 'Destination'] = SnifferThread.get_src_dst(pkt) return SingelRow
def send_batch(self, batches): packets_len = len(batches) if packets_len == 0: return packet_list = PacketList() for pkt in batches: packet_raw = Packet(pkt) packet_list.append(packet_raw) sendp(packet_list, iface=self._options.iface, verbose=0)
def guess_payload_class(self, payload): prog=re.compile("^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT)") result=prog.search(payload) if result: return HTTPrequest else: prog=re.compile("^HTTP/((0\.9)|(1\.0)|(1\.1))\ [0-9]{3}.*") result=prog.search(payload) if result: return HTTPresponse return Packet.guess_payload_class(self, payload)
def on_wireshark(packet: Packet): """ 抓包回调函数 """ if not packet.haslayer(MQTTPublish): return global packet_info # 约定使用 utf-8 编码 packet_info['topic'] = packet.topic.decode('gbk') packet_info['msg'] = packet.value.decode('gbk') packet_info['src host'] = str(packet[IP].src) packet_info['dst host'] = str(packet[IP].dst)
def guess_payload_class(self, payload): ''' Decides if the payload is an HTTP Request or Response, or something else ''' prog = re.compile("^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT)") result = prog.search(payload) if result: return HTTPRequest else: prog = re.compile("^HTTP/((0\.9)|(1\.0)|(1\.1))\ [0-9]{3}.*") result = prog.search(payload) if result: return HTTPResponse return Packet.guess_payload_class(self, payload)
def process_sniffed_packet(packet: scapy.Packet): if packet.haslayer(http.HTTPRequest): # detecting url url_to_print = "" if packet[http.HTTPRequest]: url_to_print += str(packet[http.HTTPRequest].Host, 'utf-8') if packet[http.HTTPRequest]: url_to_print += str(packet[http.HTTPRequest].Path, 'utf-8') print(url_to_print) url_to_print = "" # detecting passwords if packet.haslayer(scapy.Raw): load = packet[scapy.Raw].load login_keywords = ['user', 'username', 'uname', 'phone', 'mobile', 'email', 'mail' 'pass', 'password', 'code', 'remember'] for word in login_keywords: if word in str(load): print(bcolors.OKGREEN + "[+] suspected auth credits: " + str(load) + bcolors.ENDC) break
def guess_payload_class(self, payload): """ Decides if the payload is an HTTP Request or Response, or something else """ try: prog = re.compile(r"^(?:OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT) " r"(?:.+?) " r"HTTP/\d\.\d$") req = payload[: payload.index("\r\n")] result = prog.match(req) if result: return HTTPRequest else: prog = re.compile(r"^HTTP/\d\.\d \d\d\d .+?$") result = prog.match(req) if result: return HTTPResponse except: pass return Packet.guess_payload_class(self, payload)
def guess_payload_class(self, payload): if self.type == 0: return OpenFlowHello #if self.type == 1: # return OpenFlowError elif self.type == 2: return OpenFlowEchoRequest elif self.type == 3: return OpenFlowEchoReply #if self.type == 4: # return OpenFlowEchoReply elif self.type == 5: return OpenFlowFeaturesRequest elif self.type == 6: return OpenFlowFeaturesReply else: return Packet.guess_payload_class(self, payload)
def scapy_match(self, packet: Packet) -> None: """ This function gets IP address of matching packets with scapy. """ if packet.haslayer(ARP): ip = packet[ARP].psrc mode = "ARP" else: ip = packet[IP].src mode = "IP" debug(f"{mode} detected in packet...") targets = self._targets if ip in targets: targets.remove(ip) self._handle_UP(ip, mode, packet[Ether].src)
def handle_packet(self, packet: Packet): if not DeviceSniffer.is_probe_request(packet): return try: target_ssid = packet.getlayer(Dot11Elt).getfieldval("info").decode( "utf-8") if len(target_ssid) == 0: return source_mac_addr = packet.addr2.upper() userid = self.user_querier.get_userid(target_ssid, source_mac_addr) if userid is not None: self.device_dectect_stream.on_next(userid) except Exception as err: self.device_dectect_stream.on_error(err)
def copy(self, *args, **kwargs): """Overwrite Packet.copy from Scapy Packet class.""" clone = Packet.copy(self, *args, **kwargs) clone._setup() newanno, keepkeys = {}, [] for k in self._anno: keep = True keep &= not isinstance(self.getanno(k), list) # do not copy lists keep &= not isinstance(self.getanno(k), dict) # do not copy dicts keep &= not (k in self.privanno()) keep &= not (k in const.ANNO_BLACKLIST) if keep: keepkeys.append(k) for k in keepkeys: if isinstance(self._anno[k], Reference): newanno[k] = Reference(self._anno[k]) else: try: newanno[k] = deepcopy(self._anno[k]) # deepcopy item except: sys.stderr.write("%s caused deepcopy error\n"%(k)) clone.writeanno(newanno) return clone
def copy(self): pkt = Packet.copy(self) pkt._config = self._config return pkt
def clone_with(self, *args, **kargs): pkt = Packet.clone_with(self, *args, **kargs) pkt._config = self._config return pkt