第4章 Wireshark高级过滤表达式归纳总结

说实话,过滤表达式才是Wireshark的核心战斗力。你想想看,抓包谁都会,但要从成千上万个报文里精准定位问题,靠的就是过滤表达式。我刚开始用Wireshark那会儿,觉得界面花哨就行,后来才发现——嗯,过滤表达式玩得转,才算真正入门。

4.1 显示过滤器 vs 捕获过滤器

这两个东西,说白了就是「抓的时候过滤」和「抓完之后过滤」的区别。很多人一开始搞混它们的位置:捕获过滤器写在抓包界面顶部的输入框里,显示过滤器写在报文列表上方的输入框里。

对比维度捕获过滤器显示过滤器
语法基础BPF (Berkeley Packet Filter)Wireshark Display Filter
作用时机抓包时,丢弃不匹配的包抓包后,隐藏不匹配的包
性能开销低(内核级过滤)高(用户级过滤)
是否可逆不可逆,丢弃的包无法恢复可逆,只是隐藏
支持函数不支持支持
示例host 10.0.0.1 and port 80ip.addr == 10.0.0.1 and tcp.port == 80

我个人习惯是:抓包时用捕获过滤器,只抓我关心的流量,减少文件体积;分析时用显示过滤器,反复调整条件深挖细节。我记得有一次抓生产环境的问题,没用捕获过滤器,结果抓了1GB的包,光打开就卡了半天——从那以后我就学乖了。

4.2 逻辑运算符与比较表达式

过滤表达式离不开逻辑组合。Wireshark支持三种基本逻辑,也可以用符号表达:

  • and (&&):同时满足两个条件
  • or (||):满足其中一个条件
  • not (!):取反,排除某些条件
  • 括号 ():改变优先级,让表达式更清晰

比较运算符速查

== 等于 · != 不等于 · > 大于 · < 小于 · >= 大于等于 · <= 小于等于 · contains 包含 · matches 正则匹配

举个实际例子:(tcp.port == 80 or tcp.port == 443) and ip.src == 192.168.1.1。我个人习惯用括号把条件分组,可读性会好很多。你想想看,一长串表达式如果不加括号,优先级搞混了,结果就完全不对了。

4.3 协议专用过滤表达式

每个协议都有自己的专用过滤字段。我整理了几个最常用的:

协议过滤表达式说明
HTTPhttp.host == "example.com"按主机名过滤HTTP请求
HTTPhttp.request.uri contains "/api"过滤API接口请求
TCPtcp.port == 443过滤HTTPS流量
TCPtcp.flags.syn == 1只看SYN包(三次握手第一步)
IPip.addr == 10.0.0.1过滤某个IP的所有流量
DNSdns.qry.name contains "google"过滤包含特定域名的DNS查询

之前排查一个OAuth登录问题,我就是用 http.host == "login.example.com" and http.request.method == "POST" 精准定位到认证请求的。如果没有协议专用字段,想在几千个包里找到那个请求,真的很痛苦。

4.4 过滤函数与计算操作

Wireshark提供了一些内置函数,用来对字段做变换或统计:

  • upper(field) / lower(field):大小写转换,解决大小写敏感问题
  • len(field):取字段长度,比如过滤超长URL
  • count(field):统计字段出现次数
  • string(field):将字段转为字符串

比如你要过滤URL路径超过100个字符的请求:len(http.request.uri) > 100。我记得有一次分析恶意软件的网络行为,就是用 len(http.host) > 50 找到那些随机生成的长域名请求——正常网站哪有那么长的域名,对吧?

4.5 实战过滤组合案例

光讲语法太枯燥,直接上实战场景。这些组合表达式,我建议你自己动手敲一遍——嗯,光看是记不住的。

  1. 查找某个IP所有的HTTP 500错误
    http.response.code >= 500 and ip.addr == 10.0.0.1
  2. 分析TCP三次握手失败
    tcp.flags.syn == 1 and tcp.flags.ack == 0 and not tcp.flags.syn == 0
  3. 过滤非HTTPS的明文HTTP请求
    http and not tcp.port == 443
  4. 查找DNS查询中返回NXDOMAIN的域名
    dns.flags.rcode == 3(3表示域名不存在)
  5. 定位某个时间段内的TCP重传
    tcp.analysis.retransmission and ip.addr == 192.168.1.100

小技巧: 在Wireshark里输入过滤表达式时,按下 Tab 键可以自动补全字段名。这个功能很多人不知道,但真的很省时间。

Wireshark高级过滤表达式 知识体系 高级过滤表达式 显示过滤器 语法: field == value 支持 contains / matches 可逆隐藏 分析时反复调整 捕获过滤器 语法: BPF host / port 等 内核级过滤 不可逆丢弃 逻辑运算符 and / or / not && || ! 括号分组 改变优先级 协议过滤 HTTP / TCP / IP DNS 专用字段 精准匹配 协议特征定位 函数计算 upper / len count / string 变换与统计 复杂条件计算 核心:精准定位问题 · 高效分析流量

4.6 常见陷阱与避坑指南

过滤表达式看起来简单,实际用起来坑不少。我总结几个最常见的:

  • ip.addr 的陷阱:很多人以为 ip.addr == 10.0.0.1 只过滤源IP或目的IP,实际上它同时匹配两者。如果你只想过滤源IP,用 ip.src == 10.0.0.1;只想过滤目的IP,用 ip.dst == 10.0.0.1。我在项目中被这个坑过一次,查了半天才发现过滤结果里多了一堆不相关的包。
  • tcp.port 同理:tcp.port == 80 同时匹配源端口和目的端口。严格区分的话,用 tcp.srcport 和 tcp.dstport。
  • 大小写敏感:字段名是大小写敏感的。http.host 是对的,HTTP.HOST 就不行。不过字段值是否敏感取决于协议本身。
  • 引号的使用:字符串值要用双引号引起来,比如 http.host == "www.example.com"。数字和布尔值不用引号。

避坑提醒: 我曾经因为大小写问题折腾了半小时——写了个