近日,工作中有开发对抓包文件进行针对性过滤的小程序的需求,兜兜转转踩了很多坑后还是绕回了wireshark。
作为最出名的开源软件之一,wireshark也具有使用命令行进行操作的功能,这就是我们今天会总结到的“tshark.exe”。
通常,当你安装好wireshark,这个"tshark"就会和你的wireshark在同一路径下默默的躺着,就长这样:
这个程序和图形化的wireshark功能基本相同,接下来我会针对性地对使用该软件对已经完成抓包生成的抓包文件(.pacpng、.pacp)进行解析的功能命令进行总结。
先上一个例子:
D:\**你的路径**\tshark.exe -r "C:\**你的路径**\抓包数据.pcap" -Y esp -T fields -e esp.spi -e esp.sequence -e ip.src -e ip.dst
运行输出结果如下:
这个代码以tshark的绝对路径开头(配置环境变量会更方便),然后是抓包文件的路径指定文件,然后是各种过滤指令和字段选择,达到了针对某文件输出我们需要的字段的效果。
下面开始系统性介绍。
1、读取抓包文件
使用 -r
读取已有的抓包文件:
tshark -r <infile>
<infile>
是输入的抓包文件名。
2. 过滤数据
2.1 显示过滤器
使用 -Y
选项指定显示过滤器,过滤解码数据或写入文件的包:
tshark -r <infile> -Y <display filter>
<display filter>
是显示过滤器表达式,使用读/显示过滤器的语法,而不是捕获过滤器的语法。
2.2 读取过滤器
使用 -R
选项指定读取过滤器,在分析的第一遍中应用,不匹配的包将不考虑后续遍历:
tshark -r <infile> -R <read filter>
<read filter>
是读取过滤器表达式,同样使用读/显示过滤器的语法。
3. 输出格式
3.1 输出格式类型
使用 -T
选项设置输出格式:
tshark -r <infile> -T <format>
<format>
可以是以下之一:
-
ek
:用于批量导入 Elasticsearch 的换行符分隔 JSON 格式。 -
fields
:指定字段的值,格式由-E
选项控制。 -
json
:JSON 文件格式。 -
jsonraw
:仅包含原始十六进制编码包数据的 JSON 文件格式。 -
pdml
:XML 格式的包详情。 -
ps
:PostScript 格式。 -
psml
:XML 格式的包摘要。 -
tabs
:类似于默认文本报告,但使用制表符分隔。 -
text
:默认的人可读文本格式。
3.2 指定输出字段
使用 -e
选项添加要显示的字段,智能与 -T ek|fields|json|pdml
之一配合使用:
tshark -r <infile> -T fields -e <field1> -e <field2> ...
<field1>
, <field2>
等是要显示的字段。
3.3 设置字段打印选项
使用 -E
选项控制字段打印格式:
tshark -r <infile> -T fields -E <option>
<option>
可以是以下之一:
-
bom=y|n
:是否添加 UTF-8 字节顺序标记,默认为n
。 -
header=y|n
:是否打印字段名作为输出的第一行,默认为n
。 -
separator=/t|/s|<character>
:设置字段分隔符,默认为制表符。 -
occurrence=f|l|a
:选择字段的出现次数,默认为a
。 -
aggregator=,|/s|<character>
:设置字段聚合符,默认为逗号。 -
quote=d|s|n
:设置字段的引用字符,默认为无。 -
escape=y|n
:是否对字段值中的空白控制字符进行转义,默认为y
。
到这里我们就可以系统性地输出数据包中我们想要的值了!
这时候有小伙伴们要问了“博主博主,命令行我们明白了,但该怎么用到程序里呢?”
欸,我演示一个函数你就明白了,调用起来不要太轻松:
python"> def process_certificates(self, file_path, display_filter):command = [self.tshark_path,'-r', file_path,'-Y', f'tls.handshake.type==11&&{display_filter}','-T', 'fields','-e', 'ip.src','-e', 'ip.dst','-e', 'tls.handshake.certificate']lines = self.run_tshark_command(command)for line in lines:parts = line.split('\t')if len(parts) < 3:continuesrc_ip, dst_ip, certs_hex = partstry:certs = certs_hex.split(',')for cert_hex in certs:cert_der = bytes.fromhex(cert_hex)self.process_single_cert(cert_der, src_ip, dst_ip)except ValueError:continuedef run_tshark_command(self, command):try:result = subprocess.run(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True,text=True)return result.stdout.splitlines()
通过调用上面的函数,我们就完成了对命令的拼接,对输出的读取。
经过进一步简单处理,我们就达到了筛选所有TLS握手过程中传递的证书的效果,还顺带得到了他们的源IP目的IP等信息。
最后经过同理的简单开发,可得到这样的效果
——END——