欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

RPC漏洞挖掘案例研究(上)

来源:本站整理 作者:佚名 时间:2018-12-28 TAG: 我要投稿

2018年8月底,一名自称“沙盒逃脱者”(SandboxEscaper)的女性研究人员发布了一个Windows本地权限升级0 day漏洞。另外,还附上一个概念性验证攻击程序,允许黑客读取系统中未经授权的区域,不过目前她的GitHub帐号已被封了。这是因为从该漏洞被公开发布到攻击者使用这一漏洞进行攻击,不到两周的时间,这让网络安全机构根本来不及应对。
安全研究人员相信,了解这种漏洞攻击的运行原理将极大的帮助他们找到类似SandboxEscaper在Windows任务计划程序(Windows Task Scheduler)中发现的漏洞。在这篇文章中,我们将讨论通过SandboxEscaper通过滥用RPC服务器上的符号链接来发现权限升级漏洞的方法。
继今年8月及10月之后, SandboxEscaper在12月又第三次公开披露了Windows的0 day漏洞了,尽管前两次都招致批评,且本月她还收到Google的警告通知,指出她已被FBI盯上,但SandboxEscaper似乎不为所动,依然不理会安全社群的“责任披露”原则,持续直接对外公开披露安全漏洞。
原来,Windows任务计划程序在其通过RPC服务器公开的远程过程调用(RPC)应用程序编程接口(API)中存在漏洞。事实上,大多数RPC服务器由运行本地系统权限的系统进程托管,并且允许具有较低权限的RPC客户端与它们交互。与其他软件一样,这些RPC服务器可能容易受到拒绝服务、内存损坏和逻辑漏洞等软件漏洞的影响。换句话说,攻击者可以利用RPC服务器中可能存在的任何漏洞发起攻击。
0 day漏洞如此迅速流行的原因之一是潜在的漏洞非常容易被利用,它是由程序逻辑漏洞引起的,只要使用正确的工具和技术,程序逻辑漏洞就很容易被发现。这种特殊类型的权限升级漏洞通常使用伪符号链接来升级文件或文件夹,进而导致普通用户的权限升级。对于感兴趣的人,网上有有大量关于符号链接攻击的资源。
如何在动态条件和静态条件下发现RPC服务器的漏洞
对于研究人员来说,在进行一个新的研究主题时,都会查看一下是否有可用的开源工具。幸运的是,Microsoft RPC是一个众所周知的协议,在过去的几十年中,研究人员对它进行了很好的逆向工程。比如,研究人员已经开源了一个名为RpcView的工具,它是识别运行在Windows操作系统上的RPC服务的一个非常方便的工具。这绝对是我最喜欢的RPC工具之一,具有许多高效实用的功能,例如搜索RPC接口通用惟一标识符(UUID)、RPC接口名称等。
但是,我们本文的目的不是将所有RPC信息反编译并导出到文本文件中。幸运的是,在阅读源代码时,我们发现其中已经包含了我们需要的功能,但是默认情况下它不会被启用,只能在调试模式下使用特定的命令行参数被触发。由于此限制,我们在启用该功能时,会将现有的DecompileAllInterfaces函数调整为RpcView GUI。如果你对使用这个功能感兴趣,可以在Github存储库中使用我们自定义的RpcView工具。我们现在可以在下一节中讨论“反编译所有接口” 功能的好处时,详细谈到。

RpcView会反编译所有接口
在分析RPC服务器的行为时,我们总是通过RPC接口调用API。通过RPC客户端向服务器发送RPC请求,然后使用SysInternals中的Process Monitor工具观察其行为,进而实现与感兴趣的RPC服务器的这种交互。在我看来,最方便的方法是通过脚本而不是重新编写需要程序编译的C / C ++ RPC客户端,编写很费时间。
本文,我们将使用的是PythonForWindows工具。它以Python化的方式提供了一些Windows功能的抽象,这在很大程度上依赖于Python的ctypes 模块。它还包含一个RPC库,该库提供了一些方便的包装函数,节省了我们编写RPC客户端时的时间。例如,典型的RPC客户端二进制文件需要定义接口定义语言,你需要手动实现绑定操作,这通常涉及一些c++代码,具体的请参见下面的代码段1和代码段2,它们演示了如何使用最少的漏洞处理代码编写RPC客户端脚本和编程之间的差异。
import sys
import ctypes
import windows.rpc
import windows.generated_def as gdef
from windows.rpc import ndr
StorSvc_UUID = r"BE7F785E-0E3A-4AB7-91DE-7E46E443BE29"
class SvcSetStorageSettingsParameters(ndr.NdrParameters):
MEMBERS = [ndr.NdrShort, ndr.NdrLong, ndr.NdrShort, ndr.NdrLong]
def SvcSetStorageSettings():
print "[+] Connecting...."
client = windows.rpc.find_alpc_endpoint_and_connect(StorSvc_UUID, (0,0))
print "[+] Binding...."
iid = client.bind(StorSvc_UUID, (0,0))
params = SvcSetStorageSettingsParameters.pack([0, 1, 2, 0x77])
print "[+] Calling SvcSetStorageSettings"
result = client.call(iid, 0xb, params)
if len(str(result)) > 0:
print " [*] Call executed successfully!"
stream = ndr.NdrStream(result)
res = ndr.NdrLong.unpack(stream)
if res == 0:
print " [*] Success"
else:
print " [*] Failed"
if __name__ == "__main__":
SvcSetStorageSettings()
代码段1:使用PythonForWindows RPC客户端的SvcSetStorageSettings
RPC_STATUS CreateBindingHandle(RPC_BINDING_HANDLE *binding_handle)
{
RPC_STATUS status;
RPC_BINDING_HANDLE v5;
RPC_SECURITY_QOS SecurityQOS = {};
RPC_WSTR StringBinding = nullptr;
RPC_BINDING_HANDLE Binding;
StringBinding = 0;
Binding = 0;
status = RpcStringBindingComposeW(L"BE7F785E-0E3A-4AB7-91DE-7E46E443BE29", L"ncalrpc", nullptr, nullptr, nullptr, &StringBinding);
if (status == RPC_S_OK)
{
status = RpcBindingFromStringBindingW(StringBinding, &Binding);
RpcStringFreeW(&StringBinding);
if (!status)
{
SecurityQOS.Version = 1;

[1] [2] [3] [4] [5]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载