The Patch Tuesday of last
September included several vulnerabilities that allowed kernel elevation of
privilege. But no details or analysis were published about them.
In this post, I will present my
research on CVE-2020-1034
2. Patch Diffing
The affected module was ntoskrnl.exe. I downloaded both patched
and unpatched versions of this module. I carried out my analysis on
Windows 10 1903 x64.
Here is the bindiff result of
comparing version 18362.1049 to 18362.1082.
It was clear that EtwpNotifyGuid was changed. I had a close look at the function and discovered an important change.
I decided to look into this further.
3. The Vulnerability
First, I studied NtTraceControl which is the gateway to
the EtwpNotifyGuid. This is a
description of NtTraceControl.
The FunctionCode that leads to
the call of EtwpNotifyGuid
is 0x11. And a few checks need to be satisfied before the actual call as
you will see in the following diagram.
Then, I analyzed the function in
question. If we take a careful look at EtwpNotifyGuid, we will discover
some interesting points. Pay great attention at the spot where the patch was
The rdi register contains the address of the input buffer. The diagram
says the byte at address rdi+0Ch decides
whether to create a UmReplyObject.
Let’s see where the value of r12b
register comes from.
The initial value of r12b was 4. But it is reset to 1. So
when the value of byte ptr [rdi+0Ch] equals
to 1, the qword at rdi+18h is set to
the address of newly created UmReplyObject.
Otherwise, the qword will remain intact. This may contain a dangerous
consequences. As the input can never be trusted.
I expected and tried to see if it
really is. I set the qword at rdi+18h
to an arbitrary value and saw what happened. It was just as I expected. I got a
Wow! I got very excited. I
carried on my analysis further.
The input buffer is passed to EtwpSendDataBlock and EtwpQueueNotification.
Looking into EtwpQueueNotification, I found where the UmReplyObject was referenced.
The value of bl is zero. If the byte at rbp+0Ch is not 0, then the qword at rbp+18h
is read as a pointer to an object. And the reference of the object is increased.
I understood the root cause of
the problem. The culprit was the inconsistent comparison of the byte at rbp+0C.
In the comparison
done in EtwpNotifyGuid, the value
was compared to 1 to decide whether to create a new UmReplyObject.
But in the last comparison, the value was compared to zero.
The first comparision might look like the following in C code.
if (*(bool*)(rdi+0x0C) == true)
The second one might look like the following.
You see the inconsistency? What
if the value is other than 1 or 0? An arbitrary value will be taken as an
Then, ObfReferenceObject is called
for it which means the operation qword
ptr [[InputBuffer + 0x18] - 0x30] ++ is carried out. So arbitrary address
increment was achieved.
This is the proof-of-concept
4. How to Exploit
It is a very nice vulnerability
and the exploitation is quite straightforward.
On kernels of Win10 RS3 or below, we can use the technique of two adjacent palettes.
On kernels of Win10 RS4 or above, we can manipulate the Privilege field of the process token.
Explicit boolean testing
is dangerous if performed on the value of a boolean pointer.
It took much time for me to reproduce
this vulnerability. It was indeed a nice one that is very simple and reliable.
It was quite surprising that
windows kernel should contain this sort of vulnerability.
I will not disclose the full
exploit code as it will be abused by malicious actors.
contact : firstname.lastname@example.org[ PGP ]