In this article we will learn about Automating Windows Privilege Escalation.
Introduction[Automating Windows Privilege Escalation]
Privilege escalation on any system primarily involves gathering a large amount of information about the target host, which further includes some of the following sets of questions that a penetration tester must cover:
- What version of the operating system is installed on the host?
- Is any vulnerable package installed or running?
- What type of services are running in the system and are they properly configured from a security point of view or not?
- How are user roles segregated?
- How are file system permissions assigned to different user roles?
- Are there any configuration/password files stored on the system?
- Are there any misconfigured CRON jobs/scheduled jobs running on the system?
By answering the above and many other questions depending on the situation and availability, one can certainly escalate one’s privileges from a normal user to a highly privileged user. As we can see, there is a lot of information to gather, which directly means that we have to do a lot of manual checks to successfully escalate our privileges. So automating certain tasks will save time and provide an additional benefit to any penetration tester.
The test rig / software used to test our tool can be downloaded here. The required python package can also be installed using the following command:
pip install wmi
We will automate the following tasks using the Python programming language.
- Unspecified service routes.
- Misconfigured permissions for service executables.
- Misconfigured MSI registry entries.
Unlisted Service Paths:
Before we get to understanding the code used to automate this task, we need to understand how we can exploit the unlisted service path vulnerability. This is mainly related to how Windows interprets the path to the executable service before starting it. For example:
Run the test program/script using the command line by specifying the path to the executable file.
As we can see, our helloworld program runs successfully when placed in a folder with no space. So what happens to the space folder?
As you can see, there is a helloworld.exe file in the folder with the space. To do this, we simply change our directory by providing quotes around the folder name. Now the question arises how we can abuse this Windows behavior.
As you can see, in the first window of the image, it treats the folder name with a space as an executable file and throws us the error that “the folder is not recognized as an internal or external command/executable/batch file”. This means that if we put an executable file called folder.exe, it should run when the user calls the program path without spaces.
First we tried to run our program without space. Next, we copied the same program into a folder on the desktop called folder.exe and deleted our program from the older path to ensure that only the planted binary would run.
Windows will now launch our binary named folder.exe.
So we automate this process by telling our program to iterate through the service paths and show us which service paths are unlisted.
In our code, we first defined a WMI object, selected everything from the Win32_Service class, and iterated over that to get all the service paths. Next, we check that the path doesn’t contain any quotes, if our condition is met, we add that path to our dictionary, keeping the service name as the key name.
Next, we check to see if any service paths are identified and iterate through our dictionary to display the values.
We will add the above code snippets to our final program.
Misconfigured permissions for service executables
The second part of the program involves checking the permissions of the executable files of the service. Which means if any low privilege user can modify/write/replace the executable with their code/executable. The next time the service starts, the malicious code will start as system.
In this case, we’ll use the Windows “icacls” utility to find out the permissions of all service executables. Additionally, list those in which any user has full access to the executable.
As you can see, we used the wmi query output from our previous code section and added the found executables to the Python list.
We will now provide the executable path to the icacls utility to get the executable’s permission information and parse the output using the find_paths function.
The find_paths function compares the executable’s permission information against predefined values and prints if a match is found.
Misconfigured MSI registry entries
Windows has this configuration which, if set, allows any user to run MSI (Microsoft Installers) with SYSTEM privileges. This includes checking the actual value for a 32-bit dword named “AlwaysInstallElevated” in the following two registry keys:
HKCUSOFTWARE Policy Microsoft Windows Installer
This will be our last addition to the program, in this case we will use a built-in python module called “_winreg” to load the registry entries.
We open the registry keys using the OpenKey function and enumerate the first dword value. Next, we verify that both registry keys are set to true.
If both registry keys exist and dword values are set, we display the following message to the user.
Run our complete script on a vulnerable computer. As you can see, our script is successfully able to identify the mentioned problems. Since our computer is not vulnerable to the third issue, I encourage the diligent reader to manually create these registry entries and run their own MSI executable using the msiexec utility.
Tip: We can generate msi files using msfvenom.
The complete Python script can be downloaded from here.