Analysis and exploitation of UAF vulnerability CVE-2015-2546

This article will analyze win32kthe CVE-2015-2546 vulnerability in the Windows operating system kernel module window manager subsystem. Similar to the CVE-2017-0263 vulnerability analyzed in the previous article, this vulnerability is also a post-release reuse of the pop-up menu tagPOPUPMENUobject ( UAF) vulnerability. The environment analyzed is a virtual machine in the Windows 7 x86 SP1 basic environment.

Article link: xiaodaozhi.com/exploit/122…

0x0 Preface

This article analyzes the CVE-2015-2546 UAF (use-after-free) vulnerability that occurs in the menu management component of the window manager (User) subsystem. During the kernel function xxxMNMouseMovecall xxxSendMessageto send a message to the target menu window object MN_SELECTITEM, the execution flow has the possibility of a user callback; after the function call that sends the message returns, the function does not reacquire the address of xxxMNMouseMovethe pop-up menu object associated with the target menu window object , but tagPOPUPMENUDirectly use the pop-up menu object address MN_SELECTITEMstored in the register before sending the message , pass the object address as a parameter to the function call, and access the target pop-up menu object in the function.ebxxxxMNHideNextHierarchy

If the user process has previously constructed a menu window object with special associations and properties through the exploit technique, and set a specific hook handler, then during the call to send a message to the xxxSendMessagetarget menu window object MN_SELECTITEM, the execution flow returns to the user context, and the exploit in the user process The code will have enough ability to trigger the destruction of the target menu window object, thereby directly releasing the pop-up menu object associated with the menu window object in the kernel; when the execution flow returns to the kernel context, the memory pointed to by the address stored in the register has been released, ebxand The function xxxMNHideNextHierarchylacks necessary verification before passing the address as a parameter to the function , which will lead to a UAF vulnerability.

After triggering the destruction of the target menu window object, the exploit code in the user process uses clever memory layout to cause the system to reallocate a memory area of ​​the same size to occupy the memory block of the previously released pop-up menu object, forge a new pop-up menu object and construct Relevant member fields, forge a new submenu window object and associated message processing function in the user process address space, and store the address of the window object in the reassigned pop-up menu object member field spwndNextPopup. The function in the kernel will send a message to the submenu window object pointed to by the member xxxMNHideNextHierarchyfield of the target pop-up menu object , which will cause the execution flow to directly enter the forged message processing function defined in the user process address space in the kernel context, in the execution function Kernel exploit code to achieve the purpose of kernel exploitation and privilege escalation.spwndNextPopupMN_SELECTITEM

0x1 principle

The CVE-2015-2546 vulnerability occurs in a kernel function win32k!xxxMNMouseMove. During the execution of this function, after calling the function to send a ( ) message xxxSendMessageto the target menu window object , if the function returns a value of , the system will verify the validity of the memory address of the target pop-up menu object stored in the register. Just call the function and pass the address into the function's parameter.0x1F0MN_SETTIMERTOOPENHIERARCHY0ebxtagPOPUPMENUxxxMNHideNextHierarchypopupMenu

.text:00139530pushedi ; lParam
.text:00139531pushedi ; wParam
.text:00139532push1F0h; message
.text:00139537pushesi ; pwnd
.text:00139538call_xxxSendMessage@16 ; xxxSendMessage(x,x,x,x)
.text:0013953Dtesteax, eax
.text:0013953Fjnz short loc_139583
.text:00139541pushebx ; popupMenu
.text:00139542call_xxxMNHideNextHierarchy@4 ; xxxMNHideNextHierarchy(x)
.text:00139547jmp short loc_139583 

Vulnerable target code snippet

Comparing with the patch, it is found that the patch adds a comparison judgment between the pointer of the target window object extension area pointing to the associated pop-up menu object and the value stored in the register between the statements of calling the function to xxxSendMessagesend a message and calling MN_SETTIMERTOOPENHIERARCHYthe function . If they are not equal, the function will be skipped. call.xxxMNHideNextHierarchyebxxxxMNHideNextHierarchy

.text:BF93EC2Epushedi ; lParam
.text:BF93EC2Fpushedi ; wParam
.text:BF93EC30push1F0h; message
.text:BF93EC35pushesi ; pwnd
.text:BF93EC36call_xxxSendMessage@16 ; xxxSendMessage(x,x,x,x)
.text:BF93EC3Btesteax, eax
.text:BF93EC3Djnz short loc_BF93EC8C
.text:BF93EC3Fmov eax, [ebp+pwnd]
.text:BF93EC42cmp [eax+0B0h], ebx
.text:BF93EC48jnz short loc_BF93EC8C
.text:BF93EC4Apushebx
.text:BF93EC4Bcall_xxxMNHideNextHierarchy@4 ; xxxMNHideNextHierarchy(x)
.text:BF93EC50jmp short loc_BF93EC8C 

Target code snippet fixed by patch

In the Windows kernel, the menu object is displayed on the screen through tagWNDa special type #32768( ) menu window object of the window object. The pointer MENUCLASSto the associated pop-up menu object is stored in the extended area at the end of the menu window object .tagPOPUPMENU

When a function xxxSendMessagesends MN_SETTIMERTOOPENHIERARCHYa message, the system ultimately xxxMenuWindowProcreceives and calls a function in function MNSetTimerToOpenHierarchyto process the message and return the function's return value to the caller.

When the execution flow returns to the function xxxMNMouseMove, the system determines the return value. If the return value is , 0the function is called xxxMNHideNextHierarchyto close tagPOPUPMENUthe pop-up submenu of the target pop-up menu object.

Since before calling function xxxMNHideNextHierarchy, xxxMNMouseMovethere is also a statement in function that calls xxxSendMessagefunction to send MN_SETTIMERTOOPENHIERARCHYmessage, this may cause the execution flow to be called back to the user process. Therefore, during this period, the attacker can trigger logic in the user process to cause tagPOPUPMENUthe memory of the target pop-up menu object to be released or reallocated, which will cause the target parameter popupMenuto point to uncontrollable data in the memory area. If the attack code deliberately constructs the data in the memory block reallocated in the original location, then when xxxMNHideNextHierarchysending a message to the submenu window object in the function, the execution flow of the kernel context may directly enter the exploit code function located in the user process address space. middle.

0x2 Tracking

In win32kthe kernel module, there are two calls to function from other functions xxxMNMouseMove:

  • xxxHandleMenuMessages(x,x,x)+2E9
  • xxxMenuWindowProc(x,x,x,x)+D1C

One of them is when the function xxxHandleMenuMessageshandles WM_MOUSEMOVEthe or WM_NCMOUSEMOVEmessage, and the other is when the function xxxMenuWindowProchandles MN_MOUSEMOVEthe message.

Use WinDBG to xxxMNMouseMoveset a breakpoint on the function and pop up the right-click menu in the virtual machine desktop area. Observe the paths through which the system will call the function under natural conditions. It is found that the resulting call stack is basically as follows:

 # ChildEBP RetAddr
00 98af4a90 94779066 win32k!xxxMNMouseMove
01 98af4aec 94778c1f win32k!xxxHandleMenuMessages+0x2ed
02 98af4b38 9477f8f1 win32k!xxxMNLoop+0x2c6
03 98af4ba0 9477f9dc win32k!xxxTrackPopupMenuEx+0x5cd
04 98af4c14 83e501ea win32k!NtUserTrackPopupMenuEx+0xc3
05 98af4c14 76e170b4 nt!KiFastCallEntry+0x12a 

Natural condition call stack of function xxxMNMouseMove


xxxMNMouseMove

Function xxxMNMouseMoveused to process the message that the mouse moves to the specified coordinate point. At xxxMNMouseMovethe beginning of the function, the function determines whether the pop-up menu object passed in through the parameter tagPOPUPMENUis the current root pop-up menu object, and determines tagMENUSTATEwhether the incoming mouse coordinates have indeed changed compared with the coordinates previously stored in the current menu state structure. If If the conditions are not met, return directly. Next, the function calls xxxMNFindWindowFromPointthe function and passes in the target pop-up menu object pointer and the new coordinates as parameters to find the menu window object displayed on the screen where the coordinate point is located. When the return value is the address of the real menu window object, the function uses the window object as the target window object and the menu item number where the mouse coordinates are located as the parameter. It sends a () message to the target window object to perform the operation of selecting the menu item wParamand receives The return value of the function serves as the feedback flag variable.0x1E5MN_SELECTITEM

Before calling the statement xxxSendMessageto send the message, the function determines the value of the previously returned feedback flag variable to ensure that the menu item pointed to by the pointer is associated with another pop-up menu ( ) as a submenu and is not in a disabled state ( ).MN_SETTIMERTOOPENHIERARCHYxxxMNMouseMoveMF_POPUPMFS_GRAYED

.text:00139517xor edi, edi
.text:00139519pushedi ; lParam
.text:0013951Apush[ebp+cmdItem] ; wParam
.text:0013951Dpush1E5h; message
.text:00139522pushesi ; pwnd
.text:00139523call_xxxSendMessage@16 ; xxxSendMessage(x,x,x,x)
.text:00139528testal, 10h ; MF_POPUP
.text:0013952Ajzshort loc_139583
.text:0013952Ctestal, 3 ; MFS_GRAYED
.text:0013952Ejnz short loc_139583 

Function xxxMNMouseMove determines the value of the flag variable fed back by selecting the menu item

Next, the function sets the timer for opening the pop-up submenu by calling the function to xxxSendMessagesend a message to the target menu window object . MN_SETTIMERTOOPENHIERARCHYIf the function returns a value of , 0indicating that the pop-up submenu operation failed, the function is called xxxMNHideNextHierarchyto close the pop-up menu belonging to the current target pop-up menu object.

 popupNext = popupMenu->spwndNextPopup;if ( popupNext ){[...]popupNext = popupMenu->spwndNextPopup;if ( popupNext != popupMenu->spwndActivePopup )xxxSendMessage(popupNext, 0x1E4, 0, 0); // MN_CLOSEHIERARCHYxxxSendMessage(popupMenu->spwndNextPopup, 0x1E5, 0xFFFFFFFF, 0); // MN_SELECTITEM[...]} 

Code snippet of function xxxMNHideNextHierarchy

Function Determines whether the menu window object pointed to by xxxMNHideNextHierarchythe member field of the target pop-up menu object is the same as the member field pointed to. The member field points to the menu window object of the submenu directly associated with the current pop-up menu object; and the member field is used to store the menu window object of the currently active menu (that is, the menu where the current mouse or keyboard focus is). If they are not the same, then the function returns the submenu window pointed to by the member fieldspwndNextPopupspwndActivePopupspwndNextPopupspwndActivePopupspwndNextPopup

おすすめ

転載: blog.csdn.net/javagty6778/article/details/129649645