tcpdump( dump the traffic on a network)
熟练使用tcpdump需要对tcp头部和原理有较深的理解。
原理
底层是通过libpcap库来实现的,tcpdump调用libpcap的api函数,由libpcap进入到内核态到链路层来抓包,如下图。图中的BPF是过滤器,可以根据用户设置用于数据包过滤减少应用程序的数据包的包数和字节数从而提高性能。BufferQ是缓存供应用程序读取的数据包。我们可以说tcpdump底层原理其实就是libpcap的实现原理。
而libpcap在linux系统链路层中抓包是通过PF_PACKET套接字来实现的(不同的系统其实现机制有差异)。更具体的细节一般人就没必要了解的太深了。。
https://blog.csdn.net/notbaron/article/details/79735414
参数
有很多参数,没必要全部记住,熟练其中5个就满足大部分工作需要了,其他的用到再查不迟。
-i: 指定网卡
-n : 不解析主机名
-nn : 不解析主机名和端口名
-s: 指定包的大小。-s 0指定数据包大小为262144字节,可以使得抓到的数据包不被截断,保证完整性
-c: 指定抓包数量
-w:保存到文件,以便后续在windows上使用Wireshark详细分析
-v -vv -vvv: 输出的详细级别
-X: 以十六进制和 ASCII 显示
-G: -G 60 每60秒循环使用-w指定的文件。比如-w %Y%m%d-%H%M%S.pcap,那每60秒就会生成一个以当前时间命名的文件。 另外如果命令中有-c选项,当文件大小达到size变量的值,文件名格式则会以file<count>的形式变化。
-Z: 指定具有root权限的用户。
例子
参考: http://www.cnblogs.com/starlion/p/9017495.html
1、抓取HTTP包
tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854
[20:2]意思是 过滤从20字节开始的2个字节,也就是第20和第21字节。
对照tcp头部,一行是4字节,可以算出来第六行的的字节是20-23。(因为字节是从0开始编号的)
也就是说,如果有选项,那么[20:2]对应选项部分的第1个字节和第2个字节。
如果没有选项,对应的是tcp报文中数据部分 开头的两个字节。
tcp报文的数据部分是http报文。http报文分为http头部和数据部分,所以[20:2]实际上是http头部的前两个字节
0x4745 为"GET"前两个字母"GE"的16进制, 0x4854 为"HTTP"前两个字母"HT"的16进制
2、抓取源端口大于1024的TCP数据包
tcpdump 'tcp[0:2] > 1024'
如果你看懂了上面的,这个肯定也懂
3、过滤带有选项的IPv4包或者IPv6包
tcpdump 'ip[0] > 69'
IP头部格式如下
ip[0]表示ip头部中编号为0的字节,也就是第一行的第一字节,即
,没有选项的时候,第一个字节的二进制值通常为:01000101,分成两个部分:
0100 = 4 表示IP版本 0101 = 5 表示头部长度(单位是4字节),将这个值转换为10进制就是69,如果大于69,就说明有选项或者是IPv6包
4、抓不分片的IP包
tcpdump 'ip[6] = 64'
从上图中可以看出,分片信息在IP头的第七和第八字节(即编号为6和7):
Bit 0: 保留,必须是0
Bit 1: (DF) 0 = 可能分片, 1 = 不分片
Bit 2: (MF) 0 = 最后的分片, 1 = 还有分片
Fragment Offset字段只有在分片的时候才使用。
要抓带DF位标记的不分片的包,第七字节的值应该是:
01000000= 64
5、抓icmp包
tcpdump -i eth1 -c 5 -nn icmp