Lucene search

K
attackerkbAttackerKBAKB:82041473-1F3B-4A70-B42F-C27B20B7455E
HistoryMay 09, 2023 - 12:00 a.m.

CVE-2023-29336

2023-05-0900:00:00
attackerkb.com
11
windows 10
patch diff
bindiff
hlil graph
code diff
validation of data
incrementing
binary ninja
uaf
update the lock count
ntuserenablemenuitem
menu object
submenus
exploit
sc_close
wm_close
memory deallocation

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

44.5%

Win32k Elevation of Privilege Vulnerability

Recent assessments:

gwillcox-r7 at May 31, 2023 9:15pm UTC reported:

Doing a patch diff between a Windows 10 1607 x86 version of win32kfull.sys prior to the patch and after the patch shows that only one function changed: xxxEnableMenuItem.

Looking at the code diff for this with BinDiff shows that two new blocks were added. These appear to be doing some validation of data and then optionally also incrementing a different data element.

After some time getting proper structures defined in Binary Ninja, I was able to come up with the following HLIL graph showing the code for xxxEnableMenuItem before the patch was issued:

<https://imgur.com/oKpFgBi&gt;

And here is the code after the patch was issued:

<https://imgur.com/ZgTCd5z&gt;

Of note is the fact that the new edition of the code is checking that pRealMenu exists and then if it does, its incrementing that object’s cObjLock count by one. This extra lock appears to then be undone in a call to pRealMenu = ThreadUnlock1(), which was also added in.

Further analysis is available at <https://www.numencyber.com/cve-2023-29336-win32k-analysis/&gt; which explains how this bug is a UAF, which makes sense given that a check was added into update the lock count appropriately. As explained in that writeup, prior to the patch, the code purely locked the window object pointed to by pMenu-&gt;spwndNotify and failed to also lock the menu object nested within the window object, aka the pRealMenu object returned by the call to MenuItemState.

Tracing the call flow backwards we can see that xxxEnableMenuItem() is called by NtUserEnableMenuItem(). According to the writeup, the menu item passed in via the first argument to xxxEnableMenuItem(), aka pMenu, would typically be locked inside of inside of a higher level function such as NtUserEnableMenuItem(). However they raise the question of “okay so you have a menu object you need to lock, but which menu item would need locking?”

So why this question in particular? Surely we are just dealing with one menu object which means one menu itself right? Well as the writeup explains, the object returned by a function such as MenuItemState() may encompass not only the main menu within a window object but also its submenus, and even subsubmenus in some cases.

This is becuase MenuItemState() will call MNLookupItem() which will in turn recursively call itself until it finds the object its looking for, meaning that pMenu may actually point to a nested set of menu objects. This looks like a potential case where assumptions could lead to some incorrect results.

In the exploit they create 4 menus, namely MenuA, MenuB, MenuC and MenuD, with MenuB being a child of MenuA, MenuC being a child of MenuB, and so on. They set the ID of MenuD to be 0xF060, aka SC_CLOSE. As noted at <https://stackoverflow.com/questions/10101742/difference-between-wm-close-and-sc-close&gt;, this is sent when the user presses the close button or otherwise uses some menu control to close the window. They remove the class ID of SC_CLOSE from MenuA. They then release MenuC by deleting all references to it within MenuB, in order to ensure proper memory deallocation.

When xxxRedrawTitle() is called from within xxxEnableMenuItem(), a transfer will be made to a user mode callback via a call to xxxSendMessage(), at which point the exploit removes the reference between MenuC and MenuB, effectively releasing MenuC. At this point the reference to MenuC within xxxEnableMenuItem() will become invalid. Keep in mind in the code MenuC is effectively var_pMenu_spwndNotify
so thats where the relationship comes into play.

Hope that helps!

Assessed Attacker Value: 3
Assessed Attacker Value: 3Assessed Attacker Value: 0

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

0.001 Low

EPSS

Percentile

44.5%