网络抓包与分析方法的学习记录

掌握一些网络抓包和数据包分析的方法对于解决生产环境下遇到的疑难问题有很大帮助。

使用tcpdump命令加Wireshark工具

大多数线上服务都是部署在linux环境下,所以通常用tcpdump命令来截获网络数据包,然后拿到桌面环境(如windows)下用Wireshark解析数据包。Wireshark本身既可以捕获网络数据包,也可以解析一些常见通信协议和格式的数据。

场景一:HTTP协议数据包

首先实现了一个简易的HTTP服务端,监听端口9101。在服务端使用以下命令捕获数据包,输出到文件http.pcap,直到Ctrl+C终止,

tcpdump -XvvennS -i lo -s 0 'port 9101' -w http.pcap

# 只截获GET请求
tcpdump -XvvennS -i lo -s 0 '((port 9101) and (tcp[(tcp[12]>>2):4]=0x47455420))' -w http.pcap

# 只截获POST请求
tcpdump -XvvennS -i lo -s 0 '((port 9101) and (tcp[(tcp[12]>>2):4]=0x504f5354))' -w http.pcap

使用curl命令发起HTTP请求,

# GET请求
curl 'http://127.0.0.1:9101/jelly_cs_b/c/webi/test/get'

# POST请求,发送gzip压缩格式数据
echo '{a:"some one",_id:100,b:{k:[1,2,3]}}' | gzip > content.gz
curl -iv -X POST -H 'Content-Encoding: gzip' --data-binary @content.gz 'http://127.0.0.1:9101/jelly_cs_b/c/webi/test/post'

# POST请求,发送json格式字符串,返回加密后的数据,输出到文件
curl -X POST -H 'App-EnCode:true' -d '{a:"some one",_id:100,b:{k:[1,2,3]}}' 'http://127.0.0.1:9101/jelly_cs_b/c/webi/test/post' -s -o encode.dat

# POST请求,发送文件中的二进制数据,返回解密后的数据
curl -X POST -H 'App-EnCode:false' --data-binary @encode.dat 'http://127.0.0.1:9101/jelly_cs_b/c/webi/test/post'

将得到的http.pcap文件下载到windows环境下用Wireshark打开,如下图

wireshark-001

如果没有对数据包内容进行过滤,则可以看到除了要关注的HTTP协议数据包外,还有TCP建立连接和关闭连接的数据包。首先可以使用上面的过滤器栏设置过滤条件,缩小关心的数据包范围。然后点击选中一个需要查看的数据包,这时可以在中间区域看到解析后的文本,在最下区看到文本对应的字节数组。通过右键选择“追踪流”会将数据包范围限制在本次通信的来往数据包,该功能实际上是重新设置了前面的过滤条件。右键选择“复制”可以将内容复制成不同的格式。

中间区域与最下面区域分别显示的是按照协议自动解析后的文本和数据包原始字节数组。如果在中间区域选中某个文本片段,最下区域相应的字节数组也会被选中。

wireshark-002

选中片段后可以通过右键“导出分组字节流”保存这部分字节到一个.raw文件,这样对于那些需要解密或特殊处理的数据可以再用其他工具处理。

wireshark-003

场景二:Mongodb数据包

抓取过程也是用tcpdump,只是在用Wireshark解析时有可能不会被自动识别出是哪种协议,需要手动设置解码方式来正确显示解析后的文本。选中数据包后右键“解码为”打开设置界面,可以看到Wireshark支持很多常见的解码方式。

wireshark-004

场景三:HTTP包重放

捕获HTTP协议的数据包后,将content部分存为.raw文件,然后用ab、curl等工具进行重放来定位问题或做压力测试。

ab -k -c 10000 -n 100000 -p 'abc.raw' -T 'application/json;charset=utf-8' -H 'cpv: 2.0' 'http://172.16.0.33:9091/app/msg?cmd=login'

补充:Wireshark显示过滤器

当捕获的内容比较多,难以直观看到期望的数据时,可以通过设置过滤条件缩小显示的范围。Wireshark过滤器栏支持用点(.)联想出特定的属性。点击过滤器栏右侧的“表达式…”可以打开表达式编辑窗口,编辑复杂表达式后添加到过滤器栏。表达式绿色是正确,红色是错误,黄色是结果不一定准确。

# 显示来源是172.27.*.*的,并且目的不是10.230.1.123的封包
ip.src == 172.27.0.0/16 and ip.dst != 10.230.1.123

# 显示来源或目的端口是5432,并且是POST请求方式的HTTP封包
tcp.port == 5432 and http.request.method== "POST"

# 显示请求的uri包含"jelly/msg"的HTTP封包
http.request.uri contains "jelly/msg"
lower(http.request.uri) contains "jelly/msg"

# 显示特定偏移位置符合条件的包,[20:4]表示从第21开始取4个字节
tcp[20:3] == 47:45:54
http.host[0:4] == "trac"

HTTP包工具Fiddler

参考 http://www.cnblogs.com/yyhh/p/5140852.html

在本地计算机上启动Fiddler后,它将自动设置好局域网代理服务,默认8888端口,记录通过该端口转发的网络请求和响应,用于分析数据、修改数据、调试功能。

场景一:直接在本机上用浏览器访问服务地址

场景二:客户端通过本机的接入到互联网中

Creative Commons License

本文基于署名-非商业性使用-相同方式共享 4.0许可协议发布,欢迎转载、使用、重新发布,但请保留文章署名wanghengbin(包含链接:https://wanghengbin.com),不得用于商业目的,基于本文修改后的作品请以相同的许可发布。

发表评论