wireshark分析https报文

发布时间 2023-10-18 17:01:39作者: frankming

使用wireshark分析http报文是一件愉悦的事情, 在wireshark不断滚动的窗口中,http服务的交互报文在我们面前一览无余,简单的过滤及追踪命令即可获取到特定请求的完整收发流程,然而,到https这里,事情就变得复杂起来。

协议复杂

http简单报文

下图是一个wireshark抓获的http报文:

这时一个典型的http报文, 其中,前三条是tcp三次握手,中间是正常的http通信,后几条则是tcp四次挥手,结束连接。

选择追踪http报文,一个完整的http请求文本映入眼前:

https复杂报文

不过,到了https这边,通信的报文则肉眼可见的多了不少。为了加强安全性,https采用了多种措施,将不法分子拒之门外,其安全措施大致包括有:

  1. 使用对称加密算法加密通信文本,防止信息被截取;
  2. 使用非对称加密算法对称加密算法的密钥,防止密钥被截取;
  3. 使用摘要算法对非对称密钥进行摘要,防止非对称密钥被替换。

接下来具体说明下各个报文的作用。

首先是SSL握手协商阶段,作用主要是协商加密方式以及发送证书,它包含三个报文:

  1. Client Hello:客户端向服务端发送支持的SSL版本以及加密套件列表;
  2. Server Hello:服务端收到报文后,从中筛选出自己支持的一个SSL版本以及加密套件,并返回给客户端;
  3. Server Hello Done:服务端告知客户端协商结束,并将自己的证书发送给客户端,客户端收到后会尝试用CA证书中的公钥去解密服务端证书,并从中拿到服务端的公钥。

其次是对称密钥交换阶段,作用主要是生成对称加密密钥并交换,它包含五个报文:

  1. Client Key Exchange:客户端随机生成一串字符串用作对称密钥,称为Pre-master secret,使用上阶段获取的服务端公钥加密后发送给服务端,
  2. Change Cipher Spec:客户端发送加密套件改变提醒,表示之后的报文都会采用Pre-master secret加密;
  3. Encrypted Handshake Message:客户端将之前发送的所有报文经过摘要后加密发送给服务端,让服务端确认能否成功解密;
  4. Change Cipher Spec、Encrypted Handshake Message:服务端同样发送加密套件改变提醒以及报文摘要给客户端,之后SSL连接建立完成。

最后便是http通信阶段,客户端与服务端均使用加密后的报文相互通信,在wireshark无法直接获取到明文报文,只显示Application Data

分析困难

如上一章所说,https经过一系列的精心设计,将不法分子拒之门外,而我们如果想要尝试分析https报文,却也变得困难重重。想要解密https报文,最重要的是获取对称加密的密钥,也就是Pre-master secret。而这个密钥由客户端生成,使用服务端公钥加密,如果想要得知该密钥,要么直接让客户端告诉我们,要么就得得知服务端的私钥,用私钥解密该密钥,这就衍生出两种分析https报文的方法。

通过Pre-master secret解密

wireshark提供了通过pre-master secret解密https流量的入口,在如下窗口指定pre-master secret所在文件后,便能够自动将https流量从密文变为明文。

接下来是一些导出pre-master secret的方法。

环境变量导出pre-master secret

对于使用openssl作为tls连接库的大多数程序,都可以通过SSLKEYLOGFILE环境变量导出secret。

SSLKEYLOGFILE=/tmp/keylog.txt ./executable

gdb导出pre-master secret

gdb是进程动态调试工具,可以分析运行中进程的详细情况,自然也可以用来获取客户端在tls密钥交换过程中产生的pre-master secret,具体的实施方法可以参考这篇文章:使用gdb从openssl应用程序中导出pre-master key

python程序导出pre-master secret

对于python3.8及以上版本,想要导出secret,只需要配置SSLKEYLOGFILE环境变量即可。

SSLKEYLOGFILE=/tmp/keylog.txt python a.py

而python3.8以下版本,则需要通过修改代码的方式导出secret,具体方法参考该仓库:joernheissler/SslMasterKey: Retrieve the Master Key and Client Random from an ssl.SSLSocket (github.com)

通过服务器私钥解密

如果得知了服务器私钥,那么解密https报文则简单多了,客户端在密钥协商阶段发送到密钥能够直接通过服务端私钥解密,wireshark同样也提供了该方式解密的入口。

参考

Wireshark解密HTTPS流量的两种方法 - 豫让 - 博客园 (cnblogs.com)

图解HTTP (图灵程序设计丛书) (awesome-programming-books.github.io) 第七章,7.2.5

tls - Extract pre-master keys from an OpenSSL application - Information Security Stack Exchange

TLS (wireshark.org)