Play bad vulnerability: Let the CVE-2014-4113 overflow Win8
1. Introduction
In October 14, 2014, Crowdstrike and FireEye published an article describing a new Windows Elevation of Privilege Vulnerability.Articles about CrowdstrikeMing: This new vulnerability was discovered by hurricane panda, a highly advanced attack team. Before that, it had been at least five months before the vulnerability was exploited by HURRICANE pandatv.
After Microsoft released the MS14-058 patch, the vulnerability exploitation tool described in the article went out. Before writing this article, there have been a lot of analysis on this tool and MSF exploitation modules for this vulnerability. Currently, this tool supports all 32-bit and 64-bit Windows versions except Win8.
??Interestingly, according to the analysis in the blog, FireEye pointed out that due to more protection mechanisms in Versions later than Win8, vulnerabilities can only attack Windows Versions earlier than Win8.??
So I'm curious if the vulnerability can be exploited in the latest version of Windows. This article describes my analysis results and demonstrates how to use them in Win8 and win8.1.
2. vulnerability details
The following analysis is based on the win64.exe and published information of the outbound traffic.
Analyzed binary file MD5: 70857e02d60c66e27a173f8f292774f1
This vulnerability has been described in detail elsewhere, so we only pay attention to the relevant details.
Win32k. sys is part of the Windows subsystem kernel mode. It manages Windows and provides graphical device interfaces (GDI. User32 in user mode! The TrackPopupMenu function can be used to trigger a vulnerability, and the function is responsible for processing win32k! XxxHandleMenuMessages, which calls win32k! XxxMNFindWindowFromPoint, (generally, win32k is returned! TagWND struct address or error code-1,-5), the called function checks the first return value, but does not check-5, win32k! XxxSendMessage regards-5 (0 xfffffffb) as a valid address, and the value will be passed through win32k! The xxxSendMessage function is passed into win32k! XxxSendMessageTimeout (win32k on Win8! XxxSendTransformableMessageTimeout ). In user mode, the published exploit uses ZwAllocateVirtualMemoryAPI in 0xfffffffb to apply for memory and put a constructed win32k in this address! The tagWND struct. After the vulnerability is triggered, the kernel accesses the forged struct in this user mode. The constructed struct can change the program execution process and then execute a win32k! Function pointer in the tagWND struct. This function pointer points to a simple Kernel Mode shellcode: Replace the pointer to the Master card in the current EPROCESS struct with a pointer to the Master card with a pointer to a process running with the system permission.
3. Use of Win8.1
This vulnerability cannot be used directly for Windows 8 because the Supervisor ModeExecution Prevention OF Win8 SMEP will prevent shellcode from running on the memory page of Kernel Mode user mode. But win32k! The incorrect call to xxxSendTransformableMessageTimeout still exists. However, Win8.1 has been replaced by win32k! The index of the tagWND address structure, which is a correct boundary check.
Therefore, Windows 8.1 can no longer be controlled. However, in the next section, we will see a specially crafted win32k! The tagWND address structure can still be used to successfully exploit this security vulnerability.
3.1 carefully crafted win32k! TagWND struct
To exploit this vulnerability, we need to apply for a designed win32k in Win8.1 user mode! TagWND address structure. When the vulnerability is triggered, win32k! The xxxSendTransformableMessageTimeout function is first available in win32k! The tagWND address offset 0 × 10 reads a 64-bit value and matches it with win32k! Compare the gptiCurrentkernel pointer. If an unsupported value is provided in this offset address, an exception occurs. Next, the program reads a WORD from offset 0 and uses it as a memory index. The byte mentioned by this index will be compared with 0 × 01.
If we set win32k! If the first dword of the tagWND struct is set to 0, the check will fail and the program will call win32k! XxxInterSendMessageEx and the constructed win32k! The tagWND struct address is used as the first parameter.
Win32k! The xxxInterSendMessageEx function reads win32k again! In the tagWND struct, the pointer at 0x10 is offset, and the pointer is referenced to read the new pointer. The new pointer is used to read the value at the offset of 0x170, and ntoskrnl! The value returned by PsGetCurrentProcessWin32Process is compared.
Constructed win32k! The tagWND struct will read the value 0 in user mode and then win32k in the user mode after the dual-decoding is successful! XxxInterSendMessageEx reads a byte from 0x2b0, which can be any value except 0 × 20.
After all the conditions are met, win32k! XxxInterSendMessageEx will eventually call win32k! Iswindow?topcomposed transmits the win32k we constructed through the pointer! The tagWND struct is used as a parameter.
Win32k! Iswindow?topcomposed will be constructed from win32k! In the tagWND struct, the value at the offset of 0 × 18 is read. If the read value is 0, the function returns 0. It does not solve any reference to any member of the structure.
If all the conditions are met, win32k! The final code of xxxInterSendMessageEx is similar to the following:
This code executes the linked list insert action to insert the values found in the RDI Register into the linked list. The value of this register is a kernel address that we cannot directly control. This code will read win32k at the beginning! The offset of the tagWND struct is 0 × 60. check whether it is null. If it is null, the value is win32k! The tagWND struct is used as the new linked list header.
If win32k! The tagWND struct has stored a chain table header at a Offset of 0 × 60. This Code starts to traverse the table until it finds that the end pointer is null and overwrites the pointer with the memory address in the RDI register. This Code allows us to overwrite the eight NULL bytes of any address with one kernel address (Value in RDI register. Although we cannot control the kernel address, this is enough.
3.2 search for coverage targets
There are many things that can be covered in the kernel memory, what we need is a memory location that starts with a 64-bit value of 0 and overwrites it to the Elevation of Privilege effect. We need to be able to get the address of this memory location in user mode.
I chose the technology that Cesar Cerrudo mentioned in his paper "Easy local WindowsKernel exploitation" and used the NtQuerySystemInformation (SystemHandleInformation) API to obtain the address of the Windows Token object. This allows us to get the address of the SEP_TOKEN_PRIVILEDGES struct with the embedded token. My idea is to overwrite this struct in the Master Card. Then add a new permission to raise the permission. The advantage is that SMEP can be ignored.
So now let's take a look at the struct SEP_TOKEN_PRIVILEDGES.
The first three regions in the SEP_TOKEN_PRIVILEDGES struct represent bit masks, and each permission is represented by a bit. We are interested in some of the high permissions that can be permitted by the kernel.
The eight NUL In the struct may not be enough. You can try to reduce the permissions as much as possible. We open the handle of the Process Master Card and create a token with the minimum permission.
The result is as follows.
We found that we still cannot collect 8 NUL records. So I used the AdjustTokenPrivileges API function with the DisableAllPrivileges flag parameter to disable all possible permissions.
We can see that this function is successfully called to clear the 64-bit area.
The region can be overwritten, but the written kernel address cannot be controlled.
We can only ensure that the kernel address has two bytes: 0xff. However, the most useful privilege is the first few digits of the Enabled field, so you cannot write it directly. Instead, you can write the PresentField mask to ensure coverage. In this way, the permissions can be improved.
3.3 all steps
For successful exploitation, you need to use ZwAllocateVirtualMemory (address 0 xfffffffb) to forge a Win32k in user mode! The tahWND struct. Fill in the content of this struct as described in 3.1.
Next, create a token with all permissions removed from the Enabled field and use the NtQuerySystemInformation (SystemHandleInformation) API to disclose the kernel address of this token to the SEP_TOKEN_PRIVILEGES struct, in order to point to the middle of the Present field, we add 3 to the address, and store the added address (minus 8) in the constructed win32k! The tagWND struct offset is 0 × 60.
To obtain new permissions, we use the ImpersonateLoggedOnUser API to simulate the security environment of this token and use the privileges, and then use WriteOrocessMemory API token) and CreateRemoteThread to execute it. Finally, we can successfully obtain the System permission.
Slightly deleted from the original text
[This article was contributed by Nirvana and first publishedXI ke lianchuang Network Information Security Forum,Original article address:Http://jodeit.org/research/Exploiting_CVE-2014-4113_on_Windows_8.1.pdf, Reprinted, please indicate from FreeBuf. COM]