引言

跟网络通信有关的应用场景下(比如Web系统、IM聊天应用、消息推送系统等),经常要用到网络抓包工具,用以验证客户端和服务器之间收发的数据包是否正确。以IM聊天系统为例,TLS/SSL加密开启到底有没有成功?加密效果怎么样?端到端加密后的聊天内容安全强度够不够?等等这些疑问,都需要通过网络抓包抓出样本来分析和验证。

Wireshark是一款开源和跨平台的抓包工具。它通过调用操作系统底层的API,直接捕获网卡上的数据包,因此捕获的数据包详细、功能强大。但Wireshark本身稍显复杂,本文将以用抓包实例,手把手带你一步步用好Wireshark,并真正理解抓到的数据包的各项含义。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_cover-opti.png

ireshak的安装和基本使用

安装:直接通过官方下载对应的安装包即可 https://www.wireshark.org/download.html。

使用:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_1.png

如上图所示:

  • ***1)***左上角为几个最常用的按钮:开始捕获、停止捕获、重新捕获、捕获选项;
  • ***2)***中间为捕获过滤器,用于过滤需要捕获的数据包;
  • ***3)***捕获过滤器下面可以选择需要捕获的网络连接。

下图是用Wireshark捕获的数据包:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_2.png

可以看到,数据包结构是与OSI的七层模型相对应的,会详细显示每层的信息。

更多Wireshak的基本用法和手册,可以详读以下两篇:

快速理解Wireshak的过滤器

由于Wireshark直接捕获底层网络数据包,导致其捕获的数据包数量通常较大。为了便于筛选数据包,Wireshark提供了两种过滤器。

捕获过滤器

用于设置什么样的数据包保存在捕获结果中,避免产生过大的日志文件。

需要在开始捕获之前设置,相对简单:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_3.png

捕获过滤器语法如上,一般用于过滤协议、IP、端口等基本信息。

例如:

  • ***1)***显示目的TCP端口为8080的包:tcp dst port 8080
  • ***2)***显示来源IP地址为192.168.171.201的封包:ip src host 192.168.171.201

显示过滤器

用于在捕获日志中查找数据包,可以在捕获过程中或者捕获后随时更改。

功能更加强大和复杂:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_4.png

显示过滤器语法如上,比捕获过滤器更为强大,可以针对不同协议,过滤不同的字段。

例如:

  • ***1)***源地址是192.168.171.0网段的数据包:ip.src == 192.168.171.0/24
  • ***2)***所有的HTTP POST请求:http.request.method== “POST”
  • ***3)***显示包含TCP SYN标志的包:tcp.flags.syn == 0×02
  • ***4)***URL中包含baidu的http请求:http.request.uri contains “baidu”

用什么例子来动手学习Wireshak?

本来想借用RainbowChat 这种IM聊天中的TLS/SSL数据包来的分析来实战Wireshak,但考虑到IM通常都是私有协议,不利于理解。

因而接下来的内容将以HTTPS为例,来详细讲解如何借助Wireshak抓出的数据包(正好也顺验证之前那么多跟TLS/SSL加密有关的文章),详细理解和学习Wireshak的使用,同进加深对HTTPS协议本身的理解。

什么是HTTPS

SSL/TLS:SSL (Secure Sockets Layer),最初由Netscape公司设计,后来逐渐演变为TLS(Transport Layer Security Protocol),即“传输层安全协议”。

该协议工作在TCP层之上,应用层之下。在TCP连接完成后,进行通信双方的身份认证,并协商一些跟加密相关的工作。完成协商之后,就可以对双方发送的信息进行加密/解密了。

HTTPS:可以理解为HTTP over SSL/TLS。即在SSL/TLS协议之上运行HTTP协议,以保证通信的安全性。

更多深入的学习,可以从下面这几篇精选的资料开始:

HTTPS的SSL/TLS握手过程

SSL/TLS的握手过程主要需要解决两个问题:

  • ***1)***证明通信双方身份的真实性;
  • ***2)***协商后续通信过程中使用的密钥;

如下图所示:左侧是一个简单的握手流程,右侧为对应的抓包结果,我们可以对比分析一下SSL/TLS的握手过程。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_5.png

1)C:ClientHello

客户端发送协议版本号、sessionid、随机数、加密算法列表、扩展字段等信息:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_6.png

2)S:ServerHello

与客户端类似,不同之处在于确定了所使用的加密算法等:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_7.png

3)S:Certificate

服务端向客户端发送自己的CA证书。客户端通过证书信任链查看该证书的真实性,以验证服务端的身份。其实SSL/TLS协议还支持客户端的CA证书验证,不过在实际中使用较少。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_8.png

4)S:ServerKey Exchange

服务端根据之前选择的加密算法,传输密钥协商需要的参数。从之前的报文可以看到,这里选择的是EC-DH算法。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_9.png

5)S:ServerHello Done

该报文表示服务端发送完成。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_10.png

6)C:ClientKey Exchange

同理,客户端也要根据之前选择的加密算法,传输相应的参数。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_11.png

7)C:ChangeCipher Spec

经过上述步骤,客户端和服务器双方已经完成了身份认证,并且交换了生成密钥的全部参数。双方会根据对应的算法,各自生成加密密钥,然后就可以进行加密通信了。这个报文表示切换到密文模式,后续消息都通过加密传输。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_12.png

8)C:Finished

客户端表示握手完成。这里会发送一段Verify Data,是使用新生成的密钥加密后的一段信息。双方通过该信息验证加密算法、密钥是否有效。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_13.png

9)S:Change Cipher Spec

10)S:Finished

服务段也会发送对应的两条消息作为回应,不再赘述。

解密HTTPS报文

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_14.png

握手完成之后,就可以查看客户端发出的HTTP请求了。但我们看到的只是一段加密后的字符串?那么如何对HTTPS报文进行解密呢?

要想解密HTTPS报文,就必须要获取到加密密钥。Chrome、Firefox等浏览器支持将访问网站时使用的密钥输出到文件中。仅需要配置环境变量SSLKEYLOGFILE 即可。

如下:

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_15.png

然后需要将该密钥文件导入到Wireshark中。打开编辑-首选项,选择Protocol-SSL,填写刚才设置的文件路径。

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_16.png

现在,就可以通过Wireshark查看HTTPS请求中的具体信息了!

网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark_17.png