tcpdump
可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来筛选数据
本文修改自tcpdump使用指南,详细见原文
- option 可选参数:可用于筛选或者显示某些数据
- proto 类过滤器:根据协议进行过滤,可识别的关键词有: tcp, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet
- type 类过滤器:可识别的关键词有:host, net, port, portrange,这些词后边需要再接参数。
- direction 类过滤器:根据数据流向进行过滤,可识别的关键字有:src, dst,同时你可以使用逻辑运算符进行组合,比如 src or dst
tcp报文结构
tcpdump支持根据数据包的标志位进行过滤
tcpdump -i eth0 "tcp[tcpflags] == tcp-syn"
输出内容
下面就解释一下 tcpdump 命令输出各部分的意义。
21:27:06.995846 IP (tos 0x0, ttl 64, id 45646, offset 0, flags [DF], proto TCP (6), length 64)
192.168.1.106.56166 > 124.192.132.54.80: Flags [S], cksum 0xa730 (correct), seq 992042666, win 65535, options [mss 1460,nop,wscale 4,nop,nop,TS val 663433143 ecr 0,sackOK,eol], length 0
21:27:07.030487 IP (tos 0x0, ttl 51, id 0, offset 0, flags [DF], proto TCP (6), length 44)
124.192.132.54.80 > 192.168.1.106.56166: Flags [S.], cksum 0xedc0 (correct), seq 2147006684, ack 992042667, win 14600, options [mss 1440], length 0
21:27:07.030527 IP (tos 0x0, ttl 64, id 59119, offset 0, flags [DF], proto TCP (6), length 40)
192.168.1.106.56166 > 124.192.132.54.80: Flags [.], cksum 0x3e72 (correct), ack 2147006685, win 65535, length 0
最基本也是最重要的信息就是数据报的源地址/端口和目的地址/端口,上面的例子第一条数据报中,源地址 ip 是 192.168.1.106,源端口是 56166,目的地址是 124.192.132.54,目的端口是 80。>
符号代表数据的方向。
此外,上面的三条数据还是 tcp 协议的三次握手过程,第一条就是 SYN 报文,这个可以通过 Flags [S] 看出。而第二条数据的 [S.] 表示 SYN-ACK,就是 SYN 报文的应答报文。
下面是常见的 TCP 报文的 Flags:
-
[S]
: SYN(开始连接) -
[.]
: 没有 Flag -
[P]
: PSH(推送数据) -
[F]
: FIN (结束连接) -
[R]
: RST(重置连接)
可选参数解析
设置不解析域名提升速度
-
-n
:不把ip转化成域名,直接显示 ip,避免执行 DNS lookups 的过程,速度会快很多 -
-nn
:不把协议和端口号转化成名字,速度也会快很多。 -
-N
:不打印出host 的域名部分.。比如,,如果设置了此选现,tcpdump 将会打印’nic’ 而不是 ‘nic.ddn.mil’.
过滤结果输出到文件
使用 tcpdump 工具抓到包后,往往需要再借助其他的工具进行分析,比如常见的 wireshark 。使用 -w 参数后接一个以 .pcap
后缀命令的文件名,就可以将 tcpdump 抓到的数据保存到文件中。
tcpdump icmp -w icmp.pcap
从文件中读取包数据
使用 -w 是写入数据到文件,而使用 -r 是从文件中读取数据。读取后,我们照样可以使用上述的过滤器语法进行过滤分析。
tcpdump icmp -r all.pcap
控制详细内容的输出
-
-v
:产生详细的输出. 比如包的TTL,id标识,数据包长度,以及IP包的一些选项。同时它还会打开一些附加的包完整性检测,比如对IP或ICMP包头部的校验和。 -
-vv
:产生比-v更详细的输出. 比如NFS回应包中的附加域将会被打印, SMB数据包也会被完全解码。(摘自网络,目前我还未使用过) -
-vvv
:产生比-vv更详细的输出。比如 telent 时所使用的SB, SE 选项将会被打印, 如果telnet同时使用的是图形界面,其相应的图形选项将会以16进制的方式打印出来
控制时间的显示
-
-t
:在每行的输出中不输出时间 -
-tt
:在每行的输出中会输出时间戳 -
-ttt
:输出每两行打印的时间间隔(以毫秒为单位) -
-tttt
:在每行打印的时间戳之前添加日期的打印(此种选项,输出的时间最直观)
显示数据包的头部
-
-x
:以16进制的形式打印每个包的头部数据(但不包括数据链路层的头部) -
-xx
:以16进制的形式打印每个包的头部数据(包括数据链路层的头部) -
-X
:以16进制和 ASCII码形式打印出每个包的数据(但不包括连接层的头部),这在分析一些新协议的数据包很方便。 -
-XX
:以16进制和 ASCII码形式打印出每个包的数据(包括连接层的头部),这在分析一些新协议的数据包很方便。
过滤指定网卡的数据包
-
-i
:指定要过滤的网卡接口,如果要查看所有网卡,可以-i any
过滤特定流向的数据包
-
-Q
: 选择是入方向还是出方向的数据包,可选项有:in, out, inout,也可以使用--direction=[direction]
这种写法
其他常用的一些参数
-
-A
:以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据 -
-l
: 基于行的输出,便于你保存查看,或者交给其它工具分析 -
-q
: 简洁地打印输出。即打印很少的协议相关信息, 从而输出行都比较简短. -
-c
: 捕获 count 个包 tcpdump 就退出 -
-s
: tcpdump 默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s number, number 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。 -
-S
: 使用绝对序列号,而不是相对序列号 -
-C
:file-size,tcpdump 在把原始数据包直接保存到文件中之前, 检查此文件大小是否超过file-size. 如果超过了, 将关闭此文件,另创一个文件继续用于原始数据包的记录.
新创建的文件名与-w 选项指定的文件名一致, 但文件名后多了一个数字.该数字会从1开始随着新创建文件的增多而增加. file-size的单位是百万字节(nt: 这里指1,000,000个字节,并非1,048,576个字节, 后者是以1024字节为1k, 1024k字节为1M计算所得, 即1M=1024 * 1024 = 1,048,576) -
-F
:使用file 文件作为过滤条件表达式的输入, 此时命令行上的输入将被忽略.
对输出内容进行控制的参数
-
-D
: 显示所有可用网络接口的列表 -
-e
: 每行的打印输出中将包括数据包的数据链路层头部信息 -
-E
: 揭秘IPSEC数据 -
-L
:列出指定网络接口所支持的数据链路层的类型后退出 -
-Z
:后接用户名,在抓包时会受到权限的限制。如果以root用户启动tcpdump,tcpdump将会有超级用户权限。 -
-d
:打印出易读的包匹配码 -
-dd
:以C语言的形式打印出包匹配码. -
-ddd
:以十进制数的形式打印出包匹配码
抓包实例
dump MySQL命令
tcpdump -i eth0 -l -s 0 -w - dst port 3306 | stdbuf -o0 strings| stdbuf -o0 grep "SELECT\|INSERT\|UPDATE|\FROM\|WHERE\|ORDER\|AND\|LIMIT\|FROM\|SET\|COMMIT\|ROLLBACK"
dump用户IP
tcpdump -nn -A -s1000 -l | egrep -i 'X-Forwarded-For:|X-Real-IP:'
dump redis命令
tcp抓包看看本机redis使用,port远程redis port
tcpdump -i any -l -s 0 -w - dst port 4021 | stdbuf -o0 strings
thrift
tcpdump -tttt -s0 -X -vv host 10.0.0.1 -i any
进程端口没开启keepalive时,netstat会有很多无用的连接。此时发现有用的ip的办法
tcpdump -i any tcp port 8080
参考资料:
- tcpdump
- pcap-filter
- tcpdump使用指南
- [译]tcpdump 示例教程