原文链接:https://mp.weixin.qq.com/s/5f8GqQ892ZwbWLdowXXVOg
项目 | 详情 |
---|---|
名称 | Windows TCP/IP Remote Code Execution Vulnerability |
简介 | tcpip.sys在对ipv6数据包进行重组时,NextHeaderOffset可能超出缓冲区范围,导致越界写的发生,利用该漏洞可以实现远程命令执行 |
影响版本 | 该漏洞影响所有受支持的 Windows 操作系统 |
编号 | CVE-2022-34718 |
如果发送的数据包大小超过了最大传输单元(MTU),IPv6 源节点会将数据包分割成多个分片,在前面添加 fragment header ,作为单独的数据包进行传送,然后由目的节点对数据包进行重组。
Fragment header 结构如下:
1
2
3
4
5
6
7
|
0
1
2
3
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
Next
Header | Reserved | Fragment Offset |Res|M|
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| Identification |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
在分割时,数据包会被分为 不可分片部分 和 可分片部分:
假设原始数据包组成如下:
1
2
3
|
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| IPv6 header | Hop
-
by
-
Hop options | ICMPv6 header | ICMPv6 paylaod |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
根据数据包的大小,它会被源节点分成多个分片:
1
2
3
4
5
6
7
8
9
10
11
|
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| IPv6 header | Hop
-
by
-
Hop options | Fragment header | First fragment |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| IPv6 header | Hop
-
by
-
Hop options | Fragment header | Second fragment |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
| IPv6 header | Hop
-
by
-
Hop options | Fragment header | Last fragment |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
|
当上面的数据包都到达目的节点后,会重组成为原始数据包:
除此之外需要修改两个位置的数值:
Internet Protocal Security(IPsec) 是一个安全网络协议组,可以对数据包进行验证和数据加密,从而为位于 IP 网络中的两台计算机提供安全的加密通信。IPsec 用于 virtual private networks(VPNs)。
IPsec 使用以下的协议实现不同的功能:
其中 ESP 结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
0
1
2
3
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| Security Parameters Index (SPI) |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| Sequence Number |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| Payload data |
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| | Padding |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| | Pad Length |
Next
Header |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| Integrity Check Value (ICV) |
+
......
+
| ...... |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
漏洞发生时的函数调用栈如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
0
: kd> kb
# RetAddr : Args to Child : Call Site
00
fffff80a`
1f1842ea
: ffffb00e`
0cbef000
ffffb00e`
0d333270
ffffb00e`
0f5b4890
ffffb00e`
00000050
: tcpip!Ipv6pReassembleDatagram
+
0x1e3
01
fffff80a`
1f184442
: ffffb00e`
00000000
fffff80a`
1f1c61e8
00000000
`
00000000
ffffb00e`
0d3138f0
: tcpip!Ipv6pReceiveFragment
+
0xae2
02
fffff80a`
1f03bfdf
: ffffb00e`
0cbef000
ffffb00e`
0cbef000
00000000
`
00000001
00000000
`
0000002b
: tcpip!Ipv6pReceiveFragmentList
+
0x42
03
fffff80a`
1f03de45
: fffff80a`
1f1c1240
ffffb00e`
0c8ec940
00000000
`
00000001
ffffb00e`
0cbef000
: tcpip!IppReceiveHeaderBatch
+
0x3ef
04
fffff80a`
1f044131
: ffffb00e`
0d31eb90
ffffb00e`
0d23e9c0
fffff803`
94d7b001
00000000
`
00000000
: tcpip!IppFlcReceivePacketsCore
+
0x315
05
fffff80a`
1f043e12
:
00000000
`
00000017
fffff803`
00000001
fffff80a`
1f001bf0
ffffb00e`
0d23e901
: tcpip!FlpReceiveNonPreValidatedNetBufferListChain
+
0x271
06
fffff803`
92ebce75
:
00000000
`
00000002
fffff803`
931d1980
fffff80a`
1f043d50
fffff803`
94d7b1f0
: tcpip!FlReceiveNetBufferListChainCalloutRoutine
+
0xc2
07
fffff80a`
1f0023a6
: ffffb00e`
0cc1b7b0
00000000
`
00000000
ffffb00e`
0c7ff870
ffffb00e`
0d23e900
: nt!KeExpandKernelStackAndCalloutInternal
+
0x85
08
fffff80a`
1e10392e
:
00000000
`
00000000
fffff803`
94d7b2c0
00000000
`
00000001
fffff80a`
1de5f20d
: tcpip!FlReceiveNetBufferListChain
+
0xb6
09
fffff80a`
1e1028cc
: fffff80a`
1f522801
fffff803`
94d7dd86
0000000e
`
00000000
fffff80a`
00000001
: NDIS!ndisMIndicateNetBufferListsToOpen
+
0x11e
0a
fffff80a`
1eca6156
:
00000000
`
00000000
00000000
`
00000000
ffffb00e`
0d0f4e40
ffffb00e`
0d23e930
: NDIS!NdisMIndicateReceiveNetBufferLists
+
0x31c
0b
fffff80a`
1eca73e3
: ffffb00e`
0d23e900
00000000
`
00000001
ffffb00e`
0d0f4e40
fffff803`
94d7b588
: e1i63x64!RECEIVE::RxIndicateNBLs
+
0x132
0c
fffff80a`
1ecae315
: ffffb00e`
0c483830
ffffb00e`
0d0f4000
ffffb00e`
0d0f4001
fffff803`
00000000
: e1i63x64!RECEIVE::RxProcessInterrupts
+
0x253
0d
fffff80a`
1ecae623
: ffffb00e`
0c4226b0
00000001
`
00000000
00000001
`
00000000
00000000
`
00000000
: e1i63x64!INTERRUPT::MsgIntDpcTxRxProcessing
+
0x121
0e
fffff80a`
1ecaddb8
: ffffb00e`
0e66f7d8
00000000
`
00000000
40200342
`
00000000
00000000
`
00000000
: e1i63x64!INTERRUPT::MsgIntMessageInterruptDPC
+
0x10f
0f
fffff80a`
1e104e69
: ffffda01`
9d7c9010
ffffda01`
9d7c9320
00000000
`
00000000
00000000
`
00000000
: e1i63x64!INTERRUPT::MiniportMessageInterruptDPC
+
0x28
10
fffff803`
92e7f785
: ffffb00e`
0d200000
fffff803`
93155180
ffffb00e`
0cc8e5d0
ffffb00e`
0cc8e5d0
: NDIS!ndisInterruptDpc
+
0x1c9
11
fffff803`
92e7ed10
: fffff80a`
20dc79a8
00000000
`
002e593c
00000000
`
00140001
00000000
`
00000000
: nt!KiExecuteAllDpcs
+
0x335
12
fffff803`
92f7500a
:
00000000
`
00000000
fffff803`
93155180
fffff803`
931d1980
ffffb00e`
0f6cc080
: nt!KiRetireDpcList
+
0x910
13
00000000
`
00000000
: fffff803`
94d7c000
fffff803`
94d76000
00000000
`
00000000
00000000
`
00000000
: nt!KiIdleLoop
+
0x5a
|
根据以上信息可以确定,tcpip.sys 使用 IppReceiveHeaderBatch
函数处理接收到的数据包,对 next header 的数值进行判断并调用相应函数处理对应头部,漏洞就发生在处理 fragment header 的时候。
tcpip.sys 会调用 Ipv6pReceiveFragmentList
函数对 fragment header 进行处理,在对分片进行重组的时候:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
void Ipv6pReassembleDatagram(__int64 Packet, Reassembly_t
*
Reassembly, char OldIrql)
{
ExtensionHeaderLength
=
Reassembly
-
>ExtensionHeaderLength;
TotalLength
=
ExtensionHeaderLength
+
Reassembly
-
>DataLength;
HeaderAndOptionsLength
=
ExtensionHeaderLength
+
0x28
;
NetBufferList
=
NetioAllocateAndReferenceNetBufferAndNetBufferList(
IppReassemblyNetBufferListsComplete,
Reassembly,
0i64
,
0i64
,
0
,
0
);
NetBuffer
=
NetBufferList
-
>FirstNetBuffer;
data
=
NdisGetDataBuffer(NetBuffer, HeaderAndOptionsLength,
0i64
,
1u
,
0
)
/
/
请求访问 NET_BUFFER 中的一段连续空间,请求的大小为 HeaderAndOptionsLength
Reassembly
-
>IPv6.Payload_length
=
__ROR2__(TotalLength,
8
);
*
data
=
Reassembly
-
>IPv6;
/
/
复制 IPv6 header
memmove(data
+
0x28
, Reassembly
-
>ExtensionHeader, Reassembly
-
>ExtensionHeaderLength);
/
/
复制 ExtensionHeader
*
(data
+
Reassembly
-
>nh_offset)
=
Reassembly
-
>next_header;
/
/
复制
next
header
...
}
|
缓冲区 data 的大小为 HeaderAndOptionsLength
,next header 的偏移值为 Reassembly->nh_offset
。发生越界写的原因就是 Reassembly->nh_offset
的数值大于 HeaderAndOptionsLength
。
接下来通过调试确定这两个数值的来源,测试用数据包组成如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
0
1
2
3
4
5
6
7
8
9
a b c d e f
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
0000
| Ethernet II,
0x0e
B | |
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
+
0010
| |
+
IPv6 header,
0x28
B
+
0020
| |
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
0030
| | Routing header,
8
B |
93
59
-
> ESP header,
8
B
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
0040
99
40
00
00
00
00
|
55
55
55
55
55
55
55
55
55
55
-
> IV,
0x10
B
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
0050
55
55
55
55
55
55
|eb
42
e4
0a
95
da
11
1d
21
a1|
-
> payload
+
padding
+
padding_length
+
next_header
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
+
0x30
B,已被加密
0060
|ea c7
31
c9 e1
24
48
8d
f9
98
d4
98
82
b7 eb
5d
|
+
+
0070
|b7
8f
bf c6
3a
00
eb
22
7d
26
55
b7
43
9f
60
62
|
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
0080
|e3 ea fe
8c
23
87
|
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
|
由于 ESP header 在 Routing header 之后,系统会先处理 ESP header。tcpip.sys 会调用 IppReceiveEspList
函数处理该头部,具体功能位于 IppReceiveEspNbl
函数中,该函数会对 ESP 中的加密数据进行解密,解密结果为:
1
2
3
4
|
0x00
-
-
-
-
-
-
-
-
-
-
-
-
3a
00
-
00
01
56
56
56
56
55
55
0x10
55
55
55
55
55
55
55
55
-
55
55
55
55
55
55
55
55
0x20
55
55
55
55
55
55
01
02
-
03
04
05
06
07
08
09
0a
0x30
0b
0c
0d
0e
0e
2c
|
可以看到 next header 字段的数值为 0x2c,即 Fragment Header for IPv6,系统处理完 ESP 后会继续处理 fragment header。
整理调试过程中,Reassembly->nh_offset
和 HeaderAndOptionsLength
的数据来源变化情况:
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
|
/
/
IppReceiveHeadersHelper
Packet
-
>prefix_size
=
header_size;
/
/
0x28
这里是ipv6 header的长度
/
/
Ipv6pReceiveRoutingHeader
/
/
/
/
0x11a
保存的是 nh_offset ,因为此时在处理 routing header,
next
header 位于起始位置
/
/
/
/
因此大小和 header_size 相同
Packet
-
>nh_offset
=
Packet
-
>prefix_size;
/
/
0x28
/
/
/
/
继续向下读取 routing header 内容
NetBufferList
=
Packet
-
>net_buffer_list;
routing_header
=
NdisGetDataBuffer(NetBufferList
-
>FirstNetBuffer,
8u
, &Storage,
1u
,
0
);
len
=
8
*
routing_header
-
>length
+
8
;
Packet
-
>prefix_size
+
=
len
;
/
/
加上 routing header 的
8
个字节,
0x30
/
/
IppReceiveEspNbl
Packet
-
>nh_offset
=
Packet
-
>prefix_size
+
LOWORD(NetBuffer
-
>DataOffset)
-
data_offset
+
9
;
/
/
0x30
+
0x84
-
0x56
+
0x9
=
0x67
/
/
即 Packet
-
>prefix_size
+
len
(payload_data
+
padding)
+
8
+
1
/
/
其中
8
是SPI和Sequence Number占据字节数,
1
是Padding Length占据字节数
Packet
-
>prefix_size
+
=
(iv_length
+
8
);
/
/
0x48
/
/
Ipv6pReceiveFragment
Packet
-
>prefix_size
+
=
8
;
/
/
加上Fragment header的
8
个字节,
0x50
ExtensionHeaderLength
=
Packet
-
>prefix_size
-
0x30
;
/
/
0x50
-
0x30
=
0x20
Reassembly
-
>ExtensionHeaderLength
=
ExtensionHeaderLength;
/
/
这里赋值
0x20
Reassembly
-
>nh_offset
=
Packet
-
>nh_offset;
/
/
这里赋值
0x67
|
由此可以看出,系统在处理 ESP header 时,因为 next header 位于数据包的尾部, 因此 nh_offset 的计算考虑了 payload 的长度;但是在处理 fragment header 的时候,系统认为 next_header 位于 ExtensionHeader 中。即:
1
2
3
4
5
6
7
|
|<
-
data
buffer
size
-
>|
|<
-
0x28
B
-
>|<
-
Extension Header
0x20
B
-
>|
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
| IPv6 header | Routing header | ESP header | IV | Payload |PL |NH |
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
↑ 系统认为的next_header位置
↑ 真实的next_header位置
|
实际上,根据 ,在进行分片的时候,ESP header 是不能放在 fragment header 的前面的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
original packet:
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
/
/
-
+
-
-
-
-
-
-
-
-
+
| Per
-
Fragment |Ext & Upper
-
Layer| first | second | | last |
| Headers | Headers |fragment|fragment|....|fragment|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
/
/
-
+
-
-
-
-
-
-
-
-
+
fragment packets:
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
| Per
-
Fragment |Fragment | Ext & Upper
-
Layer | first |
| Headers | Header | Headers | fragment |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Per
-
Fragment |Fragment| second |
| Headers | Header | fragment |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
o
o
o
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
| Per
-
Fragment |Fragment| last |
| Headers | Header | fragment |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
|
其中的 Ext & Upper-Layer Headers 可能包括 TCP、UDP、IPv4、IPv6、ICMPv6、ESP 等。
Ipv6pReassembleDatagram
新增代码段
1
2
3
4
5
6
7
8
9
10
11
12
|
TotalLength
=
ExtensionHeaderLength
+
Reassembly
-
>DataLength;;
HeaderAndOptionsLength
=
ExtensionHeaderLength
+
0x28
;
if
( Reassembly
-
>nh_offset > HeaderAndOptionsLength ) {
/
/
这里比较了
next
header 偏移值和 net
buffer
的大小
LABEL_7:
LOBYTE(v9)
=
OldIrql;
IppDeleteFromReassemblySet(v8
+
20392
, Reassembly, v9);
LABEL_39:
+
+
*
(v10
+
8
);
+
+
*
(v11
+
140
);
return
;
}
|
IppReceiveEsp
新增代码段
1
2
3
4
5
6
7
8
|
next_header
=
Packet
-
>next_header;
IppReceiveEspNbl(...);
if
( !
*
next_header || (result
=
(
*
next_header
-
0x2B
), result <
=
1
) )
/
/
也就是说ESP后面不能跟
next
header <
=
0x2c
的头部了
{
result
=
IppDiscardReceivedPackets(v3,
6i64
, Packet);
*
(v2
+
140
)
=
0xC000021B
;
goto LABEL_11;
}
|
可以看到经过补丁修复之后,系统对 ESP header 的 next header 字段进行了判断,不再允许小于等于 0x2c 的头部,同时在进行分片重组时,对 Reassembly->nh_offset
和 HeaderAndOptionsLength
的数值进行了判断。
更多【CVE-2022-34718 TCP/IP 远程命令执行漏洞分析】相关视频教程:www.yxfzedu.com