SEC760 Patch diffing
During the SEC760 course, we're asked to patch diff an old IPV6 MS14-006 vuln which is a DDOS impacting IPV6 on Windows 8. The security bulletin can be found [here](https://learn.microsoft.com/en-us/security-updates/SecurityBulletins/2014/ms14-006?redirectedfrom=MSDN) . This was a pretty old patch and the Intra-Package Delta files require that you have the previous kernel files. I didn't want to spend time installing windows 8 in a VM so I thought I'd look at CVE-2024-38063 which is also an IPV6 DDOS but on windows 11 and for which MalwareTech did a nice [write-up](https://malwaretech.com/2024/08/exploiting-CVE-2024-38063.html). These are mostly my notes from this experience. If you want to know more about this vuln, reading the belowis probably a bad idea and you'd be better served reading the blog Malwaretech wrote.
I pulled the tcpip.sys file from https://winbindex.m417z.com/?file=tcpip.sys for KB5041585
I wanted to get a nice diffing experience so I thought I'd diff it against the previous version of the file on windbindex. So I diffed: 10.0.22621.3958 hash:
7cfb330c436cf064755961a3ed4f304148a2af19d325ef30a91f217958de55e7
with: 10.0.22621.4036
a97b657e0a6c89e8f49dbc59f99fa66242b6b3e20b2c90c2800b9fe33823675e
Opening this up in Bindiff, we quickly get similar results to MalwareTech. One function really differs: IPV6pProcessOptions. The graph view shows two new basic blocks added to the bottom of the function:

We quickly see in the above that the updated function now performs a check before calling IppSendErrorList. We now call Feature_1223761209__private_IsEnabledDeviceUsage which according to MalwareTech is something Microsoft adds to check a global flag and roll back a patch if needed.
if ( !(unsigned int)IppDiscardReceivedPackets((unsigned int)&Ipv6Global, v6, a1, 0, 0i64, 0, v7) && v1 )
{
v27 = Feature_1223761209__private_IsEnabledDeviceUsage();
LOBYTE(v28) = 4;
LOBYTE(v29) = 1;
v30 = _byteswap_ulong(v8);
if ( v27 )
IppSendError(v29, (unsigned int)&Ipv6Global, a1, v28, v4, v30, v3);
else
IppSendErrorList(v29, (unsigned int)&Ipv6Global, a1, v28, v4, v30, v3);
}
return v6;
}Then we either call IppSendErrorList (old code) or IppSendError (new patched code).
We can look at IppSendErrorList and rename it's args in IDA:
__int64 __fastcall IppSendErrorList(
char errorType,
int errorCode,
_QWORD *errorListHead,
char flagA,
char flagB,
int extraValue,
char flagC)
{
_QWORD *currentNode = errorListHead;
__int64 result = 0;
// Traverse linked list
while (currentNode)
{
result = IppSendError(
errorType,
errorCode,
(unsigned int)currentNode,
flagA,
flagB,
extraValue,
flagC);
currentNode = (_QWORD *)*currentNode; // move to next node in list
}
return result;
}I didn't really go any further than this because I didn't have the right kernel version to go as far as Marcus and debug what was going on. From this point, if I was taking this further and had a lab set-up, I'd go ahead and spam packets with IPV6Options; Marcus goes into more detail as to how this quickly fills up the list in IppSendError.
Last updated