m 文件 dll matlab 中调用_利用USO服务将特权文件写入武器化

James Forshaw发现的DiagHub DLL loading技术已经非常有名了。每当你在Windows或一些第三方软件中发现SYSTEM权限的任意文件写漏洞时,你就可以用这一招来造成任意代码执行,而且不用重启。不幸的是这种方法在Windows 10 build 1903年被微软禁止。Andrea Pierini在Twitter上简单地提到了这一点。在这里,我想和大家分享一下我在最新版本的Windows上寻找DLL劫持弱点时发现的另一种加载dll的方法。

前言

在本文的开头,我想澄清一下:

这不算是一个漏洞。正如我们所看到的,为了能够使用这个技巧,必须先将一个专门制作的DLL植入C:WindowsSystem32文件夹,当然只有 “SYSTEM” 权限的用户才能做到这一点。

写在开始

作为出发点,我决定寻找一些简单的例子,例如在以NT AUTHORITY/System运行的服务中的DLL劫持。我的想法是监控那些可以被普通用户启动或至少是 “影响 “的服务。为此,我做了一个非常简单的PowerShell脚本,每秒钟检查一个服务是否被启动或停止。

8de7163184ffac5499c41e75b190d447.png

在Windows操作系统的后台,运行Process Monitor来记录文件系统操作。我简单地配置了一个过滤器,只显示涉及*.dll文件的操作,如果找不到的话就返回NAME NOT FOUND错误代码。然后,我试着在没有管理员权限的情况下,一次一次地启动所有能启动的服务。不幸的是,我没有用这个方法发现任何东西。不过我发现了以下内容。

当 “Process Monitor “在后台运行时,它捕捉到一些定期打开 “windowscoredeviceinfo.dll “文件的操作。频率不一,可能每小时发生一次,也可能每30分钟发生一次。事件的属性显示了该进程的命令行。通过查看事件的属性能够发现这个操作是由命令行”C:WINDOWS/System32/svchost.exe -k utcsvc -p”造成的。

知道了这一点,就可以很容易地通过以下PowerShell命令找到相应的服务,例如。在这种情况下,可以用DiagTrack命令。

注:我也可以使用进程的PID,例如在任务管理器中查找它。这种方法的缺点是,你不知道它什么时候启动,在你检查的时候,进程可能并不在运行。

我们的第一个目标

“Process Monitor “中的事件属性显示了一些关于DLL如何被加载的信息。Stack选项卡显示了导致这次操作的调用列表。在这里,我们可以看到,初始调用是从diagtrack.dll进行的。DiagTrack服务加载了FlightSettings.dll文件,它又使用了dcntel.dll中的GetCensusRegistryLocation()方法,最后,使用标准的LoadLibraryEx()WinApi调用加载了windowscoredeviceinfo.dll。

4f077e0f8dd2a615cbab757aeedd0dbe.png

为了确定我的方向是正确的,我在IDA中打开最后一个DLL,并查找windowscoredeviceinfo.dll的出现。Strings标签页中能够清楚的找到这个dll的名字。

注意:你必须配置视图以包含unicode字符串,这不是IDA的默认设置……。

b2a72bb20b8189089a8ddd901538d79f.png

然后,我们可以直接到它在.rdata部分的位置,寻找Xrefs。在这种情况下,只有一个。这个字符串确实是在QueryWCOSDeviceInformation()方法中使用的。好吧,说明我们的路线是对的!

9d4b76a1997cd6978f1625f77cfcc7f2.png

IDA生成的伪代码非常清晰。我们发现前面看到的Process Monitor的LoadLibraryEx("windowscoredeviceinfo.dll")调用。然后,如果库被成功加载,就会进行下面的调用。GetProcAddress("QueryDeviceInformation"),也就是说这个函数应该是windowscoredeviceinfo.dll的导出函数。

9bc3bca27b8225067d35b70c367be19d.png

我们来总结一下情况。目前,我们知道以下几点。

  • DiagTrack服务定期(每30分钟或每小时)运行一个未知任务。
  • 每次,它都会尝试加载一个名为 “windowscoredeviceinfo.dll “的DLL,而这个DLL默认情况下并不存在。
  • 如果成功加载,则导入 “QueryDeviceInformation “函数。

这是一个好的开始,但我缺少一些关键要素。例如,我不知道这个 “任务 “是如何运行的。我甚至不知道作为一个普通用户是否能够触发它。所以,与其在不知道自己在寻找什么的情况下就开始对服务进行逆向工程,我决定创建一个PoC DLL,并验证我是否真的能以NT AUTHORITYSystem的方式获得任意代码执行。

制作一个PoC DLL

这个PoC DLL的目标非常简单。我想记录一些关于加载它的进程的关键信息命令行当前用户名PIDPPID。所有这些都会被记录到C:tempdll.log中。

首先,我想出了以下代码。TrackCall()函数负责收集和记录信息。它会被DllMain()和QueryDeviceInformation()执行,用来跟踪它的调用者。

#include #include #include  // UNLEN + GetUserName#include  // CreateToolhelp32Snapshot()int TrackCall(const wchar_t * callingFrom){    WCHAR strSt[4096], strUsername[UNLEN + 1];    WCHAR * strComandLine;    SYSTEMTIME st;    HANDLE hFile, hToolhelpSnapshot;    PROCESSENTRY32 stProcessEntry;    DWORD dwPcbBuffer = UNLEN, dwBytesWritten, dwProcessId, dwParentProcessId;    BOOL bResult;    strComandLine = GetCommandLine(); // Get Command line of the current process     bResult = GetUserName(strUsername, &dwPcbBuffer); // Get current user name     dwProcessId = GetCurrentProcessId(); // Get PID    // Get PPID     hToolhelpSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);    stProcessEntry = { 0 };    stProcessEntry.dwSize = sizeof(PROCESSENTRY32);    dwParentProcessId = 0;    if (Process32First(hToolhelpSnapshot, &stProcessEntry)) {        do {            if (stProcessEntry.th32ProcessID == dwProcessId) {                dwParentProcessId = stProcessEntry.th32ParentProcessID;                break;            }        } while (Process32Next(hToolhelpSnapshot, &stProcessEntry));    }    CloseHandle(hToolhelpSnapshot);    // Create log entry     GetLocalTime(&st);     wsprintfW(strSt, L"[%.2u:%.2u:%.2u] - PID=%d - PPID=%d - USER='%s' - CMD='%s' - METHOD='%s'n", st.wHour, st.wMinute, st.wSecond, dwProcessId, dwParentProcessId, strUsername, strComandLine, callingFrom);    // Save to log file     hFile = CreateFile(L"C:Tempdll.log", FILE_APPEND_DATA, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);     if (hFile != INVALID_HANDLE_VALUE)        bResult = WriteFile(hFile, strSt, lstrlenW(strSt)*sizeof(WCHAR), &dwBytesWritten, NULL);    CloseHandle(hFile);    return S_OK;}HRESULT __stdcall QueryDeviceInformation(){    TrackCall(L"QueryDeviceInformation()");    return S_OK;}BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){    switch (ul_reason_for_call)    {    case DLL_PROCESS_ATTACH:        TrackCall(L"DllMain()");        break;    case DLL_THREAD_ATTACH:    case DLL_THREAD_DETACH:    case DLL_PROCESS_DETACH:        break;    }    return TRUE;}

然后,作为管理员,我把这个DLL复制到C:/Windows/System32,然后,等待它被调用…

9ddcc5018f0dc923b2a9ddd2cef8da7e.png

过了一会儿,windowscoredeviceinfo.dll的调用终于出现在Process Monitor中。所有的CreateFile操作都成功返回。但是,在C:temp中没有创建日志文件的迹象。当然,这意味着DLL没有被正确加载,问题是:为什么?我猜测,我创建的DLL没有导出进程所需的所有函数。

15cbc3b22e81ab2d56114a614a3b26cd.png

此时,我不知道该如何继续,但是,当我回到Process Monitor时,我看到了一些以前没有看到的事件。

文件windowscoredeviceinfo.dll也被一个名为usocoreworker.exe的进程加载,这个进程的权限为NT AUTHORITY/System。这时,一些信息被记录到C:Tempdll.log中,这说明代码此时已经正确执行了。

这看起来更有希望,所以我决定抛开DiagTrack服务,看看这个新目标。

转移到新目标

我们又回到了起点。我们需要找出usocoreworker.exe进程是如何创建的。为此,我们可以寻找与写入日志文件的PPID对应的进程。根据任务管理器,它是svchost.exe的一个实例,就像大多数Windows服务一样,所以PPID对我们的帮助不大。

1b15a2893aa815c7229b2618dbc40350.png

对应的服务是 BrokerInfrastructure,它的描述是 “处理后台任务”。好吧,这也没什么用……。

3a3f9f77ae78ef81dc90fc81e152e177.png

让我们来看看我们可以从Process Monitor 中找到什么。访问与这个进程相关的事件的属性,然后,进入Stack选项卡,会显示以下内容。我们可以看到,有很多对rpcrt4.dll和combase.dll的引用。这可能意味着这个进程是由一个COM相关的RPC调用触发的。如果是这样的话,根据远程对象和接口的权限,也可以作为普通用户触发。

。COM用于进程间通信(IPC)。因此,它可以为低权限的进程提供运行高权限操作的能力。

从二进制文件的属性来看,我们可以看到如下描述:USO Core Worker Process。

aa20990ec729aaa5556c8d521ec94f0c.png

根据前几个要素,我试图在谷歌上找到更多信息。第一个结果把我引向answsers.microsoft.com上的一个帖子。根据其中一条信息,我发现这个文件与 “Update Orchestrator Service “有关。

细细研究,我发现了这个非常有趣的关于 “USO客户端 “的非官方文档。首先,我们了解到 “USO “是 “Update Session Orchestrator “的缩写。

我们还了解到,”USO客户端”(usoclient.exe)是取代 “WUAUCLT “的工具,而WUAUCLT在以前的Windows版本中是用来管理Windows更新的。事实上,这个工具已经被Windows系统管理员所熟知,因为虽然它不被微软官方支持,但它能让他们自动完成更新管理过程。

注:他们甚至引用了TechNet上微软员工的回复,其中说你不应该直接运行这个工具。这越来越有趣了。我们喜欢做我们不应该做的事情,不是吗?

文档中列出了所有你可以使用的选项。所以,我试着玩玩usoclient命令,看看是否能触发我之前观察到的相同行为。从StartScan开始,根据描述,它会触发一个简单地获取可用更新的检查。

我像往常一样在后台运行 Process Monitor,运行命令,成了。

结论

通过一个简单的命令,我们能够让Update Orchestrator服务以NT AUTHORITY/System的方式运行任意代码。这种方法的另一个好处是,我们可以在DllMain之外运行我们的代码(即在加载器锁之外)。

注意:根据微软的说法,应避免在DllMain中运行代码,因为它可能会导致应用程序死锁。更多信息查看这里。

然而,这种技术也有一些缺点。

  • 这需要你能够控制一个特权文件创建或移动的操作。
  • 导致ACL覆盖的漏洞等。
  • 作为一个普通用户,我们不知道DLL是否已经成功加载。

依赖于usoclient工具而不了解其工作原理也是我不喜欢这种技术的地方。所以,我对客户端和服务进行了逆向工程,以便制作一个可以在未来项目中重复使用的开源工具。UsoDllLoader。我将在本文的第二部分尝试解释这个过程。敬请期待

Links & Resources

  • Windows开发技巧。利用任意文件写入来提升本地的权限。
    https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html
    https://googleprojectzero.blogspot.com/2018/04/windows-exploitation-tricks-exploiting.html
  • Twitter – MS终于修复了Win 10 1903的 “Diag Hub Collector “漏洞。
    https://twitter.com/decoder_it/status/1131247394031579138
    https://twitter.com/decoder_it/status/1131247394031579138
  • 非官方的USO客户文件
    https://www.urtech.ca/2018/11/usoclient-documentation-switches/
    https://www.urtech.ca/2018/11/usoclient-documentation-switches/
  • 关于 “USO客户端 “工具的主题,在TechNet上。
    https://social.technet.microsoft.com/Forums/en-US/7619f7fa-ffc1-433b-a885-12e26f9762bf/usoclientexe-usage?forum=win10itprogeneral
    https://social.technet.microsoft.com/Forums/en-US/7619f7fa-ffc1-433b-a885-12e26f9762bf/usoclientexe-usage?forum=win10itprogeneral
  • 动态链接库最佳实践
    https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
    https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices

本文翻译自 itm4n.github.io, 原文链接 。如若转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值