Tenable ile zafiyet taraması yaparken bazı Windows sunucular üzerinde Microsoft Windows Unquoted Service Path Enumeration zafiyetleri görmeye başladık.
Peki bu güvenlik açığı ne anlama geliyor? Temel olarak bir uygulama veya servis yüklendiğinde, uygulamanın veya servisin konumu Windows Kayıt Defterine kaydedilir, ancak “C:\Program Files\” gibi aradaki boşluklar içeriyorsa, yerel erişimi olan kötü niyetli bir saldırgandır. Sistem, etkilenen pathe yürütülebilir bir dosya ekleyerek/kopyalayarak yükseltilmiş ayrıcalıklar elde edebilir.
Aslında kolayca zafiyet giderilebilir durumda, bununla ilgili yazılmış bir çok powershell script mevcut.
Kullanıp çalıştığını gördüğüm, işlem sonrası zafiyet taramalarından da zafiyetkin kapatılmasına neden olan scripti paylaşayım.
## Grab all the registry keys pertinent to services $result = Get-ChildItem 'HKLM:\SYSTEM\CurrentControlSet\Services' $ServiceItems = $result | Foreach-Object {Get-ItemProperty $_.PsPath} # Iterate through the keys and check for Unquoted ImagePath's ForEach ($si in $ServiceItems) { if ($si.ImagePath -ne $nul) { $obj = New-Object -Typename PSObject $obj | Add-Member -MemberType NoteProperty -Name Status -Value "Retrieved" # There is certianly a way to use the full path here but for now I trim it until I can find time to play with it $obj | Add-Member -MemberType NoteProperty -Name Key -Value $si.PSPath.TrimStart("Microsoft.PowerShell.Core\Registry::") $obj | Add-Member -MemberType NoteProperty -Name ImagePath -Value $si.ImagePath ######################################################################## # Find and Fix Bad Keys for each key object ######################################################################## #We're looking for keys with spaces in the path and unquoted $examine = $obj.ImagePath if (!($examine.StartsWith('"'))) { #Doesn't start with a quote if (!($examine.StartsWith("\??"))) { #Some MS Services start with this but don't appear vulnerable if ($examine.contains(" ")) { #If contains space #when I get here, I can either have a good path with arguments, or a bad path if ($examine.contains("-") -or $examine.contains("/")) { #found arguments, might still be bad #split out arguments $split = $examine -split " -", 0, "simplematch" $split = $split[0] -split " /", 0, "simplematch" $newpath = $split[0].Trim(" ") #Path minus flagged args if ($newpath.contains(" ")){ #check for unflagged argument $eval = $newpath -Replace '".*"', '' #drop all quoted arguments $detunflagged = $eval -split "\", 0, "simplematch" #split on foler delim if ($detunflagged[-1].contains(" ")){ #last elem is executable and any unquoted args $fixarg = $detunflagged[-1] -split " ", 0, "simplematch" #split out args $quoteexe = $fixarg[0] + '"' #quote that EXE and insert it back $examine = $examine.Replace($fixarg[0], $quoteexe) $examine = $examine.Replace($examine, '"' + $examine) $badpath = $true } #end detect unflagged $examine = $examine.Replace($newpath, '"' + $newpath + '"') $badpath = $true } #end if newpath else { #if newpath doesn't have spaces, it was just the argument tripping the check $badpath = $false } #end else } #end if parameter else {#check for unflagged argument $eval = $examine -Replace '".*"', '' #drop all quoted arguments $detunflagged = $eval -split "\", 0, "simplematch" if ($detunflagged[-1].contains(" ")){ $fixarg = $detunflagged[-1] -split " ", 0, "simplematch" $quoteexe = $fixarg[0] + '"' $examine = $examine.Replace($fixarg[0], $quoteexe) $examine = $examine.Replace($examine, '"' + $examine) $badpath = $true } #end detect unflagged else {#just a bad path #surround path in quotes $examine = $examine.replace($examine, '"' + $examine + '"') $badpath = $true }#end else }#end else }#end if contains space else { $badpath = $false } } #end if starts with \?? else { $badpath = $false } } #end if startswith quote else { $badpath = $false } #Update Objects if ($badpath -eq $false){ $obj | Add-Member -MemberType NoteProperty -Name BadKey -Value "No" $obj | Add-Member -MemberType NoteProperty -Name FixedKey -Value "N/A" $obj = $nul #clear $obj } # Plans to change this check. I believe it can be done more efficiently. But It works for now! if ($badpath -eq $true){ $obj | Add-Member -MemberType NoteProperty -Name BadKey -Value "Yes" #sometimes we catch doublequotes if ($examine.endswith('""')){ $examine = $examine.replace('""','"') } $obj | Add-Member -MemberType NoteProperty -Name FixedKey -Value $examine if ($obj.badkey -eq "Yes"){ #Write-Progress -Activity "Fixing $($obj.key)" -Status "Working..." $regpath = $obj.Fixedkey $obj.status = "Fixed" $regkey = $obj.key.replace('HKEY_LOCAL_MACHINE', 'HKLM:') # Comment the next line out to run without modifying the registry # Alternatively uncomment any line with Write-Output or Write-Object for extra verbosity. Set-ItemProperty -Path $regkey -name 'ImagePath' -value $regpath } $obj = $nul #clear $obj } } }