- The application registers a window class to System, which defines the window’s style and behavior. The most important property of window class is window procedure which defines the window ‘s behavior when there's an incoming message. The window procedure is provided by the application.
- The application then calls the API CreateWindow/CreateWindowEx with the window class to create the window. These APIs will switch to kernel mode to call service routine NtUserCreateWindowEx. NtUserCreateWindowEx is complicated function and does the real job of creating the window in Windows system. During the function execution, it will switch to user mode many times to call many functions that exist in user mode. These function do jobs which is fit to run in the user mode (example: to load an image, etc.).
Figure 1. The window creation process (click the image to enlarge)In the process shown above, the application's window procedure will be executed in the user mode in the most cases (as seen in steps 7 an 9), because the window object doesn’t set the state flag to “Server Side Window Proc”. However, this process has a vulnerability: In step 4, the progress will switch to user mode to call a user mode function. The user mode function address is identified by a process environment block (PEB), which can be accessed from user mode application. The attacker can take advantage of this by replacing the user mode function with a malicious one. The attacker will use this opportunity to call the SetWindowLongPtr API. Why call this API? If the parameter is “DefWindowProc”, the window object will set the flag to “Server Side Window Proc”. This means that when the window receives an incoming message, the application ‘s window procedure will execute in kernel mode. The progress is as following (flag the red color for change):
Figure 2. The window creation process with the exploitation flow (click the image to englarge)
The attack flow above will result to the application‘s window procedure to run in the kernel mode, and consequently, the attacker's code as well. From an attacker's side this is easy to execute -- all they will need to do is call the right API and set the right flag and they'll be to run code in kernel mode.
As mentioned earlier, because CVE-2015-1701 is a local privilege escalation vulnerability, attackers first needed access to the system (often by way of another vulnerability) before they can exploit this vulnerability. In the attack we mentioned where it was used, the threat actors exploited CVE-2015-3043 so that they can deliver the final payload—an exploit for CVE-2015-1701—which allowed them to take complete control over the affected system. We think that we will see this kind of trend in targeted attacks more and more -- attackers exploiting more than vulnerability to be able to circumvent defense strategies set up by their victims.
Right now this vulnerability exists in Windows 7 only. We strongly advise users to update their systems with the security patch provided by Microsoft as soon as possible.