Friday 17 April 2015

Using SCCM to fix Unquoted Service Path Security issue

How to use Compliance Items to fix this issue (see this post http://www.commonexploits.com/unquoted-service-paths/ for a description of the security issue)

Via the main SCCM Management Console 

  • Click on Assets and Compliance Section 
  • Click on Compliance Settings, Configuration Items 
  • Click on Create Configuration Item ( I won't detail all the screens here - skipping to the "Settings" section - specify name, description, supported platforms etc as you see fit. 
  • You want to create a new Settings with a Setting Type of Script and a Data type of String.



Now we'll specify the Discovery Script and the Remediation Script

Discovery Script (Script Language : Powershell)






$Services = Get-WmiObject -Class Win32_Service

$Compliant = ""

$Services | % {
    #Check the path of each service, locate .exe in the path string, then check if any spaces in the path
    #Also check if any " in the path before the EXE.  If no " and a space exists, then its not compliant

    $ServiceName = $_.Name
    $ServiceEXEPath = $_.PathName

    #$RegKey = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\$ServiceName"
    $RegPath = (Get-itemproperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$ServiceName").ImagePath

    $IndexOfSpace = $RegPath.IndexOf(" ")
    $IndexOfEXE   = $RegPath.IndexOf(".exe")
    $IndexOfQuote = $RegPath.IndexOf("`"")

    if (($IndexOfSpace -ne -1) -and ($IndexOfSpace -lt $IndexOfEXE) -and ($IndexOfQuote -ne 0))
    {
        $newpath = "`"" + $Regpath.substring(0,$IndexofEXE+4) + "`""

        #Write-Host "[$ServiceName][$ServiceEXEPath][$RegPath][$IndexOfSpace][$IndexOfEXE][$IndexOfQuote][$NewPath]"
        $Compliant += "[$ServiceName][$ServiceEXEPath]`n"
    }
}

if ($Compliant.length -eq 0)
{
    $Compliant = "Compliant"
}

$Compliant



Remediation Script (Script Language : Powershell)

$Services = Get-WmiObject -Class Win32_Service

$Services | % {
    #Check the path of each service, locate .exe in the path string, then check if any spaces in the path
    #Also check if any " in the path before the EXE.  If no " and a space exists, then its not compliant

    $ServiceName = $_.Name
    $ServiceEXEPath = $_.PathName

    #$RegKey = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\$ServiceName"
    $RegPath = (Get-itemproperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$ServiceName").ImagePath

    $IndexOfSpace = $RegPath.IndexOf(" ")
    $IndexOfEXE   = ($RegPath.toupper()).IndexOf(".EXE")
    $IndexOfQuote = $RegPath.IndexOf("`"")

    if (($IndexOfSpace -ne -1) -and ($IndexOfSpace -lt $IndexOfEXE) -and ($IndexOfQuote -ne 0))
    {
        $newpath = "`"" + $Regpath.substring(0,$IndexofEXE+4) + "`""

        if (($RegPath.length) -gt ($IndexOfEXE+4))
        {
            $newpath += $RegPath.substring($IndexOfEXE+4,($Regpath.length - $IndexofEXE - 4))
        }

        #Write-Host "[$ServiceName]`n[$ServiceEXEPath]`n[$IndexOfSpace][$IndexOfEXE][$IndexOfQuote]`n[$NewPath]"

        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$ServiceName" -Name ImagePath -Value $newpath
   
    }
}

This should allow you to scan and check all the services across your entire estate for the unqouted service path vulnerability, and when you enable the Remediate option, automatically fix any misconfigured services.

1 comment:

  1. the if ($Compliant.length -eq 0) test will always equal 0 unless the last service tested has an unquoted services path.

    I ended up adding a $count variable and incrementing it in the loop if the service being tested ended up having an unquoted services path.

    I changed the set of the variable $Compliant = "" to $Compliant = "Compliant"

    and then changed the:

    if ($Compliant.length -eq 0)

    to

    if ($Count-gt 0) {$Compliant = "NotCompliant"

    this resolved the always "true" test I was having issue with.

    ReplyDelete