Tags:
In October 2001, the DShield.org site was just about a year old, I was alerted to a flood of reports hitting the site. Looking at the reports in more detail, I found out that most of them are due to blocked ICMP packets being reported to the site. Further investigation revealed that the reports where due to a new worm, later dubbed "Nimda" [1]. The Nimda worm was the latest exploitation of a path traversal in IIS. This particular path traversal was probably the highest impact instance of this basic coding flaw.
What had happened? Path traversal (CWE #22) [2] is a vulnerability allowing an attacker to specify a path outside of a restricted "safe" directory. Typically, this involves the use of ".." to move up in the directory tree outside of the intended location. Lets look at some example pseudo code to illustrate the issue. For example, we use a little "wrapper" script to provide access control for static PDF files. The PDF files live in "/pdf" . Our (pseudo) code would look like this:
$sFilename=getUserData("Filename") $sPath="/pdf/" if ( checkUserAccess($sFilename) ) { open($sPath.$sFilename); }
Here, we check if the user has access to the file, if that is the case, we just append the user provided file name to the static directory path and retrieve the file. An exploit would pass a filename like "../etc/password", which would retrieve the file /etc/password.
The key to preventing this exploit is to normalize paths before retrieving the file, or validating the file name to avoid directory traversal. A safe filename should not allow "..", and most likely shouldn't allow "/" (or "\" on windows systems) either. A "/" may be allowed if access is provided to subdirectories.
There are a number of other means to prevent directory traversal, which can be summarized in a few steps:
- during the design phase, try to limit the path to a simple directory and easy to validate filename ("alpha numeric"). This will ease implementation later.
- setting up the system, the impact of a path traversal can be limited by limiting permissions so the application can only read files from "safe" directories.
- the file name has to be normalized before being validated.
- next the file name needs to be validated (easy if we limit ourselves to alpha-numeric names).
- finally, after concatenating the path to the filename, we verify that the file is still inside the proposed directory.
PHP for example has a "realpath" function which will resolve all ".." style directory traversal and return a normalized path. However, be aware that the path is only returned if the file exists on the system the code is run. If not, an empty string is returned.
So what was the big deal in July 2001? The problem was a directory traversal in IIS 5. A web server should only retrieve files located in its document root. IIS checked for urls like "http://example.com/../../boot.ini". However, it converted unicode characters AFTER validating the file name, not before validating the file name.
One of the URLs used by Nimda was: GET /scripts/..%255c../winnt/system32/cmd.exe?/c+dir . The '%255c' part is the Unicode representation of a backslash. The particular vulnerability was made worse by the IIS feature to execute code if the URL starts with "/script" (similar to "cgi-bin" in Apache). The example above will execute 'cmd.exe' and return a directory listing. This could be use to verify the vulnerability and then execute more malicious code on the system.
- http://www.sans.org/reading_room/whitepapers/malicious/the_nimda_worm_an_overview_95
- http://cwe.mitre.org/data/definitions/22.html