一、背景
当后台服务被安装在linux操作系统上,出现某些问题时,可能需要通过抓数据包的形式,分析接口调用传送返回的数据等,甚至以此判断接口是否调用成功或是否存在丢包的情况。基于此,本文阐明使用 tcpdump 来进行基本的抓包和分析。
二、知识点
1、常用选项
(1) 抓包选项
-c:指定要抓取的包数量。注意,是最终要获取这么多个包。 例如,指定"-c 10"将获取10个包,但可能已经处理了100个包, 只不过只有10个包是满足条件的包。 -i interface:指定tcpdump需要监听的接口。 若未指定该选项,将从系统接口列表中搜寻编号最小的已配置好的接口 (不包括loopback接口,要抓取loopback接口使用tcpdump -i lo), 一旦找到第一个符合条件的接口,搜寻马上结束。 可以使用'any'关键字表示所有网络接口。 -n:对地址以数字方式显式,否则显式为主机名,也就是说-n选项不做主机名解析。 -nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名。 -N:不打印出host的域名部分。例如tcpdump将会打印'nic'而不是'nic.ddn.mil'。 -P:指定要抓取的包是流入还是流出的包。 可以给定的值为"in"、"out"和"inout",默认为"inout"。 -s len:设置tcpdump的数据包抓取长度为len,如果不设置默认将会是65535字节。 对于要抓取的数据包较大时,长度设置不够可能会产生包截断,若出现包截断, 输出行中会出现"[|proto]"的标志(proto实际会显示为协议名)。 但是抓取len越长,包的处理时间越长,并且会减少tcpdump可缓存的数据包的数量,从而会导致数据包的丢失, 所以在能抓取我们想要的包的前提下,抓取长度越小越好。
其中:
- -i
可以通过以上命令查询当前有多少个网卡。绿色部分表示网卡。当 -i 没有指定网卡的时候这里默认就是抓取 eth0 这个网卡的包,若要指定,可以通过 -i lo ---- 表示抓取网卡 lo 上面的数据包。
(2) 输出选项
-e:输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC。 -q:快速打印输出。即打印很少的协议相关信息,从而输出行都比较简短。 -X:输出包的头部数据,会以16进制和ASCII两种方式同时输出。 -XX:输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细。 -v:当分析和打印的时候,产生详细的输出。 -vv:产生比-v更详细的输出。 -vvv:产生比-vv更详细的输出。
(3) 其它功能性选项
-D:列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于"-i"后。 -F:从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效。 -w:将抓包数据输出到文件中而不是标准输出。 可以同时配合"-G time"选项使得输出文件每time秒就自动切换到另一个文件。 可通过"-r"选项载入这些文件以进行分析和打印。 -r:从给定的数据包文件中读取数据。使用"-"表示从标准输入中读取。
2、根据指定条件抓包
port:指定端口上的数据包
端口类型 port : 抓取指定类型的端口, 端口类型包括:tcp/udp
src host xxx : 抓取 host为 xxx 发出的数据包
dst host xxx : 抓取 发送给 host 为xxx 的数据包
类型的关键字
host(缺省类型): 指明一台主机,如:host 210.27.48.2
net: 指明一个网络地址,如:net 202.0.0.0
port: 指明端口号,如:port 23
确定方向的关键字
src: src 210.27.48.2, IP包源地址是210.27.48.2
dst: dst net 202.0.0.0, 目标网络地址是202.0.0.0
dst or src(缺省值)
dst and src
协议的关键字:缺省值是监听所有协议的信息包
fddi
ip
arp
rarp
tcp
udp
其他关键字
gateway
broadcast
less
greater
常用表达式:多条件时可以用括号,但是要用转义
非 : ! or “not” (去掉双引号)
且 : && or “and”
或 : || or “or”
说明:
- host表示主机名,此时可以通过 hostname来获取主机名
- 多个筛选条件使用 and 进行连接
3、示例
(1) 抓取默认第一个网卡的某端口上的10个数据包
tcpdump -c 10 port 8500 -w cc.cap
说明:
- 当没有指明 -i 的时候,默认是抓取第一个网卡上传送的数据包,-i eth0 表示抓取网卡 eth0 上的数据包。
- -w 表示将抓取的数据内容写到 cc.cap文件中
(2) 截获主机hostname发送的所有数据包
tcpdump -i eth0 src host localhost.localdomain
(3) 监视所有发送到主机hostname的数据包
tcpdump -i eth0 dst host hostname
(4) 监视指定主机和端口的数据包
tcpdump -i eth0 tcp port 22 and host hostname
(5) 监视指定网络的数据包,如本机与192.168网段通信的数据包,抓取 10 个
tcpdump -i eth0 -c 10 net 192.168
(6) 抓取 http/https/ssl 的请求头和响应信息
a) 过滤 http Get请求
tcpdump -i eth0 -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
b) 过滤 http Post 请求
tcpdump -i eth0 -s 0 -A 'tcp dst port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)' -vvv -w /home/suxin/hello.cap
c) 过滤HTTP的请求和响应头信息,以及请求和响应消息体信息
`过滤443端口:` tcpdump -i eth0 -A -s 0 'tcp port 443 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -vvv -w /home/suxin/hello.cap ##443端口对应了https `过滤80端口:` tcpdump -i eth0 -X -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -vvv -w /home/suxin/hello.cap `过滤所有端口:` tcpdump -i eth0 -X -s 0 '(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -vvv -w /home/suxin/hello.cap
(7) 抓取主机10.37.63.255和主机10.37.63.61或10.37.63.95的通信
tcpdump host 10.37.63.255 and (10.37.63.61 or 10.37.63.95)
说明:
host 后面的 ip都是指 host
(8) 抓取主机192.168.13.210除了和主机10.37.63.61之外所有主机通信的数据包
tcpdump -b host 10.37.63.255 and ! 10.37.63.61
(9) 抓取主机10.37.63.255 除了和主机10.37.63.61之外所有主机通信的ip包
tcpdump ip -n host 10.37.63.255 and ! 10.37.63.61
(10) 抓取主机10.37.63.3所有在TCP 80端口的数据包
tcpdump host 10.37.63.3 and tcp port 80
(11) 抓取HTTP主机10.37.63.3在80端口接收到的数据包
tcpdump host 10.37.63.3 and dst port 80
(12) 抓取所有经过 en0,目的地址是 192.168.1.254 或 192.168.1.200 端口是 80 的 TCP 数据
tcpdump -i en0 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
(13) 只抓 SYN 包
tcpdump -i eth0 'tcp[tcpflags] = tcp-syn'
(14) 抓 SMTP 数据,抓取数据区开始为”MAIL”的包,”MAIL”的十六进制为 0x4d41494c
(15) 抓 HTTP GET 数据,”GET “的十六进制是 0x47455420
(16) 抓 SSH 返回,”SSH-“的十六进制是 0x5353482D
(17) 高级包头过滤如前两个的包头过滤,首先了解如何从包头过滤信息
(18) 抓 DNS 请求数据
三、常见问题解决
1、抓取的数据包写入到文件中,打开看文件内容是乱码
tcpdump -r /home/cc.cap
参考:
https://www.jianshu.com/p/d0ba8979c42d