BOOL MakeKnownDllsReadOnly()

in PPLGuardDll/dllexploit.cpp [327:439]


BOOL MakeKnownDllsReadOnly(LPCWSTR pKnownDlls)
{
    BOOL bReturnValue = FALSE;

    NTSTATUS status = 0;
    HANDLE hKnownDlls = NULL;
    UNICODE_STRING name = { 0 };
    OBJECT_ATTRIBUTES oa = { 0 };

    PSECURITY_DESCRIPTOR pOriginalSd = NULL;
    DWORD dwBytesNeeded = 0;
    LPWSTR pOriginalSdString = NULL;
    std::wstring newSdString;

    PSECURITY_DESCRIPTOR pNewSd = NULL;
    DWORD newSdLength = 0;
    
    RtlInitUnicodeString(&name, pKnownDlls);
    InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, nullptr, nullptr);

    //
    // Open \KnownDlls with the ability to RW the DACL
    //
    status = NtOpenDirectoryObject(&hKnownDlls, READ_CONTROL | WRITE_DAC, &oa);
    SetLastError(RtlNtStatusToDosError(status));
    if (status != 0)
    {
        LogLastError(L"NtOpenSymbolicLinkObject");
        goto end;
    }

    if (g_bDebug)
        LogToConsole(L"NtOpenSymbolicLinkObject('%ws', WRITE_DAC) OK\n", pKnownDlls);

    //
    // Retrieve DACL
    //
    (void)GetKernelObjectSecurity(hKnownDlls, DACL_SECURITY_INFORMATION, NULL, 0, &dwBytesNeeded);
    if (0 == dwBytesNeeded)
    {
        LogLastError(L"GetKernelObjectSecurity");
        goto end;
    }
    
    pOriginalSd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwBytesNeeded);
    if (!pOriginalSd)
    {
        LogLastError(L"GetKernelObjectSecurity allocate SD");
        goto end;
    }

    if (!GetKernelObjectSecurity(hKnownDlls, DACL_SECURITY_INFORMATION, pOriginalSd, dwBytesNeeded, &dwBytesNeeded))
    {
        LogLastError(L"GetKernelObjectSecurity");
        goto end;
    }

    //
    // Structure -> string to avoid ugly APIs
    //
    if (!ConvertSecurityDescriptorToStringSecurityDescriptorW(pOriginalSd, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, &pOriginalSdString, NULL))
    {
        LogLastError(L"ConvertSecurityDescriptorToStringSecurityDescriptorW");
        goto end;
    }

    //
    // Deny GENERIC_WRITE access to EVERYONE
    //
    newSdString = L"D:(D;OICI;GW;;;WD)";
    newSdString += (pOriginalSdString + 2);

    if (g_bDebug)
    {
        LogToConsole(L"Original SD: %s\n", pOriginalSdString);
        LogToConsole(L"New SD: %s\n", newSdString.c_str());
    }

    //
    // Convert back to structure
    //
    if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(newSdString.c_str(), SDDL_REVISION_1, &pNewSd, &newSdLength))
    {
        LogLastError(L"ConvertStringSecurityDescriptorToSecurityDescriptorW");
        goto end;
    }

    //
    // Apply the new Security Descriptor.
    //
    if (!SetKernelObjectSecurity(hKnownDlls, DACL_SECURITY_INFORMATION, pNewSd))
    {
        LogLastError(L"SetKernelObjectSecurity");
        goto end;
    }

    if (g_bDebug)
        LogToConsole(L"SetKernelObjectSecurity OK\n");

    bReturnValue = TRUE;

end:
    if (hKnownDlls)
        NtClose(hKnownDlls);
    if (pOriginalSd)
        LocalFree(pOriginalSd);
    if (pOriginalSdString)
        LocalFree(pOriginalSdString);
    if (pNewSd)
        LocalFree(pNewSd);

    return bReturnValue;
}