如何使用Scapy将HTTP请求响应的Raw Payload解码为可读内容?
解决Scapy捕获HTTPS流量Raw层乱码问题
你看到的b'\x17\x03\x03...'是加密的TLS应用数据,不是明文HTTP内容,直接解码自然得不到可读结果。以下是具体原因和解决方法:
核心原因
\x17是TLS记录层的类型标识(代表Application Data,即加密后的应用层数据),\x03\x03表示TLS 1.2版本。HTTPS是HTTP协议套在TLS加密层之上,所以你抓到的Raw payload是加密后的流量,必须先解密才能还原成Chrome开发者工具里看到的明文HTTP请求/响应。
解决方法:用Scapy配合TLS密钥日志解密
步骤1:导出浏览器的TLS密钥日志
在启动Chrome(或Firefox)前,设置环境变量让浏览器输出TLS会话密钥:
- Windows:打开命令提示符,执行
set SSLKEYLOGFILE=C:\sslkeys.log,再启动Chrome - Linux/macOS:在终端执行
export SSLKEYLOGFILE=/tmp/sslkeys.log,再启动Chrome
步骤2:Scapy加载密钥日志解密流量
使用Scapy的TLSSession类加载密钥日志,解密TLS流量并提取明文HTTP内容:
from scapy.all import sniff, TLS, IP, TCP from scapy.layers.tls.session import TLSSession # 加载提前导出的密钥日志文件 tls_session = TLSSession(keylog_file="/tmp/sslkeys.log") def handle_packet(pkt): # 过滤包含IP、TCP、TLS层的数据包 if IP in pkt and TCP in pkt and TLS in pkt: try: # 解密TLS流量 decrypted_pkt = tls_session.decrypt(pkt) # 提取明文内容并输出 if hasattr(decrypted_pkt, 'plaintext'): print(f"源IP:端口 -> {pkt[IP].src}:{pkt[TCP].sport}") print(f"目标IP:端口 -> {pkt[IP].dst}:{pkt[TCP].dport}") print("明文HTTP内容:\n" + decrypted_pkt.plaintext.decode('utf-8', errors='replace')) print("------------------------") except Exception: # 忽略解密失败的数据包(比如握手阶段的非应用数据) pass # 开始抓包,store=0不保存数据包到内存 sniff(prn=handle_packet, store=0)
其他注意事项
- 如果是明文HTTP(默认端口80),Raw层会直接是可读的HTTP文本(比如
GET / HTTP/1.1\r\nHost: example.com\r\n...),无需解密 - 若无法导出密钥日志,可使用中间人代理工具(如mitmproxy)捕获明文HTTPS流量,但需要在设备上信任代理的根证书
内容的提问来源于stack exchange,提问作者Марко Костић
相关产品推荐
相关产品推荐

