tcpdump是一款资源网络工作人员必备的工具、一款小巧的纯命令行工具
tcpdump - dump traffic on a network,将网络中的流量转储,即针对网络中传输的数据进行抓包,就是常说的抓包工具
类似的工具有wireshark、scapy、Omnipeek、Sniffer等,但tcpdump只能使用命令行执行
本文以Centos 7.6上的tcpdump 进行讲解,详细版本信息如下:
- tcpdump version 4.9.2
- libpcap version 1.5.3
- OpenSSL 1.0.2k-fips 26 Jan 2017
- 抓包命令:
tcpdump -v -i eth0
- -i 用来指定要监听的网卡
- -v 表示以verbose mode显示
- 将监听的数据保存:
tcpdump -v -i eth0 -w 20220403.pcap
- pcap可以使用wireshark等工具打开
- -w表示要将捕获的数据保存下来。
详细使用请参考: MAN PAGE OF TCPDUMP
tcpdump的包过滤规则 过滤规则定义详见过滤规则的写法参见如下文档:
- pcap-filter
- 包过滤表达式–Berkeley Packet Filter (BPF) syntax
包过滤表达式由一个或多个原语组成。原语通常由一个id(名称或数字)和一个或多个限定符组成。有三种不同的限定词:
- type:定义id名称或数字的网络类型,支持的关键字是: host,net ,port ,portrange,即可以通过主机IP、网段、端口、端口范围进行过滤,使用示例如下:
tcpdump -i ens2f1 net 172.25.21.0/24
tcpdump -i ens2f1 port 12345
tcpdump -i ens2f1 portrange 8000-8100
tcpdump -i ens2f1 host 172.25.21.8
- dir: 定义传输方向,支持的关键字是:
src
、dst
、src or dst
、src and dst
,如果没有指定dir限定词,默认是src or dst
- 注意:针对一些 link layers,
inbound
和outbound
限定符可用于指定所需的方向。 - 使用示例:
src net 172.31
、src or dst port 21
- 注意:针对一些 link layers,
- proto 定义了使用的网络协议,支持的关键字是:ether, fddi, tr, wlan, ip, ip6, arp, rarp, decnet, tcp, udp, icmp
- 注意:fddi, tr, wlan是ether的别名, 包结构很类似
- 使用示例:
udp portrange 7000-8000
除上述常规的原语,如下特殊原语关键字不遵循该模式:
gateway
、broadcast
、less
、greater
算术表达式
更复杂的过滤表达式是通过使用单词and
、or
和not
组合原语来构建的
- 捕获所有进出12345端口的IPv4 HTTP报文,即只打印包含数据的报文,不打印SYN、FIN、ACK-only等报文
命令示例:tcpdump -i ens2f1 -vvv -nn 'tcp port 12345 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
- 只抓获GET请求包
命令示例:tcpdump -i ens2f1 -vvv -nn 'tcp port 12345 and tcp[((tcp[12:1] & 0xf0)>>2):4]=0x47455420'
- 只抓获POST请求包
命令示例:tcpdump -i ens2f1 -vvv -nn 'tcp port 12345 and tcp[((tcp[12:1] & 0xf0)>>2):4]=0x504f5354'
理解以上写法,需要熟悉TCP、IP报文结构,详细请阅读 网络安全系列-X: TCP/IP协议报文格式详解
根据TCP/IP报文格式,可以推算出:【注意:0xf0是10进制的240的16进制表示,转换为二进制后是:11110000,0xf是10进制的15的16进制表示,转换为二进制后是:00001111】
- 针对TCP报文:
- 实际数据的起始位置是:tcp[12:1] & 0xf0) >> 2
(单位是字节),也可以写成(tcp[12:1] & 0xf0) >> 4 ) << 2
,因为Data Offset的单位是4个字节
- HTTP的请求方法: 从数据开始的位置再取出四个字节:tcp[((tcp[12:1] & 0xf0) >> 2):4]
-0x47455420
表示GET
,0x504f5354
表示POST
- TCP报头的控制位部分有8位,分别是CWR | ECE | URG | ACK | PSH | RST | SYN | FIN
- tcp[tcpflags] 等价于 tcp[13]
- tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg 这些同样可以理解为别名常量,分别代表 1,2,4,8,16,32,64,如抓取 syn + ack 包,命令如下:
$ tcpdump -i eth0 'tcp[13] == 2 or tcp[13] == 16'
- 针对IP报文:
- IP报头的长度:
(ip[0]&0xf)<<2
- IP报文的数据部分长度:
(ip[2:2] - ((ip[0]&0xf)<<2))
- TCP报文的数据部分长度:(ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)
- IP报头的长度:
- TCP报头的控制位部分有8位,分别是CWR | ECE | URG | ACK | PSH | RST | SYN | FIN
tcpdump -i eth0
默认情况下tcpdump将一直抓包,直到按下”ctrl+c”中止,使用-c选项我们可以指定抓包的数量:
tcpdump -c 2 -i eth0
默认情况下,tcpdump抓包结果中将进行域名解析,显示的是域名地址而非ip地址,使用-n选项,可指定显示ip地址。
增加抓包时间戳使用-tttt选项,抓包结果中将包含抓包日期
抓取特定目标ip和端口的包网络包的内容中,包含了源ip地址、端口和目标ip、端口,可以根据目标ip和端口过滤tcpdump抓包结果
tcpdump -i eth0 dst 172.25.21.22 and port 12345
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)