前言
年底工作太忙了,去它的降本增效……终于抽出那么点时间更新博客了。好不容易有一点时间休息,竟然第一时间想到的是更新博客……今天准备把Wireshark过滤器内容写了,这个内容算是Wireshark工具使用的最核心内容之一。构思了好长时间,其实官网文档写得相当详细,但又总觉得差了些什么,所以还是自己写吧(目标就是让大家看完这篇文章,能真正掌握Wireshark过滤技术)。这部分内容可能相对枯燥,但这是你迈向数据包分析精英的必经之路。所以我构思的文章内容包括了4个章节:过滤器介绍(概念、原理、分类)+ 过滤语句编写(基础语法)+ 过滤器使用举例(实践)+ 高级过滤技巧(提升)。几个章节加在一起,即让大家熟悉工具的使用,又能够解决实际工作中的问题。不废话了,万字长文献上:
一、了解Wireshark过滤器概念、原理及分类
首先来看看Wireshark是如何捕获到数据包的:

如上图:
(1)如果是在网络拓扑中间的网元设备上抓包,为了不影响生产环境,我们一般是在交换机上做端口镜像,复制一份流量到分析主机的网卡;
如果是在网络终端设备上抓包(终端设备直接安装Wireshark),则无需做镜像,直接选择网卡进行抓包即可(网卡需设置为混杂模式)。
(2)还记得我们第二篇介绍Wireshark安装的文章吗?在安装时,有个步骤是提示你需要安装npcap(winpcap),Linux系统是安装libpcap。这是一个抓包工具(或者说是抓包驱动、数据包分析库)。可以认为它才是真正负责抓包的工具,然后再把包给到Wireshark来进行分析。
(3)考虑一个场景:如果网络流量特别大,对于分析主机来说(一般是千兆或百兆网卡)极大可能是吃不消的。这时不要说用Wireshark分析了,要把包接下来都困难。这时,我们就只能选择性放弃一些我们不关注的数据包,只抓需要的数据包,来减小流量过大给分析主机带来的负担。这时,我们就要对流量进行“过滤”处理,如上图中标注的漏斗:“捕获过滤”,它将流量进行初步筛选。
这就引出了我们这篇文章的主角——过滤器!
Wireshark的过滤器分为了两种:捕获过滤器 和 显示过滤器
上面我做引入时提到的是捕获过滤器。那显示过滤器又是什么呢?虽然我们已经对流量进行了初步筛选,但实际大家在抓包时会发现,1秒钟时间还是可能会抓到成千上万个数据包!如果抓包时间长,数据包的量级可能是百万、千万甚至上亿的……那我们在分析时,要找到指定的某个数据包无疑就像是大海捞针。这时“显示过滤器”就显得格外重要了,它能将我们想分析的数据包在Wireshark中显示出来,把不想分析的数据包暂时进行隐藏!
因此,我们在使用Wireshark分析时,更多使用的是显示过滤器。
特别需要说明的是:Wireshark的捕获过滤器和显示过滤器使用的是2套不同的语法……
究其原因,就是前面提到的:捕获过滤器只是在流量大的场景下才会去使用,因此Wireshark认为捕获过滤直接用BPF(Berkley Packet Filter)进行过滤就行了。BPF的语法相对简单直接,但不能满足复杂的过滤场景。(BPF诞生于1992年,你说它能多先进,甚至都算拖拉机了……但现在eBPF倒是在云计算领域火得一塌糊涂(不在本文讲解范围,感兴趣可以自行问度娘))。
显示过滤器语法就不一样了,分析师需要根据各种不同的分析场景对已捕获的数据包进行筛选,这就对过滤器提出了高要求,因此Wireshark在BPF的基础上自主开发了一套更加复杂、灵活的过滤语法,来应对各种苛刻的过滤场景。(那直接捕获过滤也用显示过滤的语法呗?是啊,老外就是倔强,你说搞两套语法,费这事干嘛……)
这里就不得不提一下国产的科来。科来推崇的是“全流量”,简单说就是所有历史流量都捕获下来(所以平时在行里用科来的产品基本没涉及捕获过滤)。科来的过滤器有三种:分析(就是捕获,叫法不同)、显示和存储过滤器,都是用的同一套语法。和Wireshark显示过滤器语法很像,但又有不同(就像思科和华为路由器的配置语句……)。写完这篇文章,我转载科来的过滤器系列文章(他们竟然写了一个系列……当然他们是拿工资,我写Wireshark是用爱发电……),大家感兴趣的话可以深入了解一下。给我的总体感觉是科来过滤器功能不如Wireshark强大(比如Wireshark可以过滤有多层IP嵌套这种场景),但是,科来有些过滤条件设置更简单,还可以针对端点、会话和日志等进行过滤,Wireshark就只能过滤单数据包。国产软件能和Wireshark掰手腕,也算是有实力,侧面也看到新世纪以来东大真的是越来越强了。
好了,不扯远了。相信大家已经清楚了什么是过滤器,也知道了过滤器分类,下面正式进入过滤器使用介绍。
二、过滤语句编写
还是用官方介绍开头:英语还行的,我建议大家完整阅读一下官方用户手册,毕竟官方最权威,翻译后传来传去,难免会出错。我写这篇文章,用的是Ver4.5.0版本,官方用户手册第4.10节介绍捕获过滤器,而6.3节开始时介绍显示过滤器:

我尽量把官网文档的精华提取出来讲。先来看分析过滤器,再来学显示过滤器:
(一)捕获过滤器
捕获过滤器的位置:

在Wireshark打开时,选择网卡的上方,可以输入捕获过滤条件,点绿色的图标,Wireshark提供了一些常用的捕获过滤条件供用户直接使用:

如果要自己输入,则必须按照Wireshark指定的语法来构造过滤的规则语句。捕获过滤器语法规则如下图所示:

如上图:我们通过“协议”+“方向”+“主机信息”就组成一条“原子语句”,多个“原子语句”通过“逻辑运算符(与、或、非运算)”连接在一起,就能形成一条复杂的过滤语句。
对上面图片中的过滤语句作进一步解释:
1.Protocol(协议):
常用协议包括: ether、fddi、ip、arp、rarp、decnet、lat、sca、moprc、mopdl、tcp、udp
如果没有特别指明是什么协议,则默认使用所有支持的协议。
2.Direction(方向):
常用到的包括: src(源source的缩写)、dst(目的destination的缩写)、src and dst(源和目的)、src or dst(源或目的)
如果没有特别指明来源或目的地,则默认使用 “src or dst” 作为关键字。
例如:
"host 10.2.2.2" 与 "src or dst host 10.2.2.2" 相同
3.Host(s)(主机地址):
常用主机信息包括: net、 port、host、portrange
如果没有指定此值,则默认使用”host”关键字。
例如:
"src 10.1.1.1" 与 "src host 10.1.1.1" 相同
4.Logical Operations(逻辑运算):
常用的逻辑运算符包括:not、and、or
否(“not”)具有最高的优先级。或(“or”)和与(“and”)具有相同的优先级,运算时从左至右进行。
例如:
"not tcp port 3128 and tcp port 23" 与 "(not tcp port 3128) and tcp port 23" 相同
"not tcp port 3128 and tcp port 23" 与 "not (tcp port 3128 and tcp port 23)" 不同
上面讲规则语句部分,已经举了例子,我就不再单独举例了。
捕获过滤的应用场景不多,不用过于浪费时间。顺带说一下:Wireshark不是企业级的产品,一般是临时分析故障等才使用,不要想着用一台服务器直接安装Wireshark,部署到园区网或数据中心的固定位置去进行监控,这是一种得不偿失的选择。如果真有需要长期监控,请考虑企业级的流量分析解决方案。
(二)显示过滤器
官网找到Wireshark的在线用户手册,第6.3节开始时介绍过滤器的部分:

如果你英语足够好,说真的,官方文档就是最好的、最权威的教程了。写得真的通俗易懂,简单明了。好吧,我还是把精华提取出来讲解一下:

如上图,分析主界面的最上方就是显示过滤器了。同捕获过滤器一样,点击前面蓝色的图标,可以选择Wireshark集成好的一些显示过滤语句,如下:

如果要自己写,就需要遵守Wireshark的显示过滤语法规则:

如上图所示,一般是先指明协议(protocol),然后用“.”(点号,英文输入法的句号)分隔,后面是协议的某个字段(string1.string2),再对前面的字段进行赋值,这样就形成了一条“原子语句”。最后通过逻辑运算符“与或非”把多条原子语句连接在一起,就形成一条复杂的显示过滤规则语句(还是挺简单,熟能生巧,多用就行)。
对上面图片中的过滤语句作进一步解释:
1.Protocol(协议)
您可以使用大量位于OSI模型第2至7层的协议。(wireshark支持的协议介绍 https://www.wireshark.org/docs/dfref/)
常用值: IP、TCP、DNS、SSH
2.String1, String2 (可选项)
协议的子类。
可以在菜单栏“分析”->“显示过滤器表达式”中点击相关父类旁的”+”号,然后选择其子类(后面有截图演示)
对协议和协议子类,官方文档是这样说的:

可以从“视图”->“内部”->“支持的协议”中找到,如下图:

顺带说明一下:
wireshark Ver4.5.0的解码器能支持解码3055种协议及241135个字段。
在wireshark早期版本中,在安装文件夹下可以看到wireshark支持解码哪些协议,并且能够知道它的解码逻辑,但大版本3.X后就只能从这个会话框中查看了,当然,wireshark源码中应该还可以看到。
有一些wireshark默认不支持的协议(如某种私有协议),我们可以在wireshark社区中去搜索有没有相关的解码插件,比如portal认证协议,到我写这篇文章时wireshark还不支持解码第2、3版的portal协议,但网上有portal协议的解码插件,通过安装插件可以使wireshark支持portal的解码(貌似不准确)。
国内流量分析最强的科来,现在也只能解一千多种协议,比wireshark还是有明显差距,更不要说其他厂商出的软件了,它们就只支持HTTP、邮件、FTP等几十种常见协议。
所以显示过滤器可以这样写:
ip.addr == 192.168.0.1
ip.len le 1500
“==” 和 “le” 是比较运算符,如下:
3.Comparison operators (比较运算符)
可以使用6种比较运算符

4.Logical expressions(逻辑运算符)

上面就把基本的语句构成讲完了。
但光是文字描述还是有点抽象,下面用上图“ftp.passive.ip=10.2.3.4”进行具体操作说明:
输入协议名字时,Wireshark提供了输入联想功能,如下:

不用去默写协议名的单词,只要知道协议首字母就行,可用鼠标或上下键选择(不支持linux用tab键进行不全)。写完协议,键入“.”号,会自动联想出该协议所有的字段名,如下:

选出过滤条件“ftp.passive.ip”,然后选择比较运算符“==”,进行赋值:
ftp.passive.ip=10.2.3.4
这样,规则语句就写完了。

注意显示过滤器的背景颜色:当输入的过滤条件错误(或不完整)时,背景色为红色;当输入的过滤条件正确时,背景色变味绿色!
还是比较简单,对吧?
还有没有更简单的过滤条件生成办法呢?毕竟语法需要强制记忆。
答案当然是肯定的!
在Wireshark的数据包分析视图中,选中某个数据包的某一个指标,点击鼠标右键,右键菜单中有“作为过滤器应用”(用这个作为过滤条件,直接显示过滤结果)和“准备作为过滤器”(把相应过滤语句输入到现实过滤器中,但暂时不执行,方便我们改变条件的赋值)。这样是不是很简单?如下图:

同样,还可以在数据包的字段解码视图中,选中具体的一个字段点右键:

可以直接生成针对某个字段的过滤语句。
如果好不容易写出一条复杂的过滤语句,下次再分析时,可以直接调取出来用吗?答案当然也是肯定的,如下:

点击显示过滤器右侧的加号,对过滤条件进行命名。下一次就可以直接选择调用了,如下:

还有很多的过滤语句细节,我把它放在了第四部分(高级过滤技巧)中进行讲解。
三、过滤器使用举例
捕获过滤器就略过了,以下举例全是针对显示过滤。
Ver4.5.0的官方文档第6.4节写得非常详细了,我当个快乐的翻译官就行了:)
这里,只列出经常使用的和基础的部分。一些不常见或不好理解的,我把它放在本文的第四部分“高级过滤技巧”,对于刚入门的看第三部分就够了,对于要精通使用过滤器的再看第四部分,更方便大家从“入门”到“精通”!
常用显示过滤如下:

注:上面的地址信息来自网络,如果有问题请联系删除。
下面精炼官方文档内容:
(1)mac地址的过滤表达式写法:
用“:”,“-”,“.”做分隔符号都行:

(2)IPv4过滤表达式写法:

支持无类域间路由CIDR,直接过滤网段。
(3)IPv6过滤表达式写法:

和IPv4类似,不累述了。
(4)过滤字符串

字符串需要用双引号扩起来,可以使用lower()取小写字母这种函数匹配ASCii码的文本。可以用转义字符\x和\d表示16进制和十进制(匹配数据包原始数据)。
可以用“contains”做精确的字符串匹配;
可以用“matches”做字符串模糊匹配,并且matches支持用正则输入过滤条件;
(5)时间过滤

时间格式如上图例所示,照着写就行了。
四、高级过滤技巧
(1)切片操作符

用[ ]进行切片操作,第一个数字代表从这个字段开始位置的偏移值(可以取负数,代表从末尾开始倒着数偏移值),第二个数字代表要取的字节数。
以mac地址00:00:83:00:20:20进行切片举例:
eth.src[1-2] == 00:83(偏移1个字节开始,取2字节)
eth.src[:4] == 00:00:83:00(从开始位置计算,取4字节)
eth.src[4:] == 20:20(偏移4字节开始,到结束的所有字节)
eth.src[2] == 83(便宜2字节,取1个字节的内容)
也可以用负号,表示从末尾开始计算偏移,如下:
frame[-4:4] == 0.1.2.3
frame[-4:] == 0.1.2.3
**注意:**字符串字段的切片产生字符串,并在字符串转换为UTF-8(而不是字节)后在码点边界上进行索引。字节片可以直接与字符串进行比较;这将字符串转换为相应的UTF-8字节序列。要比较字符串切片和字节序列,请使用@操作符。
这句话是不是看不懂?简单说就是,切片是针对字节的,如果后面的赋值不是字节,就可能达不到你想要的效果。比如字符串切片,要使用@符号,切的字符串是转换成UTF-8字节序列再进行的切片。
(@符号就不单独举例了,因为用得少,还容易混淆,有兴趣的自己看用户手册6.4.6节)。
(2)“层”操作符

简单说,就是如果一个数据包(比如VPN),有2层2IP包头,在过滤IP地址的时候默认以第一层为准,那我们需要过滤内层的IP地址信息呢?答案就是添加“层”操作符,如下:
ip.addr#2 == 192.168.30.40
(3)成员操作符

成员很好理解,比如我要过滤端口80、443和8080,如果按之前的讲解,过滤表达式应该写为:
tcp.port == 80 || tcp.port == 443 || tcp.port == 8080
用成员操作符,可以这样写:
tcp.port in {80, 443, 8080}
用"in"表示后面是个范围,用"{ }"把所有可选成员扩起来,每个成员用逗号进行分隔。
tcp.port in {443,4430..4434}
表示端口443和4430-4434。
要特别注意:这个语句和下面语句不等价、
tcp.port == 443 || (tcp.port >= 4430 && tcp.port <= 4434)
这是因为port是个多值条件(每个数据包有源端口srcport还有dstport,因为会产生歧义),例如:
一个数据包,它的源端口为56789,目的端口是80,它也会满足tcp.port >= 4430(源端口满足这个条件) && tcp.port <= 4434((目的口满足这个条件) ),因此上面的过滤语句会产生歧义而导致不满足我们的过滤设想。
延伸:有歧义的字段(多值字段),在编写过滤条件时要特别注意。尽量精确的把多值变为单值(比如port,精确为dstport或srcport)。类似的是“!=”的使用,参考上面文章。
更多例子:
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}
(4)运算符号

没啥多说的,就是注意使用“-”减号时,必须在被减数和减号中间有个空格,否则会报错。
举例:
过虑出只有帧头、IP包头和TCP包头的数据包(就是过滤出不带数据的包)
frame.cap_len < { 14 + ip.hdr_len + tcp.hdr_len }
(5)函数

举例:
找出http.server字段为“apache”的数据包:
lower(http.server) contains "apache";
过滤出http请求中uri长度大于100的请求包:
len(http.request.uri) > 100;
将含有超过2个IP的数据包过滤出来:
count(ip.addr) > 2;
把帧号匹配13579的过滤出来:
string(frame.number) matches "[13579]$"
把目的IP在172.16.X.X-172.31.X.X范围中,且以255结尾的IP包过滤出来:
string(ip.dst) matches r"^172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.255"
将tcp的源端口及目的端口都不大于1024的包过滤出来:
max(tcp.srcport, tcp.dstport) <= 1024
(6)字段引用

可以在表达式中直接引用一个字段的值。
例:
过滤出过去5分钟的所有数据帧:
frame.time_relative >= ${frame.time_relative} - 300
访问目的ip为dns中A记录地址的http数据包:
http && ip.dst eq ${dns.a}
注意:可以将过滤表达式配置为“显示过滤器宏”(分析->显示过滤器宏)来进行引用。什么是“显示过滤器宏”,简单说就是预先配置好的显示过滤器,为它取个名字,以后直接通过名字来引用就行。如下:

做好的复杂过滤器,可以直接保存,方便以后调用(参考本文上面的第二章节)
(7)字段名改变

有的协议名或字段名进行了更新,以新的名字还是旧的名字为标准,要以wireshark版本更新为标准。
例如:DHCP以前是BOOTP,在Ver1.8之前要用bootp来进行过滤,后面才支持用dhcp进行过滤,再后来就不支持用bootp进行过滤了。
(8)协议名不明确的

举例:如果协议名和字段取值都为"fc",则它会优先按协议名进行识别过滤。如果想把字段中“fc”过虑出来,请用分片的方式过滤,如:
frame[10:] contains .fc or frame[10] == :fc
总结
不知道大家看得过不过瘾,自认为本文是现在你能找到的Wireshark过滤器教程中最好的了。当然还是没能面面俱到,比如还有在显示过滤后,再定位指定的某个数据包(后面讲数据包定位着色再讲吧)。临近年底,大家都在冲绩效,行内工作也是忙得不行,下次更新不知道是什么时候了,大家且看且珍惜!如果觉得本文对你有用,不要忘了收藏点赞!!


2321

被折叠的 条评论
为什么被折叠?



