揭秘 Cobalt Strike 的make_token命令

admin 2024年9月9日14:21:06评论39 views字数 5536阅读18分27秒阅读模式
免责声明
由于传播、利用本公众号红云谈安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号红云谈安全及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!请在授权的站点测试,遵守网络安全法!仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责!

介绍

如果你是一名渗透测试人员并且喜欢摆弄 Windows,那么你可能读过 Raphael Mudge 的以下帖子:

  • Windows 访问令牌和备用凭据

在这篇文章中,他解释了 Windows 程序runas 的工作原理,以及**netonly标志如何允许创建本地标识与网络标识不同的进程(本地标识保持不变,而网络标识由 runas 使用的凭据表示)。

Cobalt Strike 提供了make_token命令来实现与**runas /netonly类似的结果。

揭秘 Cobalt Strike 的make_token命令
img

如果您熟悉此命令,那么您可能遇到过 Beacon 创建的进程无法正确“继承”新令牌的情况。此命令的内部工作原理相当模糊,在 Google 上搜索“make_token cobalt strike”之类的内容并不能提供太多有价值的信息(事实上,分析其他框架(如Sliver或Covenant )的实现更有用)。

揭秘 Cobalt Strike 的make_token命令
图 2-make_token 文档

在 Raphael Mudge 的视频《高级威胁战术(6/9):横向移动》中,我们可以通过以下语句获得有关命令的更多详细信息:

“如果你处于特权环境中,则可以使用 Beacon 中的 make_token 创建带有凭证的访问令牌”

“make_token 和 steal_token 的问题在于,它要求你处于管理员环境中,然后才能使用该令牌执行任何操作”

尽管描述中没有提到,但 Raphael 指出make_token需要管理上下文。但是,如果我们继续以非特权用户身份使用该命令……它就可以正常工作!我们这里遗漏了什么?

揭秘 Cobalt Strike 的make_token命令
图 3-来自非特权会话的 make_token

这篇文章旨在进一步阐明make_token命令的工作原理及其功能和局限性。这些信息在您想要通过其他用户的凭证冒充其他用户以枚举或横向移动到远程系统的情况下非常有用。

值得注意的是,尽管我们讨论的是 Cobalt Strike,但这些知识完全适用于任何现代 C2 框架。事实上,出于本文的目的,我们利用了 Meterpreter 没有make_token模块这一事实,自己实现了它。

新的post/windows/manage/make_token模块的示例如下所示:

揭秘 Cobalt Strike 的make_token命令
图4-Meterpreter make_token模块

您可以在以下链接中找到有关我们实施的更多信息:

  • Pr #18022 – 将 update_token 添加到 MSF + make_token post-ex 模块
  • PR #648 – 将 update_token 函数添加到 stdapi
  • Metasploit 每周总结 15

Windows 身份验证理论

让我们先了解一些有关 Windows 身份验证的理论。这将有助于理解make_token 的工作原理并解决简介中提出的问题。

本地安全上下文 网络安全上下文?

让我们考虑这样一个场景:我们的用户是capsule.corpyamcha,我们想要与只有capsule.corpbulma 可以访问的远程系统进行交互。在此示例中,我们有 Bulma 的密码,但该帐户受到当前系统中的拒绝登录策略的影响。

如果我们尝试使用 Bulma 的凭据以runas方式运行 cmd.exe 进程,结果将是这样的:

揭秘 Cobalt Strike 的make_token命令
图 5 - 由于拒绝登录策略,runas 失败

netonly标志适用于这些场景。使用此标志,我们可以创建一个进程,在本地级别我们仍然是 Yamcha,而在网络级别我们变成 Bulma,从而允许我们与远程系统进行交互。

揭秘 Cobalt Strike 的make_token命令
图 6 - runas netonly 工作

在此示例中,Yamcha 和 Vegeta 是来自同一域的用户,我们可以使用netonly标志绕过拒绝登录策略。当您拥有来自远程系统的本地用户或来自不受信任域的域用户的凭据时,此标志也非常方便。

这里需要理解的基本知识是, Windows 不会验证您为runas /netonly指定的凭据,它只会确保在进程与网络交互时使用这些凭据。这就是为什么我们可以使用runas /netonly绕过拒绝登录策略,并使用属于我们当前系统之外的用户或来自不受信任域的凭据。

现在... ***runas***如何设法创建一个进程,其中我们在本地系统中是一个身份,而在网络中是另一个身份?

如果我们提取程序的字符串,我们将看到CreateProcessWithLogonW的存在。

$ strings runas.exe | grep -i createprocess 
CreateProcessAsUserW 
CreateProcessWithLogonW

对该函数进行简单查找表明,runas可能正在使用它来创建一个新进程,并使用指定的凭据作为参数。

揭秘 Cobalt Strike 的make_token命令
图 7-CreateProcessWithLogonW

阅读文档后,我们会发现一个LOGON_NETCREDENTIALS_ONLY标志,它允许以类似于**netonly的方式创建进程。我们可以放心地假设,当我们指定*/netonly时,* runas会使用此标志。

揭秘 Cobalt Strike 的make_token命令
图 8-Netonly 标志

Win32 API 提供了另一个与CreateProcessWithLogonW非常相似的函数,但没有进程创建逻辑。这个函数叫做LogonUserA

揭秘 Cobalt Strike 的make_token命令
图 9 - LogonUserA

LogonUserA仅负责根据给定的凭据创建新的安全上下文。这是make_token利用的函数,通常与**LOGON32_LOGON_NEW_CREDENTIALS登录类型一起使用,以创建仅限网络的安全上下文(我们可以在开源 C2 框架的实现中看到这一点)。

揭秘 Cobalt Strike 的make_token命令
图 10-Netonly 标志

要了解如何创建具有两个不同“身份”(本地/网络)的进程,熟悉 Windows 身份验证的两个重要组件是至关重要的:登录会话访问令牌

登录会话访问令牌

当用户向 Windows 系统进行身份验证时,会发生与下图类似的过程。在高级别上,用户的凭据由适当的身份验证包(通常是 Kerberos 或 NTLM)进行验证。然后使用唯一标识符创建一个新的登录会话,并将该标识符连同有关用户的信息一起发送到本地安全机构 (LSA) 组件。最后,LSA 使用此信息为用户创建访问令牌。

揭秘 Cobalt Strike 的make_token命令
图 11 - Windows 身份验证流程

关于访问令牌,它们是表示帐户的本地安全上下文的对象,并且始终与系统的进程或线程相关联。这些对象包含有关用户的信息,例如其安全标识符、权限或他们所属的组。Windows 根据访问令牌提供的信息和目标对象的自主访问控制列表 (DACL) 中配置的规则执行访问控制决策。

下面显示了一个示例,其中两个进程(一个来自 Attl4s,另一个来自 Wint3r)尝试读取“passwords.txt”文件。可以看出,Attl4s 进程能够读取文件,因为第二条规则(Attl4s 是管理员成员),而 Wint3r 进程因第一条规则(Wint3r 具有标识符 1004)而被拒绝访问。

揭秘 Cobalt Strike 的make_token命令
图 12 - Windows 访问控制

关于登录会话,其重要性源于这样一个事实:如果身份验证导致缓存凭据,则它们将与登录会话相关联。缓存凭据的目的是使 Windows 能够提供单点登录 (SSO) 体验,用户在访问远程服务(例如网络上的共享文件夹)时无需重新输入其凭据。

有趣的是,当 Mimikatz 从 Windows 身份验证包(例如sekurlsa::logonpasswords)转储凭据时,它会遍历系统中的所有登录会话以提取其信息。

下图说明了进程、令牌、登录会话和缓存凭据之间的关系:

揭秘 Cobalt Strike 的make_token命令
图 13 - 进程、线程、令牌、登录会话和缓存凭据之间的关系

关键要点如下:

  • 访问令牌代表经过身份验证的用户的本地安全上下文。本地系统使用这些对象中的信息来做出访问控制决策
  • 具有缓存凭据的登录会话代表经过身份验证的用户的网络安全上下文。当用户想要访问支持 Windows 身份验证的远程服务时,Windows 会自动且透明地使用这些凭据

runas /netonlymake_token在后台执行的操作是创建一个类似于当前用户 (Yamcha) 的访问令牌以及一个包含备用用户 (Bulma) 凭据的登录会话。这可以实现双重身份行为,即本地身份保持不变,而网络身份更改为备用用户的身份。

揭秘 Cobalt Strike 的make_token命令
图 14-Yamcha 访问令牌与 Bulma 凭证一起链接到登录会话

如前所述,runas netonlymake_token不验证凭据这一事实有很多好处。例如,我们可以为被拒绝本地访问的用户使用凭据,也可以为本地系统不知道且无法验证的帐户(例如来自其他计算机的本地用户或来自不受信任域的帐户)使用凭据。此外,我们可以创建具有无效凭据的“牺牲”登录会话,这使我们能够操纵 Kerberos 票证,而无需覆盖原始登录会话中存储的票证。

但是,这种缺乏验证的情况也会导致不愉快的意外,例如在公司使用经过身份验证的代理的情况下。如果我们在将凭证插入make_token时犯了错误,或者不小心创建了牺牲会话,我们最终可能会锁定帐户丢失我们的 Beacon,因为它不再能够通过代理退出!

有沒有行政背景!?

拉斐尔提到,为了使用make_token创建的令牌,需要一个管理环境。

“make_token 和 steal_token 的问题在于,它要求你处于管理员环境中,然后才能使用该令牌执行任何操作”

我们真的需要行政背景吗?事实上,在某些情况下,这种说法并不完全准确

据我们所知,make_token命令使用LogonUserA函数(以及LOGON32_LOGON_NEW_CREDENTIALS标志)创建一个类似于用户的新访问令牌,但链接到包含备用用户凭据的新登录会话。但该命令并不止于此,因为LogonUserA仅返回新令牌的句柄;我们必须对该令牌执行某些操作

假设我们的目标是使用新令牌的上下文创建新的流程。

使用令牌创建进程

如果我们查看 Windows API,我们会发现两个支持令牌句柄作为参数来创建新进程的函数:

  • 创建进程WithTokenW
  • 创建进程作为用户A

然而,阅读这些函数的文档,将显示以下语句:

“通常,调用 CreateProcessAsUser 函数的进程必须具有SE_INCREASE_QUOTA_NAME 权限,如果令牌不可分配,则可能需要SE_ASSIGNPRIMARYTOKEN_NAME 权限。”

“调用 CreateProcessWithTokenW 的进程必须具有SE_IMPERSONATE_NAME 权限。”

这就是 Raphael 的说法有道理的地方。即使我们可以通过LogonUserA与非特权用户一起创建令牌,我们也无法使用该令牌创建新进程。为此,Microsoft 表示我们需要管理权限,例如SE_ASSIGNPRIMARYTOKEN_NAMESE_INCREASE_QUOTA_NAMESE_IMPERSONATE_NAME

在非特权上下文中使用*make_token并尝试创建进程(例如shell dir dc01.capsule.corpC$*)时,Beacon 将默默失败并返回忽略令牌**以创建进程。这就是有时模拟似乎无法正常工作的原因之一。

需要注意的是,Meterpreter 等代理确实提供了有关故障的更多信息:

揭秘 Cobalt Strike 的make_token命令
图 15 - 模拟失败

因此,我们可以重新表述拉斐尔的陈述如下:

“make_token 的问题在于,它要求你处于管理员环境中,然后才能使用该令牌实际创建进程”

敏锐的读者现在可能会想……如果我在当前进程内操作而不是创建新进程,会发生什么?我是否仍然需要管理权限?

访问令牌 + 线程模拟

Windows API 提供了ImpersonateLoggedOnUserSetThreadToken等函数,允许进程内的线程模拟访问令牌提供的安全上下文。

揭秘 Cobalt Strike 的make_token命令
图 16 — ImpersonateLoggedOnUser

除了保留令牌句柄以供将来创建进程之外,make_token还使用类似这样的函数在 Beacon 运行的线程中获取令牌的安全上下文。我们需要管理员权限吗?根本不需要

如下图所示,我们遇到了第三点:

揭秘 Cobalt Strike 的make_token命令
图 17 - Windows 中何时允许模拟

这意味着,从 Beacon 运行的线程执行的任何命令或工具都将受益于make_token创建的安全上下文,而无需管理上下文。这包括许多本机命令,以及作为 Beacon 对象文件 (BOF) 实现的功能。

揭秘 Cobalt Strike 的make_token命令揭秘 Cobalt Strike 的make_token命令

结束语

考虑到以上所有信息,我们可以对make_token进行更详细的描述,如下所示:

make_token命令会创建一个与当前用户类似的访问令牌,以及一个包含作为参数指定的凭据的登录会话。这样可以实现双重身份,即本地没有任何变化(我们仍然是同一个用户),但在网络中,我们将由另一个用户的凭据表示(请注意,make_token不会验证指定的凭据)。创建令牌后,Beacon 会在运行内联功能时模拟它以从新的安全上下文中受益。

Beacon 还会存储令牌句柄,以便在需要管理上下文的新进程创建中使用。如果尝试使用非特权用户创建进程,Beacon 将忽略令牌并恢复常规进程创建。

最后要指出的是,2019 年,Raphael Mudge 发布了他出色的Red Team Ops with Cobalt Strike课程的新版本。在第八个视频中,make_token 再次被讨论,但这次展示了一个非特权用户的演示。虽然这表明运行命令不需要管理上下文,但并没有对此进行更多解释。

我们希望本文能够解答您关于 make_token 的所有疑问。

原文始发于微信公众号(红云谈安全):揭秘 Cobalt Strike 的“make_token”命令

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月9日14:21:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   揭秘 Cobalt Strike 的make_token命令https://cn-sec.com/archives/3146165.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息