In this post we will talk about Windows local privilege escalation and some of the most common techniques to get SYSTEM privileges from non privileged user.
Once the attacker gets into the system the next step is to get the highest possible level of privileges. To achieve this goal there are several techniques, in this post we will focus on finding vulnerable services on the machine.
We are going to use for this demo a Windows 10 machine (Build 1809) and a guest user “Visitor” who does not belong to the group of administrators:
Weak service binary permissions
The most common way to find vulnerable services is to look for services whose binary path can be edited by any user. This way we can replace the binary with another malicious one and the service will execute it with elevated permissions.
First of all, we can use this command to obtain all binary paths of services running (avoiding System32 folder which is likely not editable from standard users).
1 |
for /f "tokens=2 delims='='" %a in ('wmic service list full^|find /i "pathname"^|find /i /v "system32"') do @echo %a >> c:\windows\temp\binaries.txt |
After that, we can use “icacls” command to list permissions of those binaries and then we will check if some of those binaries has write, modify or full permissions: (M),(W) or (F), for “BUILTIN\Users”, “Authenticated Users” or “Everyone”:
1 |
for /f eol^=^"^ delims^=^" %a in (c:\windows\temp\binaries.txt) do cmd.exe /c icacls "%a" | findstr /i "(F) (M) (W) :\\" |
After running that command we can see the binary “C:\Program Files\Microvirt\MEmu\MemuService.exe” which is editable by “Everyone”:
We can use the following commands to see which is the associated service for that binary and check the status and under which user is running:
1 2 |
wmic service get name,pathname | findstr /i "MemuService.exe" MEmuSVC C:\Program Files\Microvirt\MEmu\MemuService.exe |
So basically the vulnerable service called “MEmuSVC” is running with SYSTEM privileges and configured in mode Auto.
The next step will be to replace the service binary with our malicious binary. For this demo a binary has been generated that adds the user “Visitor” to the group of local administrators. Current user doesn’t have enough permissions to add the user to admins group, but this non-privileged user is able to replace the service binary with the malicious one:
NOTE:Sometimes the binary will be locked by the service itself so we won’t be able to replace it. In this case, we only have to rename it and then copy our malicious binary with the correct name.
After that we will try to restart the service with [sc stop/sc start] commands but user Visitor does not have permissions to do that so we will directly reboot the machine to get our malicious binary executed as SYSTEM. Once the machine is rebooted, we will see that the service could not get started but our malicious binary got executed : )
Weak service permissions
We can use Sysinternals tool “accesschk.exe” to find services with vulnerable configuration. For example, using the following command we can check if our user “Visitor” is able to modify de configuration of service “TestService”:
1 |
accesschk.exe /accepteula -ucv "Visitor" TestSvc |
If the output of that command returns SERVICE_ALL_ACCESS or SERVICE_CHANGE_CONFIG then we could change the service configuration and replace the binary path of the service:
1 |
sc config TestSvc binpath= "C:\Windows\Temp\evil.exe" |
We can use directly the following commands to perform a search over all services:
1 2 3 |
accesschk.exe /accepteula -uwcqv "Visitor" * accesschk.exe /accepteula -uwcqv "Authenticated Users" * accesschk.exe /accepteula -uwcqv "Everyone" * |
Unquoted Service Paths
Another common way to find vulnerable services is to find service which Executable path is not quoted. When a executable path is not quoted and it has spaces on the string, Windows will look at the space as the end of line and will try to load a binary in a wrong path.
For example, if a service has configured its executable path as: C:\Program Files\My Service\svc.exe instead of “C:\Program Files\My Service\svc.exe”, then the service will try to execute in first place:
1 2 3 |
C:\Program.exe C:\Program Files\My.exe C:\Program Files\My Service\svc.exe |
So, if we create some malicious binary C:\Program.exe or C:\Program Files\My.exe then they will get executed before the correct one.
To find services with path vulnerable we can use the following command:
1 |
wmic service get name,pathname,displayname,startmode | findstr /i auto | findstr /i /v "C:\Windows\\" | findstr /i /v """ |
Here we have an example of vulnerable service “QVssService”. We can use ProcMon tool to see how it tries to execute C:\Program.exe binary in first place when it is started:
The service is running under SYSTEM account so if we can put the malicious file in C:\Program.exe and reboot the machine, then our malicious binary will get executed as SYSTEM.
NOTE: A recent vulnerability of this type was discovered 2 months ago in a well known VPN client software: https://support.forcepoint.com/KBArticle?id=000017525
To finish this post I would like to mention that there are several scripts on Internet which performs all of these checks and more automatically. A good example is the Powerhsell script “Powerup.ps1”.
https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerUp/PowerUp.ps1
An example of the output of this tool:
Me alegra volver a leer y aprender con tus interesantes artículos. Gracias