0%

https流量抓取与解密

https流量抓取与解密

使用服务器私钥解密

此方法局限性较大,使用于能自定义服务器且加密简单的测试场景。

能够使用服务器私钥解密的必要条件:

  • TLS版本小于等于1.2
  • 必须使用RSA密钥交换
  • 不能使用前向保密

简易的https服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import http.server
import ssl
import sys

# 配置
CERT_FILE = 'server.crt'
KEY_FILE = 'server.key'
PORT = 8443
BIND_IP = '0.0.0.0' # 监听所有IP

if len(sys.argv) > 1:
PORT = int(sys.argv[1])

# 生成证书(如果不存在)
import subprocess
import os

if not os.path.exists(CERT_FILE) or not os.path.exists(KEY_FILE):
print("生成自签名证书...")
ip_address = input("请输入服务器IP地址(默认 127.0.0.1): ") or "127.0.0.1"

# 生成证书命令
subprocess.run([
'openssl', 'req', '-x509', '-newkey', 'rsa:2048',
'-keyout', KEY_FILE, '-out', CERT_FILE,
'-days', '365', '-nodes',
'-subj', f'/CN={ip_address}',
'-addext', f'subjectAltName=IP:{ip_address}'
], check=False)

# 启动HTTPS服务器
handler = http.server.SimpleHTTPRequestHandler
httpd = http.server.HTTPServer((BIND_IP, PORT), handler)

# 包装为HTTPS
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE)

# 禁用前向加密
context.set_ciphers('DEFAULT@SECLEVEL=1:!DHE:!ECDHE')

httpd.socket = context.wrap_socket(httpd.socket, server_side=True)

print(f"HTTPS服务器已启动")
print(f"访问地址: https://127.0.0.1:{PORT}")
print(f"或: https://<你的IP>:{PORT}")
print(f"使用证书: {CERT_FILE}")
print("注意: 这是自签名证书,浏览器会显示警告")
print("按 Ctrl+C 停止服务器")

try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\n服务器已停止")

客户端

1
curl -kv https://192.168.139.176:8443 --tls-max 1.2

限制 tls 版本为 1.2

抓包

抓取一次访问的包序列,写入 pcap 中

1
sudo tcpdump host <客户端IP> and port 8443 -w https.pcap

解析

将 pcap 文件导入 wireshark,此时 https 层为加密的 Application Data

image-20251216004258863

右键添加 TLS 的 RSA keys list

image-20251216004458572

填入服务器 IP、端口、http、服务器私钥

image-20251216004656031

如此便将之前的 Application Data 解开出里面的 http 协议层

image-20251216004830275