tcpdump 是一个运行在命令行下的抓包工具,它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包;这个命令可以针对指定网卡、端口、协议进行抓包,可以结合wireshark对抓包的结果进行分析;参考
1、tcpdump命令格式:tcpdump --help
tcpdump [-aAbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ]
[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]
[ -i interface ] [ -j tstamptype ] [ -M secret ] [ --number ]
[ -Q|-P in|out|inout ]
[ -r file ] [ -s snaplen ] [ --time-stamp-precision precision ]
[ --immediate-mode ] [ -T type ] [ --version ] [ -V file ]
[ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z postrotate-command ]
[ -Z user ] [ expression ]
tcpdump [-adeflnNOpqStvx][-c<数据包数目>][-dd][-ddd][-F<表达文件>][-i<网络界面>][-r<数据包文件>][-s<数据包大小>][-tt][-T<数据包类型>][-vv][-w<数据包文件>][输出数据栏位]
tcpdump -i <接口|any> -C <每文件大小> -W <文件个数> -w <保存文件名> 抓包过滤条件
2、tcpdump参数介绍:
- -a 尝试将网络和广播地址转换成名称。
- -c<数据包数目> 收到指定的数据包数目后,就停止进行倾倒操作。
- -d 把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出。
- -dd 把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出。
- -ddd 把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出。
- -e 在每列倾倒资料上显示连接层级的文件头。
- -f 用数字显示网际网络地址。
- -F<表达文件> 指定内含表达方式的文件。
- -i<网络界面> 使用指定的网络截面送出数据包。
- -l 使用标准输出列的缓冲区。
- -n 不把主机的网络地址转换成名字。
- -N 不列出域名。
- -O 不将数据包编码最佳化。
- -p 不让网络界面进入混杂模式。
- -q 快速输出,仅列出少数的传输协议信息。
- -r<数据包文件> 从指定的文件读取数据包数据。
- -s<数据包大小> 设置每个数据包的大小。
- -S 用绝对而非相对数值列出TCP关联数。
- -t 在每列倾倒资料上不显示时间戳记。
- -tt 在每列倾倒资料上显示未经格式化的时间戳记。
- -T<数据包类型> 强制将表达方式所指定的数据包转译成设置的数据包类型。
- -v 详细显示指令执行过程。
- -vv 更详细显示指令执行过程。
- -x 用十六进制字码列出数据包资料。
- -w<数据包文件> 把数据包数据写入指定的文件。
3、命令使用:
- tcpdump -i en0 port 3306 -X -c 3
-i:是interface的含义,tcpdump监听哪个网卡
-X:需要把协议头和包内容都原原本本的显示出来(tcpdump会以16进制和ASCII的形式显示),这在进行协议分析时是绝对的利器
port 3306:抓取对应端口的报文
-c:指tcpdump抓取包的数量
-l:将tcpdump的输出变为“行缓冲”方式,这样可以确保tcpdump遇到的内容一旦是换行符即将缓冲的内容输出到标准输出,以便于利用管道或重定向方式来进行后续处理
- Linux/UNIX的标准I/O提供了全缓冲、行缓冲和无缓冲三种缓冲方式;标准错误是不带缓冲的,终端设备常为行缓冲,而其他情况默认都是全缓冲
例如我们只想提取包的每一行的第一个域(时间域),这种情况下我们就需要-l将默认的全缓冲变为行缓冲了
tcpdump -i en0 port 3306 -l | awk '{print $1}'
- 网络包存储到磁盘:tcpdump -i en0 port 3306 -C 3 -w cp.text
-w:将网络包存储到磁盘中(二进制)cp.text
- 流量回放:tcpdump -i en0 port 3306 -C 3 -r cp.text
-r:将存储的二进制网络包文件(读取raw packets) cp.text
- 报文分析:tcpdump -i en0 -e -nn -X -c 2 'port 3306'
第一行 :tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
提示使用选项-v和-vv,可以看到更全的输出内容
第二行:listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
我们监听的是通过en0这个NIC设备的网络包,且它的链路层是基于以太网的,要抓的包大小限制是262144字节;包大小限制值可以通过-s选项来设置
第三行:16:46:02.345060 78:4f:43:70:ae:8c > 74:ac:5f:d1:4f:6e, ethertype IPv4 (0x0800),
16:46:02.345060 分别对应着这个包被抓到的“时”、“分”、“秒”、“微妙”
78:4f:43:70:ae:8c > 74:ac:5f:d1:4f:6e表示MAC地址78:4f:43:70:ae:8c发送到MAC地址为74:ac:5f:d1:4f:6e的主机,ethertype IPv4 (0x0800)表示
Ethernet帧的协议类型为ipv4(即代码为0x0800)
第四行:length 78: 192.168.43.143.57563 > 192.168.2.123.3306: Flags [S], seq 2440912679,
length 78表示以太帧长度为78;192.168.43.143.57563表示这个包的源IP为192.168.43.143,源端口为57563,“>”表示数据包传输方向,192.168.2.123.3306表示这个数据包的目的端ip为192.168.2.123,目标端口为3306,3306端口是mysql端口;Flags是[S],表明是syn建立连接包(即三次握手的第一次握手),seq 2440912679序号为2440912679,这个其实就是TCP三次握手的第一次握手:client(192.168.43.143)发送syn请求建立连接包
第四行:win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 552057507 ecr 0,sackOK,eol], length 0
win 65535表示窗口大小为65535字节,options [mss 1460,nop,wscale 6,nop,nop,TS val 552057507 ecr 0,sackOK,eol]为tcp首部可选字段mss 1460表示mss是发送端(客户端)通告的最大报文段长度,发送端将不接收超过这个长度的TCP报文段(这个值和MTU有一定关系);nop是一个空操作选项,wscale指出发送端使用的窗口扩大因子为6,sackOK表示发送端支持并同意使用SACK
下面几行分别是IP、TCP首部
4、tcpdump过滤语句
过滤条件大致分为类型、方向和协议
类型关键字:host、net、port,例如host 192.168.31.163指定主机;net 192.168.31.163指明192.168.31.163是一个网络地址;port 21指定端口;如果没有指定类型,缺省的类型是host
tcpdump -i en0 'host 192.168.31.163 and host 119.23.230.194' -c 3
方向关键字:src、dst、dst or src、dst and src
协议关键字:ether、ip、ip6、arp、rarp、tcp、udp等
其他重要关键字:gateway,broadcast,less。greater,还有三种逻辑运算,取非运算是 'not ' '! ',与运算是'and','&&';或运算是'or' ,'||'
- 查找目标及其端口是21或80的网络包
tcpdump -i en0 -c 10 'dst port 21 or dst port 3306' - 想截取主机119.23.230.194和主机192.168.31.163或119.23.230.193的通信,使用命令注意括号的使用
tcpdump -i en0 -c 3 'host 119.23.230.194 and (192.168.31.163 or 119.23.230.193)' - 抓取119.23.230.194的8080、21、3306以外的其他端口网络包
tcpdump -i en0 'host 119.23.230.194 and ! port 8080 and ! port 21 and port 3306'