Windows 10 Windows Hardening Guide: Finding and fixing unquoted services

Applies to:
Windows Vista and newer

Description:
This tutorial will help illustrate and fix Windows services that have unquoted ImagePath registry keys


About Vulnerability:
The ImagePath data value contains the path to the binary associated with a given Windows service. By leaving them unquoted an attacker or malware can put a crafted binary along the path and it will be executed as the service. Since many services run as the SYSTEM account these malicious programs will have complete access to your system.

External Link:
Here is a good article descripting how this attack works. Practical Guide to exploiting the unquoted service path vulnerability in Windows - TrustFoundryPractical Guide to exploiting the unquoted service path vulnerability in Windows - TrustFoundry

The following script (also attached) can find and fix all the services that do not have quotes around the executable paths. The script will need to be run from an elevated powershell console or the Powershell ISE. If you get an error regarding execution policy you can run the following command
Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy Unrestricted

Code:
#requires -runasadministrator

# Grab all the services on the computer
$services = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services"

# Loop through each service
foreach($service in $services)
{
    $hasImagePath = $false
    foreach($pro in $service.Property)
    {
        # Check if the service has the imagepath property
        if($pro -eq "ImagePath")
        {
            $hasImagePath = $true           
            break;
        }
    }

     # If no imagepath then we skip this service
     if(-not($hasImagePath))
     {
        continue
     }

     # Copy the image path into a temporary variable
     $imagePath = [string]$service.GetValue("ImagePath")

     # If imagepath has no spaces move on to next service
     if(-not ($imagePath.Contains(" ")))
     { continue }

     # Placeholders for executable and arguments
     $binary = ""
     $args = ""


     # Evaluate drivers
     if($imagePath.Contains('.sys'))
     {
        # Split executable path and arguments for drivers
        if($imagePath.Contains('.sys"'))
        {
            $splitPoint = $imagePath.IndexOf(".sys")+5
            $binary = $imagePath.Substring(0,$splitPoint)
            $arguments = ($imagePath.Substring($splitPoint-1))
        } else
        {
            $splitPoint = $imagePath.IndexOf(".sys")+4
            $binary = $imagePath.Substring(0,$splitPoint)
            $arguments = ($imagePath.Substring($splitPoint))     
        }
     # Evaulate executables
     } elseif($imagePath.Contains('.exe'))
     {
        # Split executable path and arguments for drivers
        if($imagePath.Contains('.exe"'))
        {
            $splitPoint = $imagePath.IndexOf(".exe")+5
            $binary = $imagePath.Substring(0,$splitPoint)
            $arguments = ($imagePath.Substring($splitPoint-1))
        } else
        {
            $splitPoint = $imagePath.IndexOf(".exe")+4
            $binary = $imagePath.Substring(0,$splitPoint)
            $arguments = ($imagePath.Substring($splitPoint))
        }
    }

    # Check for spaces in the binary path
    If($binary.Contains(' '))
    {
        # Spaces and no quotes
        if(-not(($binary.StartsWith('"') -and $binary.EndsWith('"'))))
        {
            # Add quotes around the binary
            "$($service.name) has an unquoted ImagePath ($imagePath)"
            $binary = "`"$binary`""
            $newImagePath = "$binary$arguments"


            # Convert registry path
            $servicePath = $service.Name.Replace("HKEY_LOCAL_MACHINE","HKLM:")

            # Update the ImagePath
            Set-ItemProperty -Path $servicePath -Name "ImagePath" -Value $newImagePath
        }
    }
}
 

Attachments

  • Fix-UnquotedStrings.zip
    1,008 bytes · Views: 443
Just took a quick glance at this code, also noted I have paths in ImagePath such as System32\drivers\3ware.sys, does quoting it "System32\drivers\3ware.sys" break it? Usually in Windows quoting a path means its absolute is why I'm asking, wouldn't it have to be converted to "c:\windows\System32\drivers\3ware.sys" ?
 
No it won't break it. The script will only quote paths with spaces. Drivers don't usually have any.
 
Assumption is the mother of all F#$@ ups, LMAO. I have never seen a driver with spaces in it's name, but I wouldn't put it past a developer.
 
Back
Top