Finding and Fixing Unquoted Service Paths, Pt3

In my last post I continued the development of a set of scripts to identify and fix unquoted services paths in Windows, the vulnerability I demonstrated here. So far, we can get services with paths as objects and identify which ones are bad, so now its time to start fixing them…


I’ve posted updated copies of all 3 scripts with progress output and instructions for executing in parallel here. The explanation below is still valid, but I have adjusted the handling of some output to clean up the pipeline.

I spent some time trying to figure out the best way to do this. In the end, I wound up right back where I started: REG.exe

Fixing Unquoted Service Paths

REG allows me to utilize this against computers without PowerShell, as well as deliver remotely when PSRemoting isn’t enabled. Since all I have to do is get the fixed path in a format REG can understand, this script ended up being pretty short.

First, we handle input and a process loop.

[cmdletbinding()]
	Param ( #Define a Mandatory input
	[Parameter(
	 ValueFromPipeline=$true,
	 ValueFromPipelinebyPropertyName=$true,
	 Position=0)] $obj
	) #End Param
 
Process
{ #Process Each object on Pipeline
} #End Process

That should look fairly familiar if you’ve seen my last post.

Its possible I will get objects in the pipeline that have been evaluated and do not need to be changed, so I need to account for this. Beyond that, its a simple matter of escaping quotes correctly (ironically the very skill that got us into this mess!) and feeding it to the REG ADD command.

	if ($obj.badkey -eq "Yes"){
		$regpath = $obj.Fixedkey
		$regpath = '"' + $regpath.replace('"', '\"') + '"' + ' /f'
		Write-Output "$($obj.ComputerName) : $($obj.FixedKey) : $regpath"
		REG ADD "\\$($obj.computername)\$($obj.key)" /v ImagePath /t REG_EXPAND_SZ /d $regpath
		}

That’s pretty much it. We are only writing out those objects that require a change, so good keys are getting dropped in this script. It’s designed to be the end of the pipeline (or last before something like Out-File) and those things that don’t need edits are being ignored. REG.exe escapes with \, so its fairly straight forward. We hold the escaped version in a temporary string and feed to REG ADD with the /f (force) parameter. We get back single line statements that contain the computer name, the old path, and the new path we’re writing (delimited by colons). It also writes the output of the REG command, so you’ll see “The Command Completed Successfully” a lot. If REG throws an error, you’ll see it in this output.

And that’s all she wrote folks. I still have the outstanding task to try to catch unflagged arguments, but they are not common enough to hold up putting this out there. I will update when I’ve got a solution for handling that argument.

Final Thoughts

This whole thing stems from developers who do not escape their strings correctly. After something like 10+ years, we’re still dealing with (and in a lot of cases, just discovering) this vulnerability. The right answer for your vulnerabilities is to demand your developers and vendors write their code correctly.

That said – hopefully this is a tool that will help you keep the band aids on between releases. You will need to run this periodically. As you discover those titles that are vulnerable, you’ll need to keep up with desktop and server deployments, as well as application patches for software that you identify as vulnerable but haven’t fixed yet. That is part of the reason I cut these scripts up like I did. This gives us both a reporting tool and a correcting tool, so we can monitor our environments and quickly remediate those things we find if appropriate.

I cannot say it enough, check your results before you run the fix. Look for those unflagged arguments. Exceptions that fall outside what is coded for here are uncommon, but I have found them. At the end of the day, I cannot be liable for what you do with this code, but I do hope you use it and its helpful. If you have suggestions or comments or would like to see something changed, please leave me a comment or send me an email at Jeff@RyanandJeffShow.com

As an aside, Hey Microsoft! Can we stop parsing these paths this way and start reading them literally? Can you provide us some insight on why this hasn’t been done and what prevents it from happening? Thanks!

Here’s the whole Fix script.

#Fix-BADSVCPath.ps1
[cmdletbinding()]
	Param ( #Define a Mandatory input
	[Parameter(
	 ValueFromPipeline=$true,
	 ValueFromPipelinebyPropertyName=$true,
	 Position=0)] $obj
	) #End Param
 
Process
{ #Process Each object on Pipeline
	if ($obj.badkey -eq "Yes"){
		$regpath = $obj.Fixedkey
		$regpath = '"' + $regpath.replace('"', '\"') + '"' + ' /f'
		Write-Output "$($obj.ComputerName) : $($obj.FixedKey) : $regpath"
		REG ADD "\\$($obj.computername)\$($obj.key)" /v ImagePath /t REG_EXPAND_SZ /d $regpath
		}
} #End Process

Jeff is a system administrator for an enterprise of over 4000 devices. He is comfortable on Windows and *nix and participates in everything from desktop to network support. In addition, he develops in PowerShell to aid in the automation of administrative tasks.

When not at work, Jeff is adjunct faculty at the University of Alaska Anchorage, where he teaches PC Architecture to first year students in the Computer and Networking Technology Program. He is also working on new curriculum in PowerShell and Virtualization as well as leading department technology deployments.


View Jeff Liford's profile on LinkedIn



Posted in Computer Security, Desktop, PowerShell, Server