In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
Many novices are not very clear about the vulnerability analysis of CVE-2018-8120 in the Windows 7 x64 environment. In order to help you solve this problem, the following editor will explain it in detail. People with this need can come and learn. I hope you can get something.
Background
On May 15, 2018, ESET disclosed two 0-day vulnerabilities in samples of PDF documents it captured. Among them, CVE-2018-4990 is the code execution vulnerability of Adobe PDF reader, and CVE-2018-8120 is the kernel rights enhancement vulnerability of Windows operating system Win32k. After obtaining the code execution rights, it uses the kernel rights vulnerability to bypass the sandboxie protection of Adobe PDF reader to achieve arbitrary code execution.
CVE-2018-4990 Adobe Reader Code execution vulnerability Analysis has been released by threat Intelligence Center on May 25th 2018 (see reference [1] for details). Although the kernel privilege vulnerability has public exploit code, it is only aimed at exploitation in Windows 32-bit environment. Since most user machines are already 64-bit operating systems, the harm of leaked code is limited. Recently, some security researchers uploaded the exploit code for CVE-2018-8120 in Windows 7 64-bit environment on GitHub. After verification and analysis, the exploit code is really available. Considering that the technical details and verification procedures related to the vulnerability have been made public, it is very likely that this vulnerability will be exploited to carry out large-scale attacks.
Loophole analysis
In this paper, we try to analyze the vulnerability principle and exploitation process in detail through the public kernel rights enhancement POC for Windows 7 64-bit environment, and record the whole analysis process. Please forgive me if there is any improper analysis.
Analysis environment: the process of analysis and debugging will take place in an environment based on Windows 7 x64
Sample source: https://github.com/unamer/CVE-2018-8120
Patch comparison
Through the analysis of the security bulletin patch, we can see that this vulnerability mainly fixes the win32k.sys kernel module file in the system. We compare the win32k.sys file in 64-bit Windows 7 with the unpatched file, and find that the following fixes have been made to the NtUserSetImeInfoEx function of win32k.sys:
It is obvious that the patched function code adds a check to whether the value of the member field spklList of the window station object tagWINDOWSTATION is 0. If the value is 0, the function directly returns:
Code before patching:
Patched code:
Details of the vulnerability
According to the above code comparison of the changes before and after the win32k.sys patch, the vulnerability occurs in the function NtUserSetImeInfoEx. NtUserSetImeInfoEx is an interface function provided by the operating system, which is used to set the input method extension information object defined by the user process in the window station associated with the current process.
Window station
The window station is a kernel object associated with the current process and session (session). It contains the clipboard (clipboard), atomic table, one or more desktop (desktop) objects, and so on. The window station tagWINDOWSTATION structure is defined as follows:
Analysis of NtUserSetImeInfoEx execution process
Knowing the fix part of the patch code, let's take a look at the specific implementation of the vulnerability function NtUserSetImeInfoEx, which takes only one parameter of type tagIMEINFOEX:
The execution process of the collated vulnerability function is analyzed as follows:
The l function first gets the current window station rpwinsta and gets the spklList member from the window station object pointed to by rpwinsta
SpklList is a pointer to the header node of the associated keyboard layout tagKL object list. The keyboard layout tagKL structure is defined as follows:
The function then traverses the linked list of keyboard layout objects from the first node until the pklNext member of the node object refers back to the first node object. Function to determine whether the hkl member of each traversed node object is equal to the hkl member of the source input method extended information object pointed to by the parameter ime_info_ex
The next function determines whether the piiex member of the target keyboard layout object is empty and whether the member variable fLoadFlag value is FALSE. If so, copy the data of the parameter ime_info_ex to the piiex member of the target keyboard layout object
The implementation of the function is relatively simple, and here we can clearly see the cause of the vulnerability in step 2 of the analysis process:
When traversing the keyboard layout object linked list spklList, it does not determine whether the spklList address is NULL. Assuming that spklList is empty at this time, an access exception will be triggered when accessing spklList, resulting in the occurrence of system BSOD.
POC verification
We use the PowerShell script to test and verify the vulnerability. The following PowerShell script creates a window station using CreateWindowStation, and calls the function SetProcessWindowStation to associate the created window station with the current process, then prints out the HANDLE of the window station, and finally calls the NtUserSetImeInfoEx function to trigger the vulnerability:
After printing out the window station HANDLE, we use PCHunter to find the kernel address of the window station 0xfffffA801a1c4270:
View the 0xfffffA801a1c4270 address of the window station handle created in WinDbg using the win32k windows tagging structure type:
At this point, we can see that spklList is initialized to empty by default in the created window station. Combined with the above analysis of the NtUserSetImeInfoEx function, we can see that if we continue to call the NtUserSetImeInfoEx function at this time, it will lead to the occurrence of the system BSOD:
Exception code:
Summarize the causes of the vulnerability:
When the user process calls functions such as CreateWindowStation to create a new window station, the kernel will eventually perform the operation created by the window station. During the execution of this function, the spklList member of the new window station object is not initialized and will always point to the NULL address.
However, NtUserSetImeInfoEx does not make a short pointer judgment on the spklList member of the window station object. Because the spklList member of the window station object associated with the current process points to the NULL address, and the zero-page memory where the empty address is located is not mapped at this time, when the kernel function NtUserSetImeInfoEx tries to access zero-page memory, it will trigger an access exception, resulting in the occurrence of BSOD.
Vulnerability exploitation in Windows 7 x64 environment
On May 20, 2018, @ unamer uploaded a royalty code using CVE-2018-8120 for Windows 7, Windows 2008 32-bit and 64-bit systems on github. In this chapter, we use public samples to analyze the exploitation process of this vulnerability in Windows 7 x64 environment.
Allocate zero-page memory
As can be seen from the previous analysis, due to improper code design, when an object pointer in the kernel points to a memory address in the user address space, the utilization code in the user process will be able to realize the ability of arbitrary kernel code execution by allocating such memory pages and ingenious memory layout.
When the vulnerability is triggered, the NtUserSetImeInfoEx function will copy the controllable parameters to the zero address. If you know the distribution of virtual address space, you should know that in 32-bit Windows systems, the total virtual address space available is 2 ^ 32 bytes (4 GB). Usually the low-address 2GB is used for the user space, and the high-address 2GB is used for the system kernel space. In 64-bit Windows systems, the theoretical size of the virtual address space is 2 ^ 64 bytes, but in practice only part of it is used. 8 TB from 0x000'00000000 to 0x7FF'FFFFFFFF is used for user space, and part of the 248TB from 0xFFFF0800'00000000 to 0xFFFFFFFF'FFFFFFFF is used for system space. Notice the null pointer assignment partition, which is the closed interval from 0x00000000 to 0x0000FFFF in the process address space, and is reserved to help programmers capture null pointer assignments. If a thread in the process attempts to read or write to a memory address located in this partition, an access violation exception is thrown:
Virtual address space segment
Using the ZwAllocateVirtualMemory function, you can request a block of memory in the virtual space of the specified process, which will be aligned to the 64kb size by default. When BaseAdress is set to 0, the system looks for the first unused memory block to allocate, and cannot allocate space in zero-page memory. One of the AllocateType parameters has an allocation type of MEM_TOP_DOWN, which means that memory allocation allocates memory from top to bottom. If you specify BaseAddress as a low address, such as 1, and specify that the size of the allocated memory is greater than this value, such as 8192 (a memory page), then the address range after successful allocation is 0xFFFFE001 (- 8191) to 1, including the 0 address. At this time, try to write data to the address executed by the NULL pointer, and the program will not be abnormal. In this way, we find that memory is allocated at a high address (kernel space) as well as at address 0. Please refer to [11] for details.
Bitmap GDI function to read / write any address in the kernel
However, by modifying the key objects of the Bitmap GDI function proposed in recent years, the limited arbitrary address write vulnerabilities can be transformed into kernel arbitrary address read / write. The key to this technique is that when we create a bitmap, we can reveal its address in the kernel. This leak was patched after the v1607 version of Windows10.
When you create a bitmap, a structure is attached to the GdiSharedHandleTable member of the process PEB. GdiSharedHandleTable is a pointer to an array of GDICELL64 structures:
We can find the kernel address of Bitmap in the following ways:
Use WinDbg to verify the entire process:
L first create a Bitmap object with the following PowerShell script, print the kernel object handle, and then use the tool to find the object for later comparison
Print out the Bitmap kernel object handle:
Switching process:
Get the GdiSharedHandleTable address:
Get the address of the Bitmap handle:
You can see that the address fffff900`c1ca6000 is the same as the one obtained by the tool in the image above. The Bitmap kernel address is available, how to use it? The pKernelAddress member of the GDICELL structure points to the BASEOBJECT structure, but our concern is that after this header, there is a specific structure whose type is determined by the wType member:
Bitmap structure:
The pvScan0 member is what we need to make use of, because the two API, GetBitmapBits and SetBitmapBits, can manipulate this member. GetBitmapBits allows us to read any byte on the pvScan0 address, and SetBitmapBits allows us to write any byte on the pvScan0 address. If we have a loophole (for example, CVE-2018-8120) that can change the kernel address once and change the pvScan0 to the kernel address we want to operate, does this enable arbitrary kernel read and write that can be reused?
With this basic knowledge, we sort out the loophole of using this method and writing an arbitrary address to transform GetBitmapBits / SetBitmapBits into a utilization function that can read and write any address. The specific steps are as follows:
L create 2 bitmaps (Manager/Worker)
Use the handle to find GDICELL64 and calculate the pvScan0 address of the two bitmaps respectively
L use the vulnerability to write the WorkerpvScan0 offset address to the pvScan0 value of Manager
L use SetBitmapBits on Manager to select an address
Use GetBitmapBits/ SetBitmapBits on Worker to read / write to the address set in the previous step
The whole utilization operation flow is as follows:
Using Bitmap GDI to realize vulnerability exploitation of CVE-2018-8120 in Windows 7 x64 environment
With all the basics above, let's take a look at how the exploiting program can implement a privilege attack using CVE-2018-8120 in a Windows 7 64-bit environment.
The first step is to use ZwAllocateVirtualMemory to allocate blocks of memory with a base address on the zero page so that the zero page is mapped:
Calling the NtAllocateVirtualMemory function successfully allocates a piece of space above the zero address:
The second step is to create two bitmap (Manager/Worker) objects, and use the CVE-2018-8120 vulnerability to write the WorkerpvScan0 offset address to the pvScan0 value of Manager, and create the read and write capability of any address in the kernel, as follows:
L create two bitmap objects
L divulge their kernel addresses and get two pointers mpv and wpv:
L use arbitrary write to set mpv to point to the address of wpv to achieve reusable kernel arbitrary read and write
First, we need to construct an environment for the function to run to the place where the data is copied below. remember our analysis of the principle of NtUserSetImeInfoEx function vulnerabilities above? The NtUserSetImeInfoEx function traverses the linked list of keyboard layout objects from the first node until the pklNext member of the node object points back to the first node object. It is then determined whether the hkl member of each traversed node object is equal to the hkl member of the source input method extended information object pointed to by the parameter ime_info_ex. In order to trigger subsequent copy operations, we need to skip this loop
To skip this loop, it's easy to make the parameter addresses of the pkl- > hkl and NtUserSetImeInfoEx functions equal. The following code forges a tagIMEINFOEX structure of the same type as the spklList member of the tagKL structure at page zero, and then sets its hkl field to the address of wpv. Later, we put the address of wpv in the first member of the parameter ime_info_ex of the NtUserSetImeInfoEx function. So you don't enter the while (pkl- > hkl! = ime_info_ex) loop:
Then put the address of the mpv at the zero page memory address offset 0x50, and the NtUserSetImeInfoEx function copies its parameters (IMEINFOEX structure) to the input method information object buffer pointed to by the piiex member of the target keyboard layout tagKL object. The offset of this field under win7 x64 is 0x50:
The following are the values of mpv and wpv obtained during debugging:
Then construct the vulnerability exploitation environment, call the CreateWindowStation function to create a window station, call the SetProcessWindowStation function to associate the window station with the current process, and then construct a tagIMEINFOEX structure to put the address of wpv in its hkl member. After calling NtUserSetImeInfoEx, the NtUserSetImeInfoEx function will copy the address of wpv into the mpv:
In the debugger, we can see that the NtUserSetImeInfoEx vulnerability has been successfully triggered:
When the NtUserSetImeInfoEx is executed, the arbitrary read and write environment of our GDI kernel has been constructed:
Note: the length of the copy data triggered by NtUserSetImeInfoEx is uncontrollable, memmove (piiex, & ime_info_ex, 0x160ui64); you can see in the code that it is the length of 0x160, that is, sizeof (tagIMEINFOEX). If we want to modify the pvScan0 address of Worker Bitmap in this place, we will overwrite the other data in the SURFACE structure. The subsequent calls to Gdi32's GetBitmapBits/SetBitmapBits functions will not succeed, because the way these two functions operate on pvScan0 is related to the lDelta, iBitmapFormat, iType, fjBitmap, and flags fields of the SURFOBJ structure. For more information about the structure, please refer to [10].
The following code is the corresponding value of the member that needs to be repaired:
The final step is to use Gdi32's GetBitmapBits/SetBitmapBits API call to read and write the kernel address space for arbitrary code execution:
The following code replaces the NtQueryIntervalProfile function in HalDispatchTable to the address of our weighting ShellCode and calls NtQueryIntervalProfile to execute ShellCode:
Finally, replace the token of the SYSTEM process with the token of the current process in ShellCode to lift the rights:
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.