tcpdump是工作中必用的一道指令,如果熟悉掌握,将会很快的帮你解决问题!文章写的有点多,但是我认为都很有用!
参数列表
设置不解析域名提升速度 | ||
---|---|---|
-n | 不把ip转化成域名,直接显示 ip,避免执行 DNS lookups 的过程,速度会快很多 | |
-nn | 不把协议和端口号转化成名字,速度也会快很多。 | |
-N | 不打印出host 的域名部分.。比如,,如果设置了此选现,tcpdump 将会打印’nic’ 而不是 ‘nic.ddn.mil’. | |
过滤指定网卡的数据包 | ||
-i | 指定要过滤的网卡接口,如果要查看所有网卡,可以 -i any |
|
过滤特定流向的数据包 | ||
-Q | 选择是入方向还是出方向的数据包,可选项有:in, out, inout,也可以使用 –direction=[direction] 这种写法 | |
常用的一些参数 | ||
-A | 以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据 | |
-l | 基于行的输出,便于你保存查看,或者交给其它工具分析 tcpdump -nn -A -s1500 -l | egrep -i ‘User-Agent:|Host’ 通过 egrep 可以同时提取用户代理和主机名(或其他头文件): |
|
-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 文件作为过滤条件表达式的输入, 此时命令行上的输入将被忽略. | |
过滤结果输出到文件 | ||
-w | 使用 -w 参数后接一个以 .pcap 后缀命令的文件名,就可以将 tcpdump 抓到的数据保存到文件中。使用 wireshark 打开此文件便可进行分析 |
tcpdump icmp -w icmp.pcap |
-r | 从文件中读取数据,读取后,我们照样可以使用上述的过滤器语法进行过滤分析。 | tcpdump icmp -r all.pcap |
对输出内容进行控制的参数 | ||
-D | 显示所有可用网络接口的列表 | |
-e | 每行的打印输出中将包括数据包的数据链路层头部信息 | |
-E | 揭秘IPSEC数据 | |
-L | 列出指定网络接口所支持的数据链路层的类型后退出 | |
-Z | 后接用户名,在抓包时会受到权限的限制。如果以root用户启动tcpdump,tcpdump将会有超级用户权限。 | |
-d | 打印出易读的包匹配码 | |
-dd | 以C语言的形式打印出包匹配码. | |
-ddd | 以十进制数的形式打印出包匹配码 | |
控制详细内容的输出 | ||
-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码形式打印出每个包的数据(包括连接层的头部),这在分析一些新协议的数据包很方便。 |
过滤规则组合
有编程基础的同学,对于下面三个逻辑运算符应该不陌生了吧
- and:所有的条件都需要满足,也可以表示为
&&
- or:只要有一个条件满足就可以,也可以表示为
||
- not:取反,也可以使用
!
举个例子,我想需要抓一个来自10.5.2.3
,发往任意主机的3389端口的包
$ tcpdump src 10.5.2.3 and dst port 3389
当你在使用多个过滤器进行组合时,有可能需要用到括号,而括号在 shell 中是特殊符号,因为你需要使用引号将其包含。例子如下:
$ tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'
而在单个过滤器里,常常会判断一条件是否成立,这时候,就要使用下面两个符号
=
:判断二者相等==
:判断二者相等!=
:判断二者不相等
当你使用这两个符号时,tcpdump 还提供了一些关键字的接口来方便我们进行判断,比如
- if:表示网卡接口名、
- proc:表示进程名
- pid:表示进程 id
- svc:表示 service class
- dir:表示方向,in 和 out
- eproc:表示 effective process name
- epid:表示 effective process ID
内容输出结构
21:26:49.013621 IP 172.20.20.1.15605 > 172.20.20.2.5920: Flags [P.], seq 49:97, ack 106048, win 4723, length 48
从上面的输出来看,可以总结出:
- 第一列:时分秒毫秒 21:26:49.013621
- 第二列:网络协议 IP
- 第三列:发送方的ip地址+端口号,其中172.20.20.1是 ip,而15605 是端口号
- 第四列:箭头 >, 表示数据流向
- 第五列:接收方的ip地址+端口号,其中 172.20.20.2 是 ip,而5920 是端口号
- 第六列:冒号
- 第七列:数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length,其中 [P.] 表示 PUSH 标志位为 1,更多标识符见下面
理解 Flag 标识符
截取数据只是第一步,第二步就是理解这些数据,下面就解释一下 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]
看出。下面是常见的 TCP 报文的 Flags:
[S]
: SYN(开始连接)[.]
: 没有 Flag[P]
: PSH(推送数据)[F]
: FIN (结束连接)[R]
: RST(重置连接)
而第二条数据的 [S.]
表示 SYN-ACK
,就是 SYN
报文的应答报文。
先看看 tcpdump 的具体参数及意义:
-i :指定 tcpdump 监听的网络接口
-s :指定要监听数据包的长度
-c :指定要监听的数据包数量,达到指定数量后自动停止抓包
-w :指定将监听到的数据包写入文件中保存
-A :指定将每个监听到的数据包以 ACSII 可见字符打印
-n :指定将每个监听到数据包中的域名转换成 IP 地址后显示
-nn :指定将每个监听到的数据包中的域名转换成 IP 、端口从应用名称转换成端口号后显示
-e :指定将监听到的数据包链路层的信息打印出来,包括源 mac 和目的 mac ,以及网络层的协议
-p :将网卡设置为非混杂模式,不能与 host 或 broadcast 一起使用
-r :指定从某个文件中读取数据包
-S :指定打印每个监听到的数据包的 TCP 绝对序列号而非相对序列号
OK ,参数介绍先到这里,下面看几个具体例子
先来看一个比较基本的用法:
#tcpdump -i eth0
@eth0为参数值,表示需要抓包的网口,这是个必需参数哦。
tcpdump 支持很多的关键字,下面先看几个例子:
#tcpdump -i eth0 host 192.168.0.250
@在网口eth0上抓取主机地址为192.168.0.250的所有数据包。
#tcpdump -i eth0 net 192.168.0.0/24
@在网口eth0上抓取网络地址为192.168.0.0/24的所有数据包
#tcpdump -i eth0 port 80
@在网口eth0上抓取端口为80的所有数据包(注意,这里不区分是源端口还是目的端口)
当然,我们也可以指定源端口或目的端口
#tcpdump -i eth0 src port 80 and dst port 6100
@在网口eth0上抓取源端口为80且目的端口为6100的数据包,这里用到了and逻辑运算符,后面再介绍
#tcpdump -i eth0 icmp
@在网口eth0上抓取所有icmp协议的数据包
以上几个例子,可以大致体现出tcpdump的基本用法。
实际上, tcpdump 主要包括三种类型的关键字,第一种是关于类型的关键字,主要包括 host , net , port ,如上面的例( 1 )( 2 )( 3 ),第二种 是确定传输方向的关键字,主要包括 src , dst , src or dst , src and dst ,这些关键字指明了传输的方向,如上面的例( 4 )。第三种是协议关键字,包括 fddi , ip , arp , rarp , tcp , udp , imcp 等,如上面的例( 5 )。
除了这三种类型的关键字外,还有其他重要的关键字,如: gateway , broadcast , less , greater ,还有三种逻辑运算,取非运算是 ‘not’ 、 ‘!’ ,与运算符是 ‘and’ 、 ‘&&’ 、
或运算符是 ‘or’ 、 ‘||’ ,这些关键字可以组合起来构成强大的组合条件来满足我们的需求。
#tcpdump -i eth0 -s 1400 -nn host 192.168.0.250 and ! 192.168.0.74 and icmp -e
@抓取网口eth0上192.168.0.250与除192.168.0.74外的其他主机之间的icmp报文
#tcpdump -i eth0 -s 1400 -nn tcp and \(host 192.168.0.250 and ! 192.168.0.74\)
@抓取网口eth0上192.168.0.250与除192.168.0.74外的所有tcp数据包,
这里用到了括号,注意,在tcpdump中使用括号时必须用转义
#tcpdump -i eth0 ether src or dst 00:21:85:6C:D9:A3
@抓取网口eth0上源mac地址或目的mac地址为00:21:85:6C:D9:A3的所有数据包,
注意,这里的mac地址格式必须以':'分隔。