Windows Privelege Escalation
Nicholas Underwood
Senior Manager Cyber Threat Team (Hunting, Intelligence, WAF, RISK)
Being able to successfully attack a box and deliver an exploit that works isn’t the end of the line when it comes to “hacking.” In order to get the information wanted, or deliver the desired “Actions on Target”, you have to be able to gain full control of the system. A lot of exploits do not gain you Admin access on a system, but as a normal user, worst cases guest access. This guide is here to teach you how to gain Admin privileges on the specific windows box. As Windows is the most predominantly used OS, we will be using it. The odds are favorable of you running across a windows box versus macOS or Linux based systems.
There are multiple routes of action we can take at this point. No system is always going to be the same, and some systems will have certain vulnerabilities patched. For the purpose of this explanation, I will be using a Kali Linux VM; this is what was used to compromise the host. I will assume you already understand some of the basics that come with Kali, so I won’t go into detail about it. The first method to windows escalation is using Unquoted Service Paths.
Unquoted Service Paths
Basically, it is a vulnerability that occurs if a service executable path is not enclosed with quotation marks and contains space. To identify these unquoted services you can run this command on Windows Command Shell:
wmic service get name,displayname,pathname,startmode |findstr /i "Auto" |findstr /i /v "C:\Windows\\" |findstr /i /v """
All services with unquoted executable paths will be listed:
If you look at the registry entry for this service with Regedit you can see the ImagePath value is:
C:\Program Files (x86)\Program Folder\A Subfolder\Executable.exe
It should be like this:
“C:\Program Files (x86)\Program Folder\A Subfolder\Executable.exe”
When Windows attempts to run this service, it will look at the following paths in order and will run the first EXE that it will find:
C:\Program.exe
C:\Program Files.exe
C:\Program Files (x86)\Program.exe
C:\Program Files (x86)\Program Folder\A.exe
C:\Program Files (x86)\Program Folder\A Subfolder\Executable.exe
This vulnerability is caused by the CreateProcess function in Windows operating systems. If we can drop our malicious .exe successfully on one of these paths, upon a restart of the service, Windows will run our .exe as SYSTEM. But we should have the necessary privileges on one of these folders. In order to check the permissions of a folder, we can use built-in Windows tool, icals. Let’s check permissions for C:\Program Files (x86)\Program Folder folder:
As you can see, “Everyone” has full control on this folder.
F = Full Control
CI = Container Inherit (This flag indicates that subordinate containers will inherit this ACE)
OI = Object Inherit (This flag indicates that subordinate files will inherit the ACE)
This means we are free to put any file to this folder. From now on, what you’re going to do depends on your intentions. I will generate a reverse shell payload to run as SYSTEM. MSFvenom can be used for this job:
Let’s place our payload to C:\Program Files (x86)\Program Folder folder:
At the next start of the service, A.exe will run as SYSTEM. Here I am to stop and restart the service:
Access is denied because we don’t have permission to stop or start the service. However we can wait for someone to restart the machine, or we can do it ourselves with shutdown command:
Our target machine is now restarting. Soon, the payload will work as SYSTEM. Next we start a handler:
Now we have a Meterpreter shell with SYSTEM privileges. As you can see, the session “died” as soon as it was started. It’s because when a service starts in Windows operating systems, it must communicate with the Service Control Manager. If it’s not, Service Control Manager thinks something is not right and terminates the process. All that is needed is to migrate it to another process before the SCM terminates our payload, or you can consider using auto-migration.
There is a Metasploit module for checking and exploiting this vulnerability:
exploit/windows/local/trusted_service_path
This module only requires you to link it to an existing Meterpreter session before running:
Before we move on to the next vulnerability we can use, you should check your own system for this to make sure you aren’t able to be owned by someone else. The following showcases how to detect this:
Services with Vulnerable Privileges
As we know, Window’s services run as SYSTEM. So their folders, files, and registry keys must be protected with access controls. This isn’t always the case when it comes to third party services.
Insecure Registry Permissions
In Windows, information related to services is stored in HKLM\SYSTEM\CurrentControlSet\Services registry key. If we want to see information about our “Vulnerable Service” we should check HKLM\SYSTEM\ControlSet001\Services\Vulnerable Service key.
Of course, our Vulnerable Service has some weaknesses for educational purposes.
But the point here is, how can we check these permissions from the command line? Let’s start the scenario from the beginning. You have a low-priv Meterpreter session back and you want to check permissions of a service:
You can use SubInACL tool to check registry keys permissions. You can download it and work with it alongside, but the point you need to be aware of is that it deploys as a msi file. If AlwaysInstallElevated policy setting is not enabled on target machine you can’t install msi files with low-priv user. And of course, you may not want to install new software to the target machine.
I recommend installing it on a virtual machine and finding the subinacl.exe file in C:\Program Files (x86)\Windows Resource Kits\Tools\. It will work well without having to install msi package. Let’s upload SubInACL tool to our target:
Now SubInACL tool is ready to use. Let’s check permissions for HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Vulnerable Service:
Focus on the lines that say Everyone has Full Control on this registry key. It means we can change the executable path of this service by editing the ImagePath value. If we generate a simple reverse shell payload and drop it to our target, all that remains is changing the ImagePath value for our vulnerable service with the Payload’s path. Let’s generate a simple reverse shell payload:
Drop it to the target machine:
Now change the ImagePath value with the Payload’s path:
At the next start of the service, Payload.exe will run as SYSTEM. But remember, we had to restart the computer to do this:
The target machine is restarting now. Prepare a handler at this point. Soon, our payload will work as SYSTEM.
Remember, we are working with services just as in the previous method. The hi-priv meterpreter session will die quickly.
Insecure Service Permissions
It is very similar to the previous Insecure Registry Permissions example. Instead of changing the service’s ImagePath registry value directly, we will do it by modifying service properties. To check which services have vulnerable privileges, use the AccessChk tool from SysInternals Suite. Remember, it isn’t always viable to install software/tools on a target machine as this may alert the adversary of your presence, or leave footprints. You can get around this by using a custom script (preferably in PowerShell as it comes default with windows) and having it dump out the output to the terminal, thus leaving less of a trace.
Here I will be using AccessChk:
All services “testuser” can modify will be listed. SERVICE_ALL_ACCESS means we have full control over modifying the properties of Vulnerable Service.
Let’s view the properties of the Vulnerable Service:
BINARY_PATH_NAME points to Executable.exe which is executable file for this service. Changing this value with any command means this command will run as SYSTEM at the next start of the service. We can add a local admin if we want.
The first thing to do is adding a user:
After changing binpath, restart the service with the “sc stop” and “sc start” commands.
When you try to start the service, it will return an error. As shown earlier, when a service starts in Windows, it has to communicate with the Service Control Manager. “Net user” cannot communicate with the SCM at this point. This is not an issue - our “service” will run as SYSTEM and will create the new user successfully without throwing an error.
We will now add “eviladmin” user to the local admins by changing “binpath” and starting the service again (we don’t need to stop it again, it is not running because it didn’t communicate with the SCM.)
Now, we have a nice Local Admin account to conduct whatever business we need to:
As we did before, you may prefer dropping a reverse shell payload to target machine and replacing binpath with the payload’s path. Instead of manually applying this method, you can use this metasploit module( this should already come with an updated version of Metasploit): exploit/windows/local/service_permissions
You will need to link it to an existing Meterpreter session:
Insecure File/Folder Permissions
It is very similar to Unquoted Service Paths. Unquoted Service Paths takes advantage of “CreateProcess” function’s weakness in combination with folder permissions along the executable file path of a service. Here we will try to replace the executable directly. For example, if we check permissions for our Vulnerable Service’s executable path, we can see it is not well protected:
Simply replacing “Executable.exe” file with a reverse shell payload and restarting the service will give us a meterpreter session with SYSTEM privileges.
AlwaysInstallElevated
AlwaysInstallElevated is a policy setting that directs Windows Installer to use elevated permissions when it installs any package on the system. If this policy setting is enabled, privileges are extended to all programs. Actually, enabling this is the equivalent of granting administrative rights to non-privileged users. Sometimes system administrators enable this setting:
You should check the registry values to understand if this policy is enabled:
[HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer]
“AlwaysInstallElevated”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer]
“AlwaysInstallElevated”=dword:00000001
If you have a low-priv Meterpreter session, the built-in command line tool, reg query will help you check these values:
If you received an error such as “ERROR: The system was unable to find the specified registry key or value.” this means this registry values never created. So, the policy is not enabled.
However, if you see the following output, it means the policy setting is enabled and you can exploit it:
As said before, in this situation, Windows Installer will use elevated permissions when it installs any package. So we should generate a malicious .msi package and run it. MSFvenom can handle this. You can generate a .msi package that adds a local admin to our target machine. You should use windows/adduser as a payload:
In this scenario, I’ll generate an executable reverse shell payload(Payload.exe) and an msi package(malicious.msi) that executes this payload.
Generating the payload:
Generating malicious.msi by using windows/exec as a payload. Make sure you enter the correct path for Payload.exe:
Now we can upload these two to our target machine:
Before executing the .msi file, start a new handler on another terminal window for brand new hi-priv shell:
Now, execute it:
/quiet = Suppress any messages to the user during installation
/qn = No GUI
/i = Regular (vs. administrative) installation
Now you have a shell with System privileges.
There are multiple other ways to get SYSTEM access, but the discussed solutions should give you a good understanding of the topic. Promote your knowledge by looking up and practicing other ways on a target box.
Technical Program Manager
4 年Skills like this are paramount to any pentester wanting to be successful in an AD environment. Sick read and great work man!