Wireshark使用技巧及数据包分析方法

零、前言

Wireshark是一款图形界面的网络嗅探器,支持多种平台,是网络流量分析的利器。它的创始人是Gerald Combs,前身是Ethereal,作为开源项目经过众多开发者的完善它已经成为使用量最大的安全工具之一。最近刚把《Wireshark网络分析就是这么简单》看完,写的很有意思,把一些心得和技巧分享一下,部分内容也也源自个人总结。本文所使用的Wireshark2.4.0版,可以到官网下载:

https://www.wireshark.org

注:本文已首发合天

一、网络分析

0x00:只抓包头

在进行网络分析时往往只需要知道两个节点是不是能够联通,具体的传输信息并不重要,所以抓包的时候可以设置只抓包头,这样就大大减少了数据包的大小,有利于数据分析。

设置方法:Capture(捕获)–>Options(选项)–>SnaplenSnap长度)。

将这个值设置200以下就可以抓到所有网络层次的头信息了。

另外也可以直接点击任务栏里的快捷键,快速设置

0x01:只抓必要的包

我们可以设置抓包的filter,只抓一些感兴趣的包。

设置方法:Capture(捕获)–>Options(选项)–>Capture Filter(捕获过滤器)

在输入框里输入规则,然后点击开始即可,比如输入

dst host 220.181.111.188(捕获目标主机为220.181.111.188的数据包)

220.181.111.188ping www.baidu.comip地址,不同地理位置pingip可能不一样,然后浏览器访问百度就可以看到我们想要的捕获结果。

0x02:过滤

使用过滤规则进行数据包筛选是Wireshark最强大的功能之一,比如如果知道问题发生的具体协议就可以以协议名称过滤。使用协议过滤时要注意协议之间的依赖性,比如NFS共享挂载失败,问题可能发生在挂载所用的mount协议,也可能发生在mount之前的portmap协议。

然后就是IP+端口的方式,一个比较简单的方法就是可以在感兴趣的数据包上右键然后点击“追踪流”,就可以看到与这对ip和端口的全部通信。

也可以在相应的包上右键–>Apply as Filter(作为过滤器应用)–>Selected(选中),Wireshark就可以自动生成相应的过滤规则。这里给出一些常用的规则。

过滤IP

IP源地址:ip.src == 192.168.1.1

IP目的地址:ip.dst == 192.168.1.1

IP地址(包括源和目的):ip.addr == 192.168.1.1

过滤端口:

TCP端口:tcp.port==80

TCP目的端口:tcp.dstport == 80 

TCP源端口:tcp.srcport == 80

UDP端口:udp.port eq 15000

TCP 1-80之间的端口:tcp.port >= 1 and tcp.port <= 80

过滤协议:

httptcpudparpicmphttpsmtpftpdns 等。

过滤MAC地址:

MAC地址:eth.src==A0:00:00:04:C5:84

目的MAC地址:eth.dst==A0:00:00:04:C5:84

MAC地址(包括源和目的):eth.addr==A0:00:00:04:C5:84

过滤包长度:

整个UDP数据包:udp.length==20

TCP数据包中的IP数据包:tcp.len>=20

整个IP数据包:ip.len==20

整个数据包:frame.len==20

HTTP模式过滤:

请求方法为GEThttp.request.method==GET

请求方法为POSThttp.request.method==POST

指定URIhttp.request.uri==/img/logo-edu.gif

请求或相应中包含特定内容:http contains FLAG

0x03:自动分析

Wireshark有强大的统计分析功能,可以帮助分析人员快速统计出一些基本信息。比如点击Analyze(分析)–>Expert Info Composite(专家信息),就可以看到数据包的中的一些不同级别的信息统计,包含重传次数、链接建立次数、网络错误等,在分析网络性能时这个功能很有作用。

单击Statistics(统计)–>TCP Stream GraphTCP流图形),可以生成一些统计图表,比如下图表示171192的数据传输过程,水平线表示短暂的停止过程。

此外还可以统计分层信息、网络会话列表、网络端点列表、ip地址统计列表、应用层数据包信息等。

0x04:搜索

Ctrl+FWireshark也可以进行关键字搜索,选择“分组详情”后才可以搜索数据包中的内容,这样的搜索可以在CTF中也许会有意外收获。

一、CTF

下面每一种对应的操作都会给出一到几个CTF题目的例子,帮助大家快速上手。

0x00:搜索

题目文件:key.pcapng

题目描述:flag被盗,赶紧溯源!

题目题解:

首先可以只将这个数据包当做文本文件打开,比如用一些notepad++编辑器,然后直接搜索

正经的做法就是用Wireshark自带的搜索功能找尝试查找一些关键词(比如keyflagshellpass等),往往直接搜索就能有意外收获。

然后跟进可疑的数据包

根据数据包特征,很明显看出这是一个菜刀连接一句话木马的数据包,然后往下找,即可看到读取的flag

0x01:文件提取

题目文件:caidao.pcapng

题目描述:有人偷偷下载了文件!

题目题解:

根据题意可能数据包中存在文件传输,尝试直接导出,选择File(文件)–>Export Objexts(导出对象),然后可以看到一些协议,比如选中http就可以看到通过http传输的一些文件,在右下角有导出按钮,可生生成相应的文件。但是本题中无法用此方法直接看到被下载的文件,因为有些文件是直接通过tcpudp协议传输的,http协议只能看到的访问的链接,但不会看到传输的内容(比如你去访问放一个链接download.php?file=test.rar,通过上述导出对象的方式看不出来下载的文件的内容的),如下如所示。

这个时候就需要找到那个执行下载的数据包,找到数据传输的部分再导出,比如下面这个数据包

大概是一个菜刀下载的过程,在最后一个包可以看到下载的文件,直接右键点击“导出分组字节流”,然后保存为.tar.gz文件

本题中最后还要使用16进制编辑器去除开头和结尾的X@Y字符,这个是菜刀的特征符号,不是文件内容。

再或者一个简单的方法,右键“显示分组字节流”,去除前后各三个字节在解压缩

再复杂一点就是多个包的数据提取了,一个较大的文件其传输过程可能要经过多个数据包,比如下面这道题目。

题目文件:misc_fly.pcapng

题目描述:抓到一只苍蝇!

题目题解:

首先用HTTP条件过滤一下

右键第一个包,追踪流

可以看到一些基本信息,首先这是一个POST数据包,发送了一些文件相关信息,包括名称(fly.rar)和大小(525701)等。接下来应该就是文件实际上传的数据包,将过滤条件改为

http.request.method==”POST”

从数据包的结构上看应该就是第二至第六个数据包是数据传输的过程。点开第二个可以看到Media Type的长度为131436

第二到第五个都是一样的长度,第六个为1777,应该是剩余的最后一部分数据。但是131436*4+1777=527521=525701,再看下第一个数据包

都知道rar文件头应该是Rar,但是选中的数据部分前面却多出了很多,简单计算一下一共多出了364,且364*5+525701=527521。所以多出的也许是某种校验数据,在导出的时候将其忽略。

每个包都做同样的操作即可得出5个文件,再将这个文件按顺序拼接即可。拼接的话可以使用16进制编辑器手动拼接,也可以使用linuxcat命令,比如“cat 1 2 3 4 5 > fly.rar”。这道题还设置了伪加密,需要修改加密位,将0x84位置改为0x80即可。

解压出来后是一个exe可执行文件,里面隐藏了一个png图片,是个二维码,扫描即可得到flag

Flagflag{m1Sc_oxO2_Fly}

0x02:信息提取

题目文件:sqlmap.pcap

题目描述:

题目题解:

数据包记录的是sqlmap获取flag的过程,使用http && http contains “flag”过滤一下

可以看出这是一个布尔盲注的过程,一位一位的读取flag,然后用二分法不断判断其ascii码的范围并最终确定这一位的值。第806个包是读取flag第一位的数据包

将其payload解码一下是这样的,判断其ascii码是否大于64

id=1 AND ORD(MID((SELECT IFNULL(CAST(value AS CHAR),0x20) FROM isg.flags ORDER BY value LIMIT 0,1),1,1))>64

然后一直到836个包判断第一位ascii码值大于72,然后开始从高到低递减,判断其ascii码不大于73,则第一位的ascii码值是73,对应的字符为I。以此类推,其flagISG{BLind_SQl_InJEcTi0N_DeTEcTEd}。本题需要一定的耐心和SQL注入基础。但是这么做可能有些繁琐,其实pcap数据包可以直接用文本编辑器打开,就可以看到其中的http请求

所以可以使用字符串搜索的方式直接去查找其中的语句,然后判断flag,首先将原数据包中的http请求导出来,另存为sqli.pcap

导出后的文件为:sqli.pcap

再使用如下的Python脚本一键读取即可

ISG{BLind_SQl_InJEcTi0N_DeTEcTEd}

一、Tshark

Tshark是命令行版的Wireshark,相对于Wireshark它有更好地灵活性,结合脚本程序可以发挥巨大的威力,在安装Wireshark的时候就默认安装了Tshark

如下是运行-h参数,具体的参数解释可以参考官方文档

https://www.wireshark.org/docs/man-pages/tshark.html

比如kali下的一个简单的使用示例(windows不知为何无法获取网卡)

-s 512:只抓取前512个字节

-i eth0:监听eth0网卡

Tshark-z参数可以进行各种信息的统计,比如下面这条命令,统计每一秒钟里由ip为的192.168.228.128主机发出的http请求的次数

tshark -z io,stat,1.00,http&&ip.src==192.168.228.128

程序在监听的时候会不断输出拦截的数据信息

最后终止的时候则会给出一个报表

Python本身也可以解析数据包,它可以向Wireshark一样将pcap数据包分层解析,然后进行数据处理,这里需要安装scapy模块,如果安装不成功可以在kali2.0里尝试运行。网络模型大家应该有所了解,按不同的标准有七层和五层的分法,Wireshark就是按不同层次解析数据。同理scapy也是如此,

scapy主要是分为EthernetIPTCPRaw这四层,每一层都有每一层的关键字,可以利用键值对的方式直接读取相应的内容。其实Python适合处理大量数据包的情况,比如需要从100个数据包中查找某个特征,使用Wireshark一个一个打开就不现实,可以写脚本批量处理。这里给出一个示例代码,其作用是将/root/pcap文件夹里的数据包全部读取一遍,查找其中存在长度为32的字符串的数据包,并将其写入到另一个文件夹中。(Pythonpcapng格式的数据包处理存在一定的问题,建议将其转换成pcap格式)

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from scapy.all import *
import os
import re
import shutil
import time
 
rootpath = "/root/pcap/"
 
def openfiles(path):
    filelist = []
    files = os.listdir(path)
    for f in files:
        filelist .append(f)
    return filelist
 
def writefile(filename,stringlist):
    f = open("/root/result/"+filename+".txt","w")
    for i in stringlist:
        f.write(i+"\n")
    f.close()
    shutil.copy(rootpath+filename,"/root/result/"+filename)
 
 
def search(filename):
    filepath = rootpath+filename
    stringlist = []
    pcaps = rdpcap(filepath)
    for p in pcaps:
        for f in p.payload.payload.fields_desc:
            fvalue = p.payload.getfieldval(f.name)
            reprval = f.i2repr(p.payload,fvalue) #转换成十进制字符串
            if str(f.name)=="src" and reprval=="10.250.109.12": #指定特定的ip地址
                for f2 in p.payload.payload.payload.payload.fields_desc: #payload向下解析一层
                    #print f2.name
                    if f2.name=="load"or f2.name=="data":
                        fvalue = p.payload.getfieldval(f2.name)
                        reprval = f2.i2repr(p.payload,fvalue)
                        refind = re.compile(r'[A-Fa-f0-9]{32}') #根据自己的需求设置正则
                        temp = refind.findall(reprval)
                        stringlist.extend(temp)
    if len(stringlist)>0:
        writefile(filename,stringlist) #将解析结果和对应的pcap包保存下来
 
if __name__=="__main__":
    filelist = openfiles(rootpath)
    for file in filelist:
        print file
        search(file)
 
    print "DONE!"

 

测试数据包如下,是我们上文提到的几个数据包及两个测试数据包

然后执行代码运行

result文件夹里可以看到20160813-084957.pcap中存在符合条件的字符串,并且生成了对应的txt文件。同理,我们可以改变查找的规则,在大量数据包中查找我们想要的信息。


发表评论

电子邮件地址不会被公开。 必填项已用*标注

*