I'm writing a custom windows authentication package, but the LSA does not load my Dll.
I have the following methods exported via the .def
file
EXTERN_C __declspec(dllexport) NTSTATUS NTAPI SpLsaModeInitialize(
ULONG LsaVersion,
PULONG PackageVersion,
PSECPKG_FUNCTION_TABLE * ppTables,
PULONG pcTables
) {
__LOG_TRACE_FUNC_BEGIN(); // Write a log entry to C:\temp\log.txt
*PackageVersion = SECPKG_INTERFACE_VERSION;
*ppTables = sp_lsa_function_table;
*pcTables = 1;
__LOG_TRACE_FUNC_END(); // Write a log entry to C:\temp\log.txt
return 0;
}
I also have the DllMain
and DllInit
functions.
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
__LOG_TRACE_FUNC_BEGIN(); // Write a log entry to C:\temp\log.txt
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
__LOG_TRACE_FUNC_END(); // Write a log entry to C:\temp\log.txt
return TRUE;
}
BOOLEAN DllInit(IN PVOID DllHandle, IN ULONG Reason, IN PCONTEXT Context OPTIONAL)
{
__LOG_TRACE_FUNC_BEGIN(); // Write a log entry to C:\temp\log.txt
switch (Reason)
{
case DLL_PROCESS_ATTACH:
#if defined (DEBUG)
DebugBreak();
#endif
InitializeCriticalSection(&DllCritSect);
break;
case DLL_PROCESS_DETACH:
EnterCriticalSection(&DllCritSect);
LeaveCriticalSection(&DllCritSect);
DeleteCriticalSection(&DllCritSect);
break;
}
__LOG_TRACE_FUNC_END(); // Write a log entry to C:\temp\log.txt
return TRUE;
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(DllHandle);
}
I have the export definition in dap.def
as below,
EXPORTS
DllMain
DllInit
SpLsaModeInitialize
I also have the dap.dll.manifest
file (even though I'm not sure if it is required. The manifest file was required for another part of the project, a credential provider)
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<dependency>
<dependentAssembly>
<assemblyIdentity
type='win32'
name='Microsoft.VC80.DebugCRT'
version='8.0.50608.0'
processorArchitecture='x64'
publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>
My Dll is compiled for Release/x64
.
I'm signing my Dll (dap.dll) as below (not sure if this step is mandatory)
makecert.exe -sv dap.pvk -n "CN=Dallas" dap.cer -r
pvk2pfx.exe -pvk dap.pvk -spc dap.cer -pfx dap.pfx -po 123
signtool.exe sign /f "dap.pfx" /p 123 "dap.dll"
Then I move my file, dap.dll, into Windows\System32
in the target Windows 10 VM and add the following registry entry.
I've also tried adding the same into the Security Packages
.
Then I restart the VM.
But none of these attempts worked, and my Dll never gets called (I don't see any log entries created.).
Here is my OS info,
My questions are,
- Am I doing everything right? or am I missing any step?
- Does the signing step mandatory, and Am I doing it right?
- When the Local Security Authority process ignores my DLL, does it create any event entries? I tried enabling
%SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-LSA%4Operational.evtx
events, but nothing useful came up. Is there any other place? - Are there any other way to troubleshoot this?
Cheers,
In order to load a custom DLL I needed to change local policies.
In Local Group Policy Editor, navigate to Administrative Templates > System > Local Security Authority.
Enable Allow Custom SSPs and APs to be loaded into LSASS.
Disable Configure LSASS to run as a protected process.
My DLL is NOT signed.
This allowed my DLL to load into LSASS.
This was on a Windows 11 system.