如何解码Scapy嗅探器捕获的不可读数据?
解决Scapy嗅探数据无法正常阅读的问题
你的核心问题在于:直接将整个网络数据包转为字符串会包含大量二进制协议头部(以太网、IP、TCP等层的非文本数据),同时Python3的字节-字符串处理逻辑和Python2存在差异,导致乱码。以下是针对性的修复方案:
问题分析
- 你当前的代码跳过了HTTP层判断,处理了所有捕获到的数据包(包括非HTTP的二进制包),这些包的头部是二进制格式,转成字符串必然乱码。
- Python2中字符串与字节没有严格区分,Scapy的HTTP层处理会自动适配文本显示;但Python3中必须显式处理字节解码,且只提取HTTP相关的文本负载。
修复后的代码
import scapy.all as scapy from scapy.layers import http import optparse parser = optparse.OptionParser() parser.add_option('-i', '--interface', dest='interface', help='Interface to be sniffed.') opt, args = parser.parse_args() def sniff(interface): # 只捕获包含HTTP请求的数据包,减少无效处理 scapy.sniff(iface=interface, store=False, prn=packet_process, lfilter=lambda pkt: pkt.haslayer(http.HTTPRequest)) def packet_process(packet): http_request = packet[http.HTTPRequest] # 打印HTTP请求行(方法、路径、版本) print(f"\n[+] HTTP Request: {http_request.Method.decode()} {http_request.Path.decode()} {http_request.Http_Version.decode()}") # 打印HTTP请求头 print("[+] Headers:") for header, value in http_request.fields.items(): if header not in ['Method', 'Path', 'Http_Version'] and isinstance(value, bytes): try: print(f" {header}: {value.decode('utf-8', errors='replace')}") except: pass # 打印HTTP请求负载(如果有) if packet.haslayer(scapy.Raw): raw_data = packet[scapy.Raw].load try: decoded_data = raw_data.decode('utf-8', errors='replace') # 只打印可能的文本内容(过滤掉二进制数据) if any(c.isprintable() for c in decoded_data): print("[+] Raw Data:") print(f" {decoded_data}") except: pass sniff(opt.interface)
关键修复点
- 过滤HTTP请求包:通过
lfilter参数只处理包含http.HTTPRequest的数据包,避免处理非HTTP的二进制包。 - 提取HTTP字段:直接访问
http.HTTPRequest的内置字段(Method、Path等),这些字段已经是结构化的字节数据,只需解码即可。 - 安全解码:使用
decode('utf-8', errors='replace')处理编码错误,避免因部分非utf-8字符导致解码失败,同时替换不可读字符。 - 过滤Raw负载:只打印包含可打印字符的Raw数据,避免输出二进制乱码。
内容的提问来源于stack exchange,提问作者Jugert Mucoimaj
相关产品推荐
相关产品推荐

