The %PATH% environment variable is a critical component for the operating system. It specifies the directories that the system searches to find executable files for commands, tools, or programs. When a user types a command in the terminal or command prompt, the system looks through the directories listed in the %PATH% variable to locate the executable file associated with that command.
This environment variable is particularly useful for running programs without needing to specify their full paths. Instead of typing the complete path to an executable, users can simply type the command name, and the system will search the directories in the %PATH% variable to find and execute the program.
The %PATH% variable is used for relative paths, meaning it searches through the specified directories in the order they are listed. If the executable is found in one of these directories, it is executed. If not, the system returns an error indicating that the command was not found.
For example, if the %PATH% variable includes directories like C:\Windows\System32 and C:\Program Files, the system will search these directories for the executable file when a command is entered. This allows for efficient and convenient execution of programs without needing to navigate to their specific directories.
Properly configuring the %PATH% variable is essential for ensuring that the system can locate and run the necessary programs efficiently. It is also important to avoid adding unnecessary or insecure directories to the %PATH% variable, as this can pose security risks.
In summary, the environment variable %PATH% is used for relative paths and not absolute paths.
This is a relative path:
1
cmd.exe
This is an absolute path:
1
C:\Windows\System32\cmd.exe
When we use a relative path the system needs to search for the executable file and to search for it, it uses the %PATH% environment variable. The first directory listed in the %PATH% environment variable will be the first directory that will be searched, here is an example:
1
2
3
4
5
6
C:\Windows\system32 # First search in here, if its not here then continueC:\Windows # Second search in here, if its not here then continueC:\Windows\System32\Wbem # If its here, then execute the command and stop searchingC:\Windows\System32\WindowsPowerShell\v1.0\C:\Windows\System32\OpenSSH\C:\Program Files\dotnet\
Note: The %PATH% environment variable is used to search the name of the executable, it doesn’t verify the integrity of the file, which means that we can create an illegitimate executable as long as we can hijack the %PATH%.
The user environment variables can be found in the registry HKEY_CURRENT_USER\Environment:
Alternatively, both the user environment variables and the system environment variables can be found using the GUI:
Windows XP - Right-click My Computer, and then click Properties → Advanced → Environment variables → Choose New, Edit or Delete.
Windows 7 - Click on Start → Computer → Properties → Advanced System Settings → Environment variables → Choose New, Edit or Delete.
Windows 8 - Right click on the bottom left corner to get Power User Task Menu → Select System → Advanced System Settings → Environment variables → Choose New, Edit or Delete.
Windows 10 - Right click on Start Menu to get Power User Task Menu → Select System → Advanced System Settings → Environment variables → Choose New, Edit or Delete.
In Windows 11 is at the following path Control Panel\System and Security\System\About\Advanced Settings or Settings > System > About:
Advanced System Settings
System Properties -> Advanced -> Environment Variables…:
Advanced System Settings
Now we can see both (user and system) environment variables:
Advanced System Settings
%PATH% Usage
We can change the user environment variable with setx and since this environment variable belongs to our current user we don’t need to execute this as administrator:
There is a problem with the above configuration and that is the value of the Path registry key (it only has one directory), it must not disturb other programs that use this environment variable therefore let’s change its value:
Alternatively, if we have access to the GUI we can go to:
System Properties -> Advanced -> Environment Variables… -> System variables
%PATH% Hijacking Privilege Escalation
To create a vulnerable $PATH hijacking scenario we need the following requirements:
PATH contains a writable folder.
The writable folder is before or above the folder that contains the legitimate binary.
The “vulnerability” or “problem” lies in the fact that if we’re able to write to a directory that’s before or above the valid program/command/tool/application, we can then create a malicious binary with the same name as the valid program/command/tool/application. Once it is found Windows will stop searching for the program since it will assume that it found it and it will execute it:
1
2
3
4
5
6
C:\Windows\system32# First search in here, if its not here then continueC:\Windows# If we have write access then we can create a malicious binary with the same name as the valid binary. Once the binary -name- is found Windows will stop searching for the program since it will assume that it found it and it will execute it.C:\Windows\System32\WbemC:\Windows\System32\WindowsPowerShell\v1.0\C:\Windows\System32\OpenSSH\# Valid binary is here but it won't be executed since it already found it and it stopped searching.C:\ProgramFiles\dotnet\
Note: Remember this is the PATH environment variable of our current process, if this executable was executed by a Service, Task Scheduler, or something else. We would need to use the system %PATH% environment variable instead, depending on the configuration.
Because the directory “C:\Temp” is before “C:\Windows\system32\” in the PATH environment variable, the next time the user runs “cmd.exe”, our calculator will run, instead of the legitimate one in the system32 folder.
Using Process Hacker as Administrator we can see the process tree:
Process Hacker Process Tree
We can also view the token of the cmd.exe process and from there we can see that is running with High-Integrity Level and we have more privileges since cmd.exe was executed from an administrator PowerShell console:
Process Hacker Token
If this was executed by a service with the LocalSystem user (System Integrity Level) or by a task scheduler running with the highest level (High Integrity Level), or simply by an administrator (High Integrity Level) we could elevate our privileges as long as we replace the cmd.exe command with our payload or implant.