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
}
}
$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.