By Chengdu Security Response Center of 360 Core Security
The monthly security patches released by Microsoft on March 12th, 2019 fixed two Windows zero-days being abused in the wild. CVE-2019-0808 was one of them which was discovered by Google’s Threat Analysis Team and submitted to Microsoft. According to Microsoft, this vulnerability affecting Win32k components allows attackers to elevate privileges and execute arbitrary code in kernel mode. Google’s analysis says the vulnerability only affects Windows 7 and Windows Server 2008. Windows 10 will not be affected because Microsoft introduced vulnerability mitigation measures in the latest version of the operating system. Considering that some users are still using Windows 7 and this vulnerability combined with Chrome RCE (CVE-2019-5786) has been used for real APT attacks, so this 0day is very likely to be exploited to perform large-scale attacks and pose a real threat. Therefore, 360 Core Security Technique Center constructed the POC and reproduced the vulnerability triggering process so that security vendors can reference to increase the corresponding protection measures.
After receiving the menu window object returned by the window procedure function, the xxxMNFindWindowFromPoint function does not effectively check the validity of its member tagPOPUPMENU, causing the subsequent MNGetpItemFromIndex function to trigger the NULL pointer deference.
Below are the elaborations of the process:
Step 1: First, you need to set the global message hook function to intercept the MN_FINDMENUWINDOWFROMPOINT message sent by xxxMNFindWindowFromPoint.
Step 2: Created a menu item with drag-and-drop functionality, and a special window handle hpwn for backup.
- Step 3: Entered the NtUserMNDragOver function by dragging the menu or directly calling the relevant system call.
- Step 4: The sequencing of the function callings is NtUserMNDragOver -> xxxMNMouseMove -> xxxMNFindWindowFromPoint. xxxMNFindWindowFromPoint sent a MN_FINDMENUWINDOWFROMPOINT message to the window and received the returned window handle. Since the global message hook function was set, the execution flow went back to the user layer.
- Step 5: The window procedure function of the menu window was replaced, so the global message hook function entered the FakeWindowProc function after execution. Here, it returned directly to the window handle hpwn that has been prepared in advance.
- Step 6: After the xxxMNFindWindowFromPoint function obtained the window handle, it directly returned its corresponding window object and passed it to the xxxMNUpdateDraggingInfo function. It should be noted that the window object obtained here is the fake hpwn window object. The internal member tagPOPUPMENU was not set completely, so most members are “0”!
- Step 7: After the xxxMNUpdateDraggingInfo function obtained the window object, it accessed its member tagPOPUPMENU object through the MNGetpItem function.
The MNGetpItem function continued to access the spmenu member of the tagPOPUPMENU object, causing a NULL pointer dereference vulnerability.
In the monthly patches in March, Microsoft fixed the window type confusion (not NULL for the MENU type), and checked the state of the popupMenu object. The code comparison was drawn before and after the patch as follows:
Through the constructed POC, it is found that the vulnerability is triggered when the NtUserMNDragOver function is called under certain circumstances, causing NULL pointer dereference in win32k!MNGetpItemFromIndex. The vulnerability uses the Windows kernel driver module win32k.sys to perform local privilege escalation. Afterwards, it can break through the restrictions of user privilege. In the meanwhile, it can also help attackers to escape sandbox to completely control the victim’s computer.