我们在工作中会遇到的一些场景:

  • 查看线上服务依赖的http接口的request/response(调用反垃圾,mapi,feed)
  • 查看客户端请求服务端的request/response(客户端出现bug,排查服务端返回数据是否正常)

由于工作中主要分析的都是http和tcp包,所以我们主要关注这两种协议的抓包,下面主要分为服务端抓包工具和客户端抓包工具两部分

服务器抓包工具(tcpdump)

Tcpdump 是一个命令行抓包工具,它可以拦截和显示计算机发送或接收的网络数据包

类型表达式

tcpdump可以使用表达式过滤指定类型的流量,有三种主要的表达式类型:type,dir,proto

  • 类型(type)选项包含:host,net,port
  • 方向(dir)选项包含:src,dst
  • 协议(proto)选项包含:tcp,udp,icmp等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. 过滤网卡
tcpdump -i any // 抓所有网卡的数据包
tcpdump -i eth1 // 抓eth1网卡上的数据包(默认是抓第一个网络接口上的数据包)

2. 过滤主机
tcpdump -i eth1 host i.api.weibo.cn // 目的或源地址是i.api.weibo.cn的数据包
tcpdump -i eth1 src host i.api.weibo.cn // 源地址是i.api.weibo.cn的数据包
tcpdump -i eth1 dst host i.api.weibo.cn // 目的地址是i.api.weibo.cn的数据包

3. 过滤端口
tcpdump -i eth1 port 8080 // 目的或源端口是8080的数据包
tcpdump -i eth1 src port 8080 // 源端口是8080的数据包
tcpdump -i eth1 dst port 8080 // 目的端口是8080的数据包

4. 过滤网络
tcpdump -i eth1 net 10.77 // 目的或源网络是10.77.*的数据包
tcpdump -i eth1 src net 10.77 // 源网络是10.77.*的数据包
tcpdump -i eth1 dst net 10.77 // 目的网络是10.77.*的数据包

5. 过滤协议
tcpdump -i eth1 tcp // 指定具体网络协议
tcpdump -i eth1 udp
tcpdump -i eth1 ip
tcpdump -i eth1 arp

逻辑表达式

使用逻辑表达式可以对数据包进行多条件过滤

  • 非 : ! 或者 not
  • 且 : && 或者 and
  • 或 : || 或者 or
  • 改变优先级:()
1
2
3
4
5
tcpdump 'src 10.77.6.161 and (dst port 8080 or 80)'

tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))' //抓取所有经过eth1,目的地址是192.168.1.254或192.168.1.200端口是80的TCP数据

tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))' // 抓取所有经过eth1,目的网络是192.168,但目的主机不是192.168.1.200的TCP数据

高级包头过滤

  • proto[x:y]
1
2
3
4
5
proto[x:y]          : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出34字节(第一字节从0开始排)
proto[x:y] & z = 0 : proto[x:y]和z的与操作为0
proto[x:y] & z !=0 : proto[x:y]和z的与操作不为0
proto[x:y] & z = z : proto[x:y]和z的与操作为z
proto[x:y] = z : proto[x:y]等于z
  • tcp header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |C|E|U|A|P|R|S|F| |
| Offset| Res. |W|C|R|C|S|S|Y|I| Window |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1
2
3
4
5
6
tcpdump -i eth1 'tcp[0:2] > 1024' // 抓取源端口大于1024的TCP数据包
tcpdump -i eth1 'tcp[13] = 2' // 只抓SYN包,00000010
tcpdump -i eth1 'tcp[13] = 18' // 抓SYN, ACK包 00010010
tcpdump -i eth1 'tcp[13] = 16' // 抓ACK包 00010000
tcpdump -i eth1 'tcp[13] = 24' // 抓PSH-ACK 000110000
tcpdump -i eth1 'tcp[13] & 2!=0' // 抓所有带ACK标志位的包

输出显示

默认显示时间戳,ip和协议相关的一些描述信息

1
2
3
4
5
6
7
20:15:09.014452 IP 172.16.138.197.http > 10.69.2.182.31779: Flags [P.], seq 7613:7618, ack 1, win 83, length 5
20:15:09.014516 IP 10.75.22.109.ezmeeting-2 > 10.69.2.182.49872: Flags [P.], seq 629144153:629144884, ack 173790027, win 2621, length 731
20:15:09.014522 IP 10.69.2.182.31779 > 172.16.138.197.http: Flags [.], ack 7618, win 284, length 0
20:15:09.014539 IP 10.69.2.182.49872 > 10.75.22.109.ezmeeting-2: Flags [.], ack 731, win 171, length 0
20:15:09.014608 IP 10.85.65.213.20569 > 10.69.2.206.4972: Flags [P.], seq 1707380290:1707380440, ack 3489947089, win 406, length 150
20:15:09.014909 IP 172.16.106.197.http > 10.69.2.182.46605: Flags [.], ack 1945920941, win 143, length 0
20:15:09.014954 IP 10.77.6.50.5141 > 10.69.2.206.50062: Flags [P.], seq 1931200872:1931201175, ack 3002082898, win 115, length 303

如果需要显示包内容加 -X 选项

抓纯http请求时,可以使用如下任意一个命令,以ASCII的方式显示完整包内容

1
2
3
tcpdump -i eth1 -A -s 0 host i.api.weibo.cn

tcpdump -i eth1 host i.api.weibo.cn -w - | strings

保存文件

使用-w选项可以将捕获的数据包信息写入文件以供以后分析,这些文件就是著名的PCAP(PEE-cap)文件,很多应用都可以处理它,比如wireshark网络包分析工具

1
tcpdump -i eth1 -w ./filename.cap // 将抓包结果保存到filename.cap文件中

线上示例

  • 示例1:msg-processor掉mapi的spage接口(http)
1
2
3
tcpdump -i eth1 host i.api.weibo.cn -w ./mapi.cap

使用wireshark打开,找到spage调用,追踪流,要查看中文的话选择UTF-8编码
  • 示例2:wesync-center查看客户端请求和响应(tcp)
1
2
3
tcpdump -i eth0 tcp port 8080 -w ./wesync.cap

使用wireshark打开,找到有数据传输的包,追踪流,对相应的数据包的二进制数据进行wesync decode来查看对应的request和response

客户端抓包工具

ios抓http/https包(charles)

https://www.jianshu.com/p/5539599c7a25
注意1:iOS 10.3系统,需要在 设置→通用→关于本机→证书信任设置 里面启用完全信任Charles证书
注意2:vpn关掉

  • 示例1:抓取消息箱userlist请求
  • 示例2:抓取主feed刷新请求
  • 示例3:抓取私信图片上传和下载请求
  • 示例4:抓取私信视频上传和下载请求

安卓抓http/https包(charles)

类似ios,设置http代理步骤和ios系统一致,安装ssl证书不同版本系统和厂商手机可能步骤不一样
注意:安卓7.0抓https的数据包需要修改app代码 https://www.jianshu.com/p/a222a420ff35

ios抓tcp包(rvictl + wireshark)

  • 查看手机UDID(iTunes设备信息,点击序列号获取UDID)
  • 通过数据线连接好iOS设备到mac
  • 通过终端输入rvictl -s UDID来创建一个Remote Virtual Interface(RVI、远程虚拟接口),这个接口就代表iOS设备的网络栈了,对这个接口抓包即可
1
2
➜  ~ rvictl -s UDID
Starting device UDID [SUCCEEDED] with interface rvi0
  • 启动wireshark对创建的网络接口进行抓包即可(上图创建的网络接口名称是rvi0)
  • 不需要使用之后,要把这个接口删除 rvictl -x UDID
1
2
➜  ~ rvictl -x UDID
Stopping device UDID [SUCCEEDED]
  • 示例1:抓取发私信请求+tcp三次握手

andriod抓tcp包

  • tpacketcapturepro:在安卓上可以指定app进行抓包,生成cap文件,之后导入wireshark进行分析(非实时)
  • 电脑代理抓包(实测不稳定,网络连接经常断)
* 电脑使用外置网卡上网,绿联
* mac上系统偏好设置-> 共享 -> 互联网共享

![](/media/packet-cap-tools/15301898403866.jpg)





* 手机连接共享wifi,mac上使用wireshark对无线网络接口进行抓包