tcpdump
tcpdump一个unix下的网络数据采集工具,即常说的抓包工具。
tcpdump参数组成
网络上流量、数据包非常多,为了抓取到我们需要的数据包,就需要定义一个精准的过滤器,从大量数据包中抓取出我们所需要的数据包。所以需要抓包工具,其实就是学习如果定义过滤器的过程。
而过滤器的实现就是通过一个又一个参数组合起来的。一个参数不够精准就再加一个参数。直到能留下我们刚兴趣的数据包。
tcpdump的各种参数:
$ tcpdump tcp src host 192.168.10.100
tcpdump [option] [proto] [dir] [type]
--[option]: [ -AdDefIJKlLnNOpqRStuUvxX ] [ -B buffer_size ] [ -c count ]
[ -C file_size ] [ -G rotate_seconds ] [ -F file ]
[ -i interface ] [ -j tstamp_type ] [ -m module ] [ -M secret ]
[ -Q|-P in|out|inout ]
[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
[ -W filecount ]
[ -E spi@ipaddr algo:secret,... ]
[ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]
[ expression ]
--[proto]: tcp、udp、icmp、ip、ip6、arp、rarp、ether、wlan
--[dir]:src、dst、src or dst
--[type]:host、net、port、portrange
- 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。
常用过滤规则
基于IP的过滤:host
使用host就可以指定host ip进行过滤
$ tcpdump host 192.168.10.100
数据包的ip可以再细分为源ip和目标ip两种
# 根据源ip进行过滤
$ tcpdump -i eth2 src 192.168.10.100
# 根据目标ip进行过滤
$ tcpdump -i eth2 dst 192.168.10.200
基于网段进行过滤:net
若你的ip范围是一个网段,可以直接这样指定
$ tcpdump net 192.168.10.0/24
网段同样可以再细分为源网段和目标网段
# 根据源网段进行过滤
$ tcpdump src net 192.168
# 根据目标网段进行过滤
$ tcpdump dst net 192.168
基于端口号进行过滤:port
使用 port 就可以指定特定端口进行过滤。
$ tcpdump port 8088
端口同样可以再细分为源端口,目标端口
# 根据源端口进行过滤
$ tcpdump src port 8088
# 根据目标端口进行过滤
$ tcpdump dst port 8088
如果你想要同时指定两个端口你可以这样写
$ tcpdump port 80 or port 8088
但也可以简写成这样
$ tcpdump port 80 or 8088
如果你的想抓取的不再是一两个端口,而是一个范围,一个一个指定就非常麻烦了,此时你可以这样指定一个端口段。
$ tcpdump portrange 8000-8080
$ tcpdump src portrange 8000-8080
$ tcpdump dst portrange 8000-8080
对于一些常见协议的默认端口,我们还可以直接使用协议名,而不用具体的端口号
比如 http == 80,https == 443 等
$ tcpdump tcp port http
基于协议进行过滤: proto
常见的网络协议有:tcp, udp, icmp, http, ip,ipv6 等
若你只想查看 icmp 的包,可以直接这样写
$ tcpdump icmp
基于IP协议的版本进行过滤
当你想查看 tcp 的包,你也许会这样子写
$ tcpdump tcp
这样子写也没问题,就是不够精准,为什么这么说呢?
ip 根据版本的不同,可以再细分为 IPv4 和 IPv6 两种,如果你只指定了 tcp,这两种其实都会包含在内。
那有什么办法,能够将 IPv4 和 IPv6 区分开来呢?
很简单,如果是 IPv4 的 tcp 包 ,就这样写(友情提示:数字 6 表示的是 tcp 在ip报文中的编号。)
$ tcpdump 'ip proto tcp'
# or
$ tcpdump ip proto 6
# or
$ tcpdump 'ip protochain tcp'
# or
$ tcpdump ip protochain 6
而如果是 IPv6 的 tcp 包 ,就这样写
$ tcpdump 'ip6 proto tcp'
# or
$ tcpdump ip6 proto 6
# or
$ tcpdump 'ip6 protochain tcp'
# or
$ tcpdump ip6 protochain 6
关于上面这几个命令示例,有两点需要注意:
跟在 proto 和 protochain 后面的如果是 tcp, udp, icmp ,那么过滤器需要用引号包含,这是因为 tcp,udp, icmp 是 tcpdump 的关键字。
跟在ip 和 ip6 关键字后面的 proto 和 protochain 是两个新面孔,看起来用法类似,它们是否等价,又有什么区别呢?
关于第二点,网络上没有找到很具体的答案,我只能通过 man tcpdump 的提示, 给出自己的个人猜测,但不保证正确。
proto 后面跟的 的关键词是固定的,只能是 ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, or netbeui 这里面的其中一个。
而 protochain 后面跟的 protocol 要求就没有那么严格,它可以是任意词,只要 tcpdump 的 IP 报文头部里的 protocol 字段为 就能匹配上。
理论上来讲,下面两种写法效果是一样的
$ tcpdump 'ip && tcp'
$ tcpdump 'ip proto tcp'
同样的,这两种写法也是一样的
$ tcpdump 'ip6 && tcp'
$ tcpdump 'ip6 proto tcp'
可选参数解析
设置不解析域名提升速度
- -n:不把ip转化成域名,直接显示 ip,避免执行 DNS lookups 的过程,速度会快很多
- -nn:不把协议和端口号转化成名字,速度也会快很多。
- -N:不打印出host 的域名部分.。比如, 如果设置了此选项,tcpdump 将会打印’nic’ 而不是 ‘nic.ddn.mil’.
过滤结果输出到文件
tcpdump+wireshark配合使用,将tcpdump抓到的包保存为后缀为.pcap,然后用wireshark打开分析。
使用 -w 参数后接一个以 .pcap 后缀命名的文件名,就可以将 tcpdump 抓到的数据保存到文件中。
$ tcpdump icmp -w icmp.pcap
从文件中读取包数据
使用 -w 是写入数据到文件,而使用 -r 是从文件中读取数据。
读取后,我们照样可以使用上述的过滤器语法进行过滤分析。
$ tcpdump icmp -r all.pcap
过滤规则组合
- 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
比如我现在要过滤来自进程名为 nc 发出的流经 en0 网卡的数据包,或者不流经 en0 的入方向数据包,可以这样子写
$ tcpdump "( if=en0 and proc =nc ) || (if != en0 and dir=in)"
参考原文
https://www.cnblogs.com/wongbingming/p/13212306.html
https://blog.csdn.net/ybhuangfugui/article/details/119745385