tcpdump高级用法(高级过滤包头)

注意:继续本文之前,必须了解tcp/ip包头的头部信息,可查看如下博文:
网络基础知识(IP数据报文结构)三
网络基础知识(TCP/UDP报文格式)四
网络基础知识(HTTP协议)五

1.高级用法

如果不熟悉基本用法可以参考抓包工具tcpdump基本用法

proto[x:y]          : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(第一字节从0开始排)
proto[x:y] & z = 0  : proto[x:y]和z的与操作为0
proto[x:y] & z !=0  : proto[x:y]和z的与操作不为0
proto[x:y] & z = z  : proto[x:y]和z的与操作为z
proto[x:y] = z      : proto[x:y]等于z

操作符:

>  : greater 大于
<  : lower 小于
>= : greater or equal 大于或者等于
<= : lower or equal 小于或者等于
=  : equal  等于
!= : different  不等于

2.用法示例

2.1 位操作方式判断是否带有选项
“一般”的IP头是20字节,但IP头有选项设置,不能直接从偏移21字节处读取数据。IP头有个长度字段可以知道头长度是否大于20字节。
通常第一个字节的二进制值是:01000101,分成两个部分:
0100 = 4 表示IP版本 0101 = 5 表示IP头32 bit的块数,5 x 32 bits = 160 bits or 20 bytes
如果第一字节第二部分的值大于5,那么表示头有IP选项。

0100 0101 : 第一字节的二进制
0000 1111 : 与操作
<=========
0000 0101 : 结果
正确的过滤方法
tcpdump  'ip[0] & 15 > 5'

或者
tcpdump  'ip[0] & 0x0f > 5'

2.2 抓取源端口大于1024的TCP数据包

tcpdump 'tcp[0:2] > 1024'
or
tcpdump 'tcp src portrange 1025-65535'

2.3 匹配TCP数据包的特殊标记
在TCP 3次握手中,两个主机是如何交换数据
1、源端发送 SYN
2、目标端口应答 SYN,ACK
3、源端发送 ACK

只抓取SYN包,第十四字节是二进制的00000010,也就是十进制的2

tcpdump 'tcp[13] = 2'

抓取 SYN,ACK (00010010 or 18)

tcpdump 'tcp[13] = 18'

抓取SYN或者SYN-ACK

tcpdump 'tcp[13] & 2 = 2'

抓取PSH-ACK

tcpdump 'tcp[13] = 24'

抓所有包含FIN标记的包(FIN通常和ACK一起,表示幽会完了,回头见)

tcpdump 'tcp[13] & 1 = 1'

抓取RST

tcpdump 'tcp[13] & 4 = 4'

TCP标记值:

tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-push, tcp-ack, tcp-urg

抓取TCP标志位

实际上有一个很简单的方法过滤 flags(man pcap-filter and look for tcpflags

tcpdump 'tcp[tcpflags] == tcp-ack'

抓取所有的包,用TCP-SYN 或者 TCP-FIN 设置

tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0

tcpdump 提供了常用的字段偏移名字:
icmptype (ICMP类型字段)
icmpcode (ICMP符号字段)
tcpflags (TCP标记字段)
ICMP类型值有:
icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit,
icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply

2.4 SMTP 数据过滤
我们将弄一个匹配任意包的过滤,这个包包括 “MAIL”
你可以用网址 http://www.easycalculation.com/ascii-hex.php 把ASCII转化为 十六进制, 也可以用python来转化

$ python -c 'print "MAIL".encode("hex")'
4d41494c

所以 “MAIL” 的十六进制是:0x4d41494c
那么规则就是

tcpdump '((port 25) and (tcp[20:4] = 0x4d41494c))'

2.5 HTTP数据过滤

http请求开始格式
GET / HTTP/1.1\r\n (16 bytes counting the carriage return but not the backslashes !)

GET ” 十六进制是 47455420

tcpdump 'tcp[32:4] = 0x47455420'

HTTP数据(从man tcpdump 看到的例子)

打印所有源或目的端口是80, 网络层协议为IPv4, 并且含有数据,而不是SYN,FIN以及ACK-only等不含数据的数据包.

tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

2.6 SSH过滤

我们看看ssh server
OpenSSH 常常应答一些内容,比如"SSH-2.0-OpenSSH_3.6.1p2", 这第一个4 bytes (SSH-)的十六进制值是 0x5353482D

tcpdump 'tcp[(tcp[12]>>2):4] = 0x5353482D'

如果我们想要找到老版本的OpenSSH的任意链接
这时候OpenSSH服务器应答的内容:比如 “SSH-1.99…”

tcpdump '(tcp[(tcp[12]>>2):4] = 0x5353482D) and (tcp[((tcp[12]>>2)+4):2] = 0x312E)'

2.7 ICMP过滤

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Type      |     Code      |          Checksum             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             unused                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Internet Header + 64 bits of Original Data Datagram      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

在ICMP报文中,我们经常过滤 type(1 byte)和code(1 byte)

下图是ICMP报文中 Type ,我们经常用到的几个值:

0    Echo Reply                 [RFC792]   回显应答报文
3    Destination Unreachable     [RFC792]   目的不可达
4    Source Quench             [RFC792]     源冷却报文
5    Redirect                 [RFC792]      重定向报文
8    Echo                     [RFC792]     请求回显报文
11    Time Exceeded             [RFC792]    超时报文

如果我们要过滤报文 type = 4

tcpdump 'icmp[0] = 4'

如我我们仅仅是要找到ICMP 的回显 应答报文,同时 ID是500。

tcpdump -i eth0 '(icmp[0] = 0) and (icmp[4:2] = 0x1f4)'

tshark -V -i eth0 ‘((port 25) and (tcp[20:4] = 0x4d41494c))’
tshark是是另外一个转包工具,wireshark是图形界面的

你可能感兴趣的:(网络技术)