The attached proof-of-concept (PoC) demonstrates a use-after-free (UAF) condition with printer device contexts. The PoC will trigger on Windows 7 32-bit with Special Pool enabled.
The attached testcase crashes Win 7 with Special Pool on win32k while accessing freed memory in bGetRealizedBrush.
This proof of concept triggers a wild write on Win 7 32-bit with Special Pool enabled on win32k.sys.
Using a series of calls, an attacker is able to free the bitmap object, while a reference to this object still exists in the trigger process after killing the first notepad process. At this time, the attacker is able to replace the freed object in memory. However, another free is triggered when quitting the trigger process, which will decrement the reference counter on the freed or replaced object, either modifying heap metadata or freeing the object which was allocated in the place of the original bitmap object.
The trigger creates a new window station which is freed during the process clean up. Through the clipboard operations the window's last reference is hold by the clipboard which is freed during the clean up of the window station object. This will also result in destroying the window object at a time where _gptiCurrent (threadinfo) is already set to null. This is used in xxxDestroyWindow in multiple locations. Depending on the window type it is potentially possible to trigger different kinds of crashes, this one demonstrates a write to a chosen memory location.
trigger.cpp is a proof of concept code which can be used to exploit a buffer overflow vulnerability in Win7 32-bit. The PoC must be compiled in release mode and may need to be run a few times to trigger the crash.
Creating a device context with the flag (DCX_NORESETATTRS) and selecting a brush object into the device context will result in the brush being freed on process exit without the reference to the object being cleared. The PoC consists of two files (prime304.cpp and poc304.cpp). poc304 will execute prime304, which triggers the issue and allows poc304 to retrieve a handle to the device context with the pointer to the freed object. We can confirm this by requesting the handle for the brush object from the device context, resulting in reading freed memory. In some cases the issue leads to memory corruption when for example another object is allocated into the space of the free brush object (see attached crash logs for examples).
This issue is a null pointer issue affecting 32-bit Windows versions. The offset is from adding onto another offset which isn't quite zero, so it is not 100% certain that it is just a null pointer. However, it was not possible to influence the values. A proof of concept is available which sets EIP to 0xdeadbeef.
The PoC triggers a pool buffer overflow in win32k!vSolidFillRect. When using Special Pool we get the crash immediately on the overwrite. Without Special Pool we often get a crash in the same function, but sometimes it crashes in a different function (similar to another issue, however with a different offset). This might be a result of the memory corruption or an out-of-memory condition before the overflow is triggered.
The PoC triggers a crashes due to a pool buffer overflow while drawing the caption bar of window. The trigger depends on the current window layout and resolution. A bruteforce Python script is also attached which should trigger a crash fairly quickly.