wireshark显示过滤器用来对捕获的报文,进行筛选显示,从而方便在大量的报文中,找到自己感兴趣的报文。
显示过滤器的语法和捕获过滤器(BPF语法)不一样。
显示过滤器过滤的内容
过滤字段
过滤字段可以是报文详情面板中的任意字段。
不过形式和报文详情里面的表述不一样。比如源ip地址,在报文详情面板是:Source,在显示过滤表达式是ip.src
那么 source 和 ip.addr 映射关系在那里查找呢?
1、View → Internals → Supported Protocols.
2、点击字段在,状态栏可以看到
字段的值
字段的值其实是有类型的
Unsigned integer | 可以是8、16、10进制表示,如下是一样的 |
Signed integer | 同上,只不过有符号 |
Boolean | 如果报文中有这个字段,就为true,比如: tcp.flags.syn |
Ethernet address | MAC地址 eth.dst == ff:ff:ff:ff:ff:ff |
IPV4 | IPV4地址,比如: ip.addr == 192.168.0.1 |
IPV6 | IPV6地址,比如: ipv6.addr == ::1 |
Text String | 字符串,比如:
|
比较操作符
有了字段和字段值,还有这两个的关系:比较操作符
English | C-like | Description and example |
---|---|---|
eq | == | Equal. |
ne | != | Not equal. |
gt | > | Greater than. |
lt | < | Less than. |
ge | >= | Greater than or equal to. |
le | <= | Less than or equal to. |
contains | Protocol, field or slice contains a value. | |
matches | ~ | Protocol or text field match Perl regualar expression. |
bitwise_and | & | Compare bit field value. |
逻辑操作符号
连接表达式,构成更复杂的表达式
English | C-like | Description and example |
---|---|---|
and | && | Logical AND. |
or | || | Logical OR. |
xor | ^^ | Logical XOR. |
not | ! | Logical NOT. |
[…] | See “Slice Operator” below. 参考下文 | |
in | See “Membership Operator” below. 参考下文 |
Slice Operator
选取一个字段值的部分来做比较,比如:有个MAc地址如下:00:00:83:00:20:20,下面是匹配的值
eth.src[0:3] == 00:00:83 | 0:起始偏移量 3:长度 |
eth.src[1-2] == 00:83 | 1:起始偏移量 2:结束偏移量 |
eth.src[:4] == 00:00:83:00 | 从开始取4个长度,等价于[0:4] |
eth.src[4:] == 20:20 | 第4个偏移量到结尾 |
eth.src[2]==83 | 只取第2个偏移量的值,等价于[n:1] |
eth.src[0:3,1-2,:4,4:,2] == 00:00:83:00:83:00:00:83:00:20:20:83 | 使用逗号连接分段 |
Membership Operator(Set集合)
枚举
tcp.port in {80 443 8080}
可以认为是 tcp.port == 80 || tcp.port == 443 || tcp.port == 8080 的缩写
范围
tcp.port in {443 4430..4434}
这个不仅仅是tcp.port == 443 || (tcp.port >= 4430 && tcp.port ⇐ 4434)的缩写,
因为比较操作符会比较一个数据包里面的任何字段,只要满足就认为是满足,而不是比较同一个字段。
比如:有个数据包包含端口 80、56789。那么 56789 >= 4430 && 80 ⇐ 4434 会是真的
但tcp.port in {443 4430..4434}是针对同一个字段过滤,所以这样的数据包就不满足
Set集合不仅可以用在数值,还可以用在字符串、ip地址等
http.request.method in {"HEAD" "GET"}
ip.addr in {10.0.0.5 .. 10.0.0.9 192.168.1.1..192.168.1.9}
frame.time_delta in {10 .. 10.5}
函数
Function | Description |
---|---|
upper | Converts a string field to uppercase. |
lower | Converts a string field to lowercase. |
len | Returns the byte length of a string or bytes field. |
count | Returns the number of field occurrences in a frame. |
string | Converts a non-string field to a string. |
1、upper和lower用来强制使用大小写敏感
比如:lower(http.server) contains "apache"
2、找出http的长url:len(http.request.uri) > 100 注意:len返回的是字节长度,而不是字符串长度
3、string 可以把其他类型转换为string类型,这样就可以用 matches 和 contains 比较操作符
For example, to match odd frame numbers:
string(frame.number) matches "[13579]$"
to match IP addresses ending in 255 in a block of subnets (172.16 to 172.31):
string(ip.dst) matches "^172\.(1[6-9]|2[0-9]|3[0-1])\..{1,3}\.255"
一个常见的错误认知
当使用 != 操作符时,wireshark可能会提示 已过时,或者 这个结果可能不符合预期。
ip.addr == 1.2.3.4:过滤所有包含1.2.3.4 IP地址的数据包,但 ip.addr != 1.2.3.4 并不表示 不包含 1.2.3.4的数据包。
因为:ip.addr != 1.2.3.4 对于wireshark来说的意思是:数据包的ip地址不等于1.2.3.4,但数据包有两个IP,有任何一个不等于,这个表达式都会为true。所以这样过滤出来的数据包还是有包含1.2.3.4的IP的。
如果需要不包含 1.2.3.4的数据包可以这样写:!(ip.addr == 1.2.3.4)
常用显示过滤器
语义 | 表达式 | 备注 |
包含字符串yang | frame contains "yang" | 这个是区分大小写的 |
包含字符串yang | frame matches "yang" frame matches "(?i)yang" | 不区分大小写 |
搜索多个单词 | frame matches "(yang|name)" frame matches "(?i)(yang|name)" | 包含单词yang和name |
指定中间字符串 | frame matches "a.{1,5}b" | a和b之间,有1到5个字符 |
参考:https://www.wireshark.org/docs/wsug_html_chunked/ChWorkBuildDisplayFilterSection.html