@TOCRotten/Juicy Potato提权原理分析

Rotten/Juicy Potato提权工原理分析

当 DCOM 对象被传递到进程外 COM 服务器时,对象引用被编组在 OBJREF 流中。对于按引用编组,这会导致生成 OBJREF_STANDARD 流,该流为服务器提供足够的信息以定位原始对象并绑定到它。除了对象的标识还有一个 RPC 绑定字符串列表(包含一个 TowerId 和一个字符串)。当发生解组时,通过将塔指定为 NCACN_IP_TCP 和host[port]形式的字符串,这可以被滥用以连接到任意 TCP 端口。当对象解析器尝试绑定 RPC 端口时,它将与指定地址建立 TCP 连接,并且如果需要,将尝试基于安全绑定进行身份验证。

如果我们在绑定中指定 NTLM 身份验证服务,则身份验证将使用基于 NTLM。我们只需要获得一个特权 COM 服务来解组对象,我们可以通过找到一个合适的 DCOM 调用来接受一个对象。但是我们可以通过滥用激活服务来进行一般的编组IStorage 对象并针对任何系统服务(例如 BITS)执行此操作。所以这给我们带来了一个反射的 NTLM 身份验证带来挑战:

  • 使用 NTLM 反射回本地 SMB 服务(根据 WebDAV 版本)
  • 在本地协商 NTLM,它将返回 LocalSystem 的完整模拟级别令牌(即使作为普通用户完成)。可以将其与 SeImpersonatePrivilege 结合起来进行令牌绑架。
  • 将 NTLM 反射回本地 RPC TCP 端点

Rotten Potato原理

**前提条件:**需要具备 SeImpersonate 或者 SeAssignPrimaryToken 权限来调用 ImpersonateSecurityContext API。

本地 DCOM DCE/RPC 连接可以反射回侦听 TCP 套接字,允许访问 LocalSystem 用户的 NTLM 身份验证消息,可以重放到本地 DCOM 激活服务以提升权限。

Rotten Potato 实现过程(BITS 服务 - RPC):

1)调用 API CoGetInstanceFromIStorage 在本地 6666 端口加载 COM 对象“BITS 服务”(通过指定 CLSID),然后通过将端口 6666 与 135(RPC)之间交换数据包,使得(以 SYSTEM 身份运行)BITS 服务向 RPC135 端口进行 NTLM 身份验证。即欺骗NT AUTHORITY\SYSTEM帐户通过 NTLM 向我们控制的 TCP 端点进行身份验证。

备注:CoGetInstanceFromIStorage 会尝试从 “指定的 host:port” 加载 “指定对象“ 的实例(通过 CLSID 指定对象),BITS 的 CLSID 为 {4991d34b-80a1-4291-83b6-3328366b9097}。

2)攻击者通过一系列 Windows API 调用将此身份验证在本地协商NT AUTHORITY\SYSTEM帐户的安全令牌,将 COM 发送的 Negotiate 消息中的 NTLM 部分提取出来,将其转发至 135 端口(RPC);然后将 RPC 返回的 Challenge 替换为本地协商的数据(替换 NTLM Server Challenge 字段 与 Reserved 字段)后发送给 COM;当 COM 收到处理后的 Challenge 消息后,它将在内存中进行后台身份验证,使用上面调用的结果调用 ImpersonateSecurityContext,以获取模拟令牌

备注:调用 AcceptSecurityContext 函数来接收 Negotiate 消息,并发送 Challenge 消息;并将 Authentiate 消息传递给该函数,以完成身份验证;最后,调用 ImpersonateSecurityContext 函数获得访问令牌。

3)最后调用 CreateProcessWithTokenW 或 CreateProcessAsUserW,以令牌拥有的权限开启进程。

NTLM 中继到本地RPC端口

从本地NT AUTHORITY\SYSTEM帐户NTLM 中继到其他一些系统服务一直是 Potato 提权漏洞的主题。 第一步是诱骗 SYSTEM 帐户对我们控制的某些 TCP 侦听器执行身份验证。欺骗 DCOM/RPC 到 NTLM 向我们进行身份验证。 这种更复杂方法的优点是它 100% 可靠,立即触发,而不是必须等待 Windows 更新。

监听COM服务

我们将滥用对 COM 的 API 调用来启动这一切。 调用是CoGetInstanceFromIStorage

public static void BootstrapComMarshal()
{
IStorage stg = ComUtils.CreateStorage();// Use a known local system service COM server, in this cast BITSv1
Guid clsid = new Guid("4991d34b-80a1-4291-83b6-3328366b9097");TestClass c = new TestClass(stg, String.Format("{0}[{1}]", "127.0.0.1", 6666)); // ip and portMULTI_QI[] qis = new MULTI_QI[1];qis[0].pIID = ComUtils.IID_IUnknownPtr;
qis[0].pItf = null;
qis[0].hr = 0;CoGetInstanceFromIStorage(null, ref clsid, null, CLSCTX.CLSCTX_LOCAL_SERVER, c, 1,       qis);
}

CoGetInstanceFromIStorage调用尝试从调用者指定的位置获取指定对象的实例。 这里告诉 COM 我们想要一个 BITS 对象的实例,我们想从 127.0.0.1 端口 6666 加载它。它实际上比这更复杂一点,因为我们实际上是从IStorage对象中获取对象,而不仅仅是直接传递host/port。 在上面的代码中,TestClass实际上是一个IStorage对象的实例,我们替换了其中的一些零碎部分以指向127.0.0.1:6666

中间人中继

已经启动了一个本地 TCP 侦听器, COM 试图在端口 6666 上与我们发起交互。 如果我们以正确的方式回复,可以让 COM(以 SYSTEM 帐户运行)尝试与我们执行 NTLM 身份验证。

COM 使用 RPC 协议与我们交互,将我们在 TCP 端口 6666 上从 COM 接收到的任何数据包中继回 TCP 端口 135 上的本地 Windows RPC 侦听器。 然后,我们可以使用从 TCP 135 上的 Windows RPC 收到的这些数据包作为我们对 COM 回复的模板。

收到的第一个数据包(数据包 #7)是从端口 6666 传入的( COM传来的)。 接下来,将相同的数据包(数据包 #9)中继到 TCP 135 上的 RPC。然后在数据包 #11 中,我们从 RPC(TCP 135)收到回复,在数据包 #13 中,我们将该回复中继到 COM。只需重复此过程,直到进行 NTLM 身份验证。

NTLM 中继和本地令牌协商

本地令牌协商流程

左侧蓝色是 COM 在 TCP 端口 6666 上发送给我们的数据包。右侧红色是我们将使用从这些数据包中提取的数据进行 Windows API 调用。 在API 调用中, 为了使用 NTLM 身份验证在本地协商安全令牌,必须首先调用函数AcquireCredentialsHandle来获取我们需要的数据结构的句柄。接下来,我们调用AcceptSecurityContext,该函数的输入将是 NTLM 类型 1(negotiate)消息。 输出将是 NTLM 类型 2(Challenge)消息,该消息被发送回尝试进行身份验证的客户端,在本例中为 DCOM。当客户端以 NTLM 类型 3(Authenticate)消息响应时,我们然后将其传递给对AcceptSecurityContext的第二次调用以完成身份验证过程并获取令牌。

此过程目的是得到NTLM 类型 2(Challenge)消息,后续步骤将用到该数据。

TYPE 1 (NEGOTIATE) PACKET

在 RPC 和 COM 之间中继几个数据包后,最终 COM 将尝试通过发送 NTLM 类型 1(negotiate)消息来尝试向我们发起 NTLM 身份验证,如下面的数据包捕获的数据包 #29 所示:

同样,我们将其转发给 RPC(在 TCP 135 上),RPC 将回复一个 NTLM Challenge。

此外, 当我们从 COM 收到 NTLM 类型 1(negotiate)消息时,我们截取数据包的 NTLM 部分(如下所示),并使用它开始本地协商令牌的过程:

因此,如上所述,我们调用AcquireCredentialsHandle,然后调用AcceptSecurityContext,将我们从该数据包中提取的 NTLM 类型 1(negotiate)消息作为输入传递。

NTLM TYPE 2 (CHALLENGE) PACKET

TYPE 1 (NEGOTIATE) PACKET我们将 NTLM 类型 1(negotiate)数据包转发到端口 135 上的 RPC,RPC 现在将回复 NTM 类型 2(Challenge)数据包,这可以在上面的数据包 #33 中的数据包捕获中看到。 这一次,不是简单地将这个数据包转发回 COM,我们需要先做一些工作。

捕获的两个 NTLM 类型 2(Challenge)数据包:

请注意突出显示的字段NTLM Server Challenge及其下方的字段Reserved,它们的值不同。 如果简单的将数据包从 RPC(左侧)转发到 COM(右侧),这将没有任何影响。

回想一下,当我们对AcceptSecurityContext进行 Windows API 调用时,该调用的输出是一条 NTLM 类型 2(Challenge)消息。 我们在这里所做的就是:在需要返回给COM 的 NTLM blob中,**用Windows API 调用返回的结果替换RPC返回的NTLM 类型 2(Challenge)。**因为我们需要 COM作为 SYSTEM 帐户运行,使用 NTLM ChallengeReserved部分用来协商本地令牌进行身份验证,如果我们没有替换数据包中的这一部分,那么我们对AcceptSecurityContext的调用将失败。

尝试身份验证的客户端(在本例中为 具有SYSTEM权限的 COM)需要对 NTLM 类型 2(Challenge)数据包的部分NTLM Server ChallengeReserved进行验证,并且只有AcceptSecurityContext调用产生的值,才会获得我们的令牌。

Because we need COM, running as the SYSTEM account to authenticate using the NTLM challenge and “Reserved” section that we are using to negotiate our local token, if we did not replace this section in the packet, then our call to “AcceptSecurityContext” would fail.

We’ll talk more about how local NTLM authentication works later, but for now just know that the client who is trying to authenticate (in this case SYSTEM through COM) needs to do some magic with the “NTLM Server Challenge” and “Reserved” sections of the NTLM Type 2 (Negotiate) packet, and that we’ll only get our token if this magic is performed on the values produced by our call to “AcceptSecurityContext”.

NTLM TYPE 3 (AUTHENTICATE) PACKET

所以现在我们已经将修改后的 NTLM 类型 2(Challenge)数据包转发到 COM,其中ChallengeReserved字段与AcceptSecurityContext的输出相匹配。Reserved字段实际上是一个SecHandle的引用,当SYSTEM账户收到NTLM Type 2消息时,会在内存中进行幕后验证。 这就是为什么我们更新Reserved字段如此重要的原因。否则,它将向 RPC 而不是 US 进行身份验证!

完成此操作后,COM 代表 SYSTEM 帐户将向我们发回 NTLM 类型 3(Authenticate)数据包。 这将是空的(因为这里的所有实际身份验证都发生在内存中),但我们将使用它来对AcceptSecurityContext进行最终调用。

模拟令牌

然后,我们可以使用上述最终调用的结果调用ImpersonateSecurityContext以获取模拟令牌。

如果我们想模拟令牌,我们最好以具有 SeImpersonate 权限(或同等权限)的帐户身份运行。 幸运的是,这包括 Windows 中的许多服务帐户,渗透测试人员最终经常使用这些帐户运行。 例如,IIS 和 SQL Server 帐户。

Juicy Potato(指定服务 - RPC)

Juicy Potato 和 Rotten Potato 原理相似,在其基础上进行上改进,可以选择加载其他的服务(通过指定 CLSID),自定义 COM 监听端口,绑定到任意 IP,以及创建进程的方式等等。

参考:Rotten Potato

Rotten/Juicy Potato提权工原理分析相关推荐

  1. windows提权—烂土豆(RottenPotato)及Juicy Potato提权

    介绍 烂土豆(Rotten Potato) MS16-075 提权是一个本地提权,只针对本地用户,不支持域用户 适用版本:Windows 7.8.10.2008.2012 烂土豆下载地址: https ...

  2. Potato提权小结

    前言 当我们拿到webshell 却苦于无法提权 早之前有巴西烤肉提权,有pr提权 今天 来一个土豆提权合集 妈妈再也不担心我的webshell无法提权了 Hot Potato 前言 利用 Windo ...

  3. Android 的提权 (root) 原理是什么?

    转载自:http://www.zhihu.com/question/21074979 Kevin 赵宏彬.师子越.杨振海  等人赞同 Android的内核就是Linux,所以Android获取root ...

  4. cve-2015-0569 安卓手机提权ROOT漏洞 分析

    测试机器:nexus4       android版本:4.4   内核版本3.4.0  漏洞介绍:函数进行拷贝时没有对长度进行判断,导致用户可以修改内核栈中值. 漏洞利用:通过修改函数返回地址,来进 ...

  5. Android提权漏洞CVE-2014-7920CVE-2014-7921分析

    作者:没羽@阿里移动安全,更多技术干货,请访问阿里聚安全博客 这是Android mediaserver的提权漏洞,利用CVE-2014-7920和CVE-2014-7921实现提权,从0权限提到me ...

  6. Android提权漏洞CVE-2014-7920CVE-2014-7921分析 1

    没羽@阿里移动安全,更多安全类技术干货,请访问阿里聚安全博客 这是Android mediaserver的提权漏洞,利用CVE-2014-7920和CVE-2014-7921实现提权,从0权限提到me ...

  7. 绿盟科技 linux漏洞,绿盟科技发布LINUX内核本地提权漏洞技术分析与防护方案

    Linux内核的内存子系统在处理写时拷贝(Copy-on-Write,缩写为COW)时存在条件竞争漏洞,导致可以破坏私有只读内存映射.一个低权限的本地用户能够利用此漏洞获取其他只读内存映射的写权限,进 ...

  8. 护卫神mysql提权_护卫神主机大师提权漏洞利用分析

    *本文原创作者:Freedom,本文属FreeBuf原创奖励计划,未经许可禁止转载 0x01 前言 护卫神·主机大师支持一键安装网站运行环境(IIS+ASP+ASP.net+PHP5.2-5.6+My ...

  9. Potato家族本地提权分析

    0x00 前言 在实际渗透中,我们用到最多的就是Potato家族的提权.本文着重研究Potato家族的提权原理以及本地提权细节 0x01 原理讲解 1.利用Potato提权的是前提是拥有SeImper ...

最新文章

  1. 磁盘管理第一章(分区与格式化)
  2. python输入一个整数倒序输出_利用Python实现倒序任意整数
  3. http协议状态码和web错误解决总结
  4. DL之LSTM之MvP:基于TF利用LSTM基于DIY时间训练csv文件数据预测后100个数据(多值预测)状态
  5. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1052:计算邮资
  6. Hybris里类似ABAP Netweaver的DDIC - 如何做data type的extension
  7. 垃圾回收机制与引用类型
  8. Ubuntu系统下go语言环境的搭建
  9. 图灵工业机器人说明书_图说人工智能:机器人极简史
  10. java pdf 水印 加密_Java生成PDF 加密 水印
  11. Internet Explorer 包含五个预定义区域
  12. 这一年很幸运,平平淡淡的|2021 年度总结
  13. 第三方支付接口搜集(附下载)
  14. 工作记忆中表征状态的振荡控制
  15. 和在java和c语言中的那些事
  16. 运营技巧|如何把产品运营好?
  17. 查看windows系统默认编码 修改windows系统默认编码
  18. 了解微信小程序、掌握微信小程序开发工具的使用、了解小程序的目录以及文件结构、掌握小程序中常用的组件、掌握WXML、WXSS、WXS的基本使用
  19. 【技术分享】python web 安全总结
  20. android 格式转化,智兔格式转换器

热门文章

  1. 一键卸载大师 v5.1.1
  2. js 编码 php 解码,浅谈php和js中json的编码和解码
  3. JAVA-JDBC: (2) 数据库的粗略的CRUD及SQL注入问题
  4. 数据结构17:什么是递归
  5. win10下MYSQL的下载、安装以及配置超详解教程
  6. prometheus+consul 服务自动发现监控
  7. 硬盘容量和宽带的计算
  8. 从零开始带你玩转单片机----------【第四期】数码管显示
  9. 一路向北,扬鞭策马九龙山
  10. 易中天品三国 - 雨热闲坛