0%

Wireshark 使用说明

理解网络层次

OSI 五层协议

  • 物理层:一般是基于电信号进行 bit 流传输

  • 数据链路层: 定义 bit 信号分组方式,常见的协议是 以太网协议 (Ethernet)

    Ethernet 数据帧 [帧头,数据,帧尾]

  • 网络层: 划分广播域 / 子网, 一般网络层都是 IP 协议

    IP 数据帧 [报头,数据]

  • 传输层: 建立端口到端口的通信, 常见传输层协议有 TCP/UDP

    TCP 基于连接,提供可靠传输,面向字节流,三次握手 / 四次挥手 (创建 / 断开连接), 粘包 / 拆包,timewait, 报文头长,总体传输慢,窗口, 拥塞控制

    UDP 无连接,尽可能快,不可靠传输,面向报文,过长报文会被分片

  • 应用层

使用 Wireshark 分析数据包时,一般关注的是后面三层, 每层的报文头中都包含了特定信息,在数据层存放更上层的数据

实际报文分析

我们看一个实际的 TCP 报文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
###[ Ethernet ]###
dst = e0:73:e7:6f:b0:1b
src = 00:20:22:01:05:b6
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 132
id = 48263
flags = DF
frag = 0
ttl = 128
proto = tcp
chksum = 0xa741
src = 192.168.10.225
dst = 192.168.10.121
\options \
###[ TCP ]###
sport = 8555
dport = 50283
seq = 739877280
ack = 3545067859
dataofs = 5
reserved = 0
flags = PA
window = 40942
chksum = 0xd82f
urgptr = 0
options = []
###[ Raw ]###
load = '\\xc9\x00\x00\x00\\xf9\x00\x00\x00\\xbc\x14\\xa8e\x02\x00\x00\x00H\x00\x00\x00\\x80\\xd85\\\x01\x00\x00\x00\\x80\\xd85\\\x01\x00\x00\x00\\x80\\x96\\x98\x00\\xef\x03\x00\x00\x00\x00\x00\x00\x00\\xa0Z@33333\\xf3b@\\xbc\x14\\xa8e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  • 以太网层 (Ethernet) 中最重要的信息

    • 源 MAC 地址
    • 目的 MAC 地址
    • 上层协议类型
  • 网络层 (IP)

    • 源 IP 地址
    • 目的 IP 地址
    • 版本,长度,标志位,上层协议类型 等
  • 传输层 (TCP)

    • 源端口
    • 目的端口
    • 长度,标志位,序列号 / 应答号 等
  • 用户数据 (示例中的传输层数据不是像 HTTP 一样普通的传输层协议报文, 可能是自定义的协议报文)

选择正确的网口

使用 Wireshark 抓包,首先需要选择正确的网络接口, 如果目的数据包的源 IP 或者目的 IP 在某个网络接口上,就选择该网络接口

一般来说,名称中包含 "以太网" 的接口是通过网线连接的网口; 包含 "WLAN" 的是无线网络的网口

Windows 上可以使用 ipconfig /all​ 来查看网口信息, 确定要使用的网口

或者鼠标指向对应的网口,在 Tooltip 中查看网口配置的 IP 信息

网络包过滤

开始捕获后一般会发现一个网口上的报文数量非常庞大, 不过滤根本看不清楚

此时我们就需要用到上述网络层次相关知识

  • 网络层过滤 (IP 协议信息过滤)

    IP 协议包含了源 IP 地址和目的 IP 地址, 这也是我们在 IP 层上一般需要过滤的内容

    1
    2
    3
    4
    5
    6
    7
    ip // 协议过滤, 非ip协议的报文过滤掉
    ip.src == 192.168.10.121 // 源地址过滤
    ip.dst == 192.168.10.225 // 目标地址过滤
    ip.addr == 192.168.10.66 // 源或者目的地址过滤
    ip.dst [not] in {192.168.10.121, 192.168.10.225} // (不)在某几个值中
    ip.version == 4 // ip协议过滤
    ip.len > 100 // 如果需要, ip协议的其它信息也可以用于过滤
  • 传输层过滤 (TCP/UDP 协议信息过滤)

    1
    2
    3
    4
    5
    6
    7
    tcp // 协议过滤, 非tcp协议报文过滤掉
    tcp or udp // 协议过滤, 仅保留tcp或者udp报文
    tcp.srcport == 8788 // tcp源端口过滤
    udp.dstport != 8888 // udp目的端口过滤
    udp.dstport not in {8888, 8889}
    udp.dstport >= 2000 and udp.dstport <= 9000
    udp.port == 12345 // 源或者目的端口过滤
  • 应用层 / 用户数据过滤 (可以根据数据帧的特性, 快速过滤出特定协议的数据包)

    数据内容过滤时,中括号第一个数字是字节起始位置, 第二个数字是字节长度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    data.data[4:2] == 0300 // tcp/udp负载数据部分第字节开始的两字节为0300的包
    tcp.segment_data[0:2] == 4d15
    tcp.payload[0:2] == 6f72 // tcp负载数据过滤
    udp.payload[0:4] == 6f726179 // udp负载数据过滤
    data.len > 0 // 负载数据长度过滤
    data.data[0:1] == 6f // tcp/udp负载数据过滤
    data.data == 6f:72:61:79 // 整端数据匹配, 十六进制数据可以按照字节用:分开
    http.request.method == GET
    dns.qry.name == "www.baidu.com"

    http.request.uri contains "User" // contains 区分大小写
    http.host contains "baidu"
    http.request.uri matches "user" // matches 不区分大小写

条件组合

以上的过滤条件都可以自由组合,使用 andornot​来连接多个判断条件

1
2
tcp.dstport in {12345, 12315} and http and ip.version == 6
ip.addr == 192.168.31.2 and (udp.port == 12345 or tcp.port == 12345)

捕获数据导出

  • 直接保存 (Save), 将保存指定时间内所有捕获的数据包, 数据量一般非常大
  • 导出特定分组 (Export Specified Packets), 可以选择只保存选中的包, 或者已过滤的包 (Displayed), Range 参数可以选择保存第 xxx 包 - 第 yyy 包
  • 导出分组解析结果 (Export Packet Dissections), 选择纯文本 (As Plain Text), 可以过滤导出哪些包,同时可以在 Packet Format 中仅勾选 Packet Bytes, 导出指定包的 hexdump

一般来说为了便于分析,先初步过滤一下,比如 ip 过滤, 然后将原始数据保存 (导出特定分组), 存储为.pcapng

之后再使用 scapy 来进一步分析,重播, 使用 scapy 重播可以取出特定层的原始数据,按照新的源 IP / 目标 IP 发送, 或者发送到特定的 Socket