New coding security vulnerability found that might affect commonly used command scripts on file-servers
What if we told you that a normal user in your network could take over the control of your Windows file-servers by just creating a special (but no so complex) directory-name in one of the directories he has access to?
In order to succeed, all the user has to do is create a folder with a special name and that you regularly run command-shell scripts for management purposes that have a (pretty common) coding vulnerability.
Sounds scary? It is! Read on for detailed info!
Let’s just start with a simple example:
Open a command prompt.
Create an environment variable that contains the & (ampersand) character, for example:
(note that the ∧ is necessary at this point; you’ll understand later on why)
SET B will show:
Now, the interesting part; type the following and look at the result:
The command shell first expands the variable B and then interprets the whole line, whereby the & character is interpreted as a command separator:
So, ECHO %B% becomes: ECHO T1&T2
The command shell sees 2 commands, separated by the command separator &:
And of course, T2 is not a recognized program.
Let's take this a step further:
Same result if you execute
What did we achieve? We managed to execute a command, just by showing an environment variable or assigning an environment variable to another.
Interesting … but is this a security vulnerability?
Because if somebody can create or modify an environment variable on your system, they can do a lot of things … including executing malware directly. So, although this might look weird (or at least unexpected) OS behavior, there’s no way to immediately turn this into an exploit.
An exploit implies that the attacker can cross security boundaries, in such a way that the victim is only executing a trusted, common action; For example, a vulnerability in acrobat reader can be turned into an exploit if the attacker manages to execute code on the victim‘s computer (=crossing security boundaries), while the user just executes a common, trusted action (like opening a web-page or opening a PDF document in a mail).
In our sample above, we have not crossed any security boundary. One could look for attack scenarios whereby the victim is tricked into changing an environment variable using social engineering tricks, but I would not really call that an exploit.
So, we need some more elements to turn this behavior into an actual exploit.
Crossing a security boundary implies that you can execute something in another user’s context (and preferably a more privileged user) and/or on a remote system.
The problem is that setting an environment variable (by a normal user) is only valid for that user’s environment itself; he cannot set an environment variable for another user, unless he is administrator. Or set an environment variable on another computer. (attacks on a system executed with administrator privileges are not exploits, since they violate the “10 immutable laws of security”)
But wait; there is actually a way to affect an environment variable of another user: using directory-names and %CD%
%CD% is a built-in environment variable that shows the current directory.
You see the current path shown up to T1 and the "PING" command being started at the same time.
We now have a way to cross security boundaries.
Only obstacle is: how can we ensure that another user browses to that directory we have just created and then executes the ECHO %CD% command or something like SET CurrentPath=%CD%? And preferably, without using any kind of social engineering tricks?
"Hey helpdesk, can you open a command shell as administrator, browse to this particular directory and execute ECHO %CD%?" That doesn’t look like a good exploit…
On a workstation, chances that you can use this as an actual exploit are very low.
Which systems do we have in our enterprise networks that allow users to create directories AND typically have these old-style batch-files (which might contain code like “SET CurrentPath=%CD%”)?
While everybody is moving to SharePoint or other document-management systems for obvious reasons, the file-servers are left as second-class citizens in the enterprise networks and scripts that used to run fine 15 years ago, still run fine today and are rarely updated. In many companies, you will hence still find some .bat or .cmd files for common system-administration tasks on these servers…
It took us just half an hour or so browsing through some script repositories on the internet to find a script that did exactly what we wanted. You can find it here: http://www.robvanderwoude.com/sourcecode.php?src=own_2k
Update: Rob Van Der Woude has meanwhile updated all potentially vulnerable scripts on his site and has also created a testing-application that you can use to test your own command-shell scripts for this vulnerability. More information can be found here: http://www.robvanderwoude.com/news.php
So, given that this script is executed on a regular basis (e.g. as a daily background task) and likely under elevated privileges (to ensure it has access to all subdirectories on a file system), the only thing a malicious user needs to do is to create a directory with malicious code on the file-server:
Where this directory contains a file “malware.exe”.
When the script runs, malware.exe gets executed under a privileged user on the file-server and… the user can do whatever he wants on that system.
An even simpler example is:
And create a file “malware.bat” that contains:
Net localgroup administrators domain\user1 /add
Net user administrator newpassword123!!
That’s how simple hacking can be done
Ok, help, I’m scared! What can I do?
The fix is as simple as the exploit. Look through the code and identify where the assignment of %CD% is done and ensure you have put quotes around any instance of %CD%. So, replace this with something like Set CurrentPath=”%CD%” (note the quotes around %CD%). That’s it. No rocket science here either…
Is Microsoft going to fix this issue?
Nope … they’re not.
We contacted Microsoft for this and they stated following:
They have a valid point, as the exploit is the result of running a script that is vulnerable. Without the script, no vulnerability.
In the end, it all comes back to the same root-cause we’ve seen so often: INPUT VALIDATION!
If you use untrusted input (in this case a directory name), you need to either to check if it is valid (which is quite hard to achieve in a batch-file) or sanitize it. In this case, sanitization is done by putting quotes around the %CD% variable in the script.
My only point of criticism is however that Microsoft has never warned about possible security implications when omitting the quotes around “%CD%”.
When Microsoft states that "The current guidance around %CD% is to encapsulate it in quotes", they have no KB article or equivalent that explicitly gives this advice. Yes, they do have some articles that clarify that putting quotes around environment variables is a good practice (see e.g. the very old KB articles 102739 and 121170), but no mentioning of any possible security issues in those articles
But, I hope you are informed now and do a quick check on your old file-server-management-command-shell-scripts.
The "file-server" exploit scenario is however just one possible scenario for this class of command-injection vulnerabilities. Any other way found by an attacker to insert an "&" in a custom or built-in environment variable could trigger malicious programs, when used by a command-script; for example, a domain-user containing an "&" character in its name (%USERNAME%) could in the same manner trigger malicious code, although an effective exploit scenario has not yet been identified for this case.
Also the proposed fix to put quotes around the variable, only works for %CD%, but not for other environment variables, since they can contain quotes themselves! For example, try:
and you will see that calc gets executed, despite having quotes around %B%.
Note: this does not apply to %CD%, since a file or directory-name cannot contain a quote character.
Feel free to let us know if you have found this to be an issue in your company or not (after you’ve fixed the issues of course) or if you have found other scripts that also trigger this vulnerability. You can do so by sending a mail to firstname.lastname@example.org (this information will of course NOT be shared with anybody outside our company).
Sample script that triggers the exploit
(Original script can be found at http://www.robvanderwoude.com/sourcecode.php?src=own_2k, but might have been updated meanwhile)
Update: the author has corrected his scripts meanwhile and has also made a tool available that allows you to test your own command-shell scripts for this vulnerability. More info can be found here: http://www.robvanderwoude.com/news.php
@ECHO OFF :: Windows version check IF NOT [%OS%]==[Windows_NT] GOTO Syntax :: Only one single command line parameter specified? IF [%1]== GOTO Syntax IF NOT [%2]== GOTO Syntax :: Help wanted? ECHO.%* | FIND "?" >NUL IF NOT ERRORLEVEL 1 GOTO Syntax :: No wildcards allowed ECHO.%* | FIND "*" >NUL IF NOT ERRORLEVEL 1 GOTO Syntax :: Was a valid directory specified? DIR /AD /X "%~1.\..\%~n1*" 2>NUL | FIND "<dir>" | FIND /I "%~n1" >NUL IF ERRORLEVEL 1 GOTO Syntax SETLOCAL ECHO."%~f1" TAKEOWN "%~f1" PUSHD "%~f1" TAKEOWN *.* SET StartDir=%CD% FOR /F "tokens=* delims=" %%A IN ('DIR /AD /B "%StartDir%.\*.*" 2^>NUL') DO ( ECHO."%%~fA" ATTRIB -H -R -S "%%~fA" TAKEOWN "%%~fA" CD "%%~fA" ATTRIB -h -r -s *.* >NUL 2>&1 FOR /F "tokens=* delims=" %%? IN ('DIR /A-D /B "%%~fA.\*.*" 2^>NUL') DO ( ECHO."%%~f?" TAKEOWN "%%~f?" ) CALL "%~f0" "%%~fA" CD "%StartDir%" ) POPD ENDLOCAL GOTO:EOF :Syntax ECHO. ECHO OWN.bat, Version 0.59.59 FINAL BETA for Windows 2000 ECHO Recursively take ownership of entire specified directory tree. ECHO. ECHO Usage: OWN startdir ECHO. ECHO Uses TAKEOWN.EXE from the Resource Kit. ECHO. ECHO Written by Rob van der Woude ECHO http://www.robvanderwoude.com ECHO. ECHO WARNING: This batch file hasn't been tested extensively yet. ECHO Use entirely at your OWN risk.