Identifying Server-Side Functionality

It is often possible to infer a great deal about server-side functionality and structure, or at least make an educated guess, by observing clues that the application discloses to the client.

Dissecting Requests

Consider the following URL, which is used to access a search function:

As we have seen, the .jsp file extension indicates that Java Server Pages are in use. You may guess that a search function will retrieve its information from either an indexing system or a database; the presence of the OrderBy parameter suggests that a back-end database is being used, and that the value you submit may be used as the ORDER BY clause of a SQL query. This parameter may well be vulnerable to SQL injection, as may any of the other parameters if they are used in database queries.

Also of interest among the other parameters is the isExpired field. This appears to be a Boolean flag specifying whether the search query should include content which is expired. If the application designers did not expect ordinary users to be able retrieve any expired content, changing this parameter from 0 to 1 could identify an access control vulnerability.

The following URL, which allows users to access a content management system, contains a different set of clues:

Here, the .aspx file extension indicates that this is an ASP.NET application. It also appears highly likely that the template parameter is used to specify a filename, and the loc parameter is used to specify a directory. The possible file extension .tpl appears to confirm this, as does the location /default , which could very well be a directory name. It is possible that the application retrieves the template file specified and includes the contents into its response. These
parameters may well be vulnerable to path traversal attacks, allowing arbitrary files to be read from the server .

Also of interest is the edit parameter, which is set to false. It may be that changing this value to true will modify the registration functionality, potentially enabling an attacker to edit items that the application developer did not intend to be editable. The ver parameter does not have any readily guessable purpose, but it may be that modifying this will cause the application to perform a different set of functions that may be exploitable by an attacker.

Finally, consider the following request, which is used to submit a question to application administrators:

POST /feedback.php HTTP/1.1
Content-Length: 389

As with the other examples, the .php file extension indicates that the function is implemented using the PHP language. Further, it is extremely likely that the application is interfacing with an external email system, and it appears that user-controllable input is being passed to that system in all relevant fields of the email. The function may be exploitable to send arbitrary messages to any recipient, and any of the fields may also be vulnerable to email header injection.

Extrapolating Application Behavior

Often, an application behaves in a consistent way across the range of its functionality. This may be because different functions were written by the same developer, or to the same design specification, or share some common code components. In this situation, it may be possible to draw conclusions about server-side functionality in one area and extrapolate these to another area. For example, the application may enforce some global input validation checks, such as sanitizing various kinds of potentially malicious input before it is processed. Having identified a blind SQL injection vulnerability, you may encounter problems exploiting it, because your crafted requests are being modified in unseen ways by the input validation logic. However, there may be other functions within the application that provide good feedback about the kind of sanitization being performed — for example, a function that echoes some user-supplied data back to the browser. You may be able to use this function to test different encodings and variations of your SQL injection payload, to determine what raw input must be submitted to achieve the desired attack string after the input validation logic has been applied. If you are lucky, the validation works in the same way across the application, enabling you to exploit the injection flaw.

Some applications use custom obfuscation schemes when storing sensitive data on the client, to prevent casual inspection and modification of this data by users. Some such schemes may be extremely difficult to decipher given access to only a sample of obfuscated data. However, there may be functions within the application where a user can supply an obfuscated string and retrieve the original — for example, an error message may include the deobfuscated data which led to the error. If the same obfuscation scheme is used throughout the application, it may be possible to take an obfuscated string from one location (for example a cookie), and feed it into the other function to decipher its meaning. It may also be possible to reverse engineer the obfuscation scheme by submitting systematically varying values to the function and monitoring their deobfuscated equivalents.

Finally, errors are often handled in an inconsistent manner within the application, with some areas trapping and handling errors gracefully, while other areas simply crash and return verbose debugging information to the user . In this situation, it may be possible to gather information from the error messages returned in one area and apply it to other areas where errors are gracefully handled. For example, by manipulating request parameters in systematic ways and monitoring the error messages received, it may be possible to determine the internal structure and logic of the application component concerned; if you are lucky, aspects of this structure may be replicated in other areas.

Mapping the Attack Surface

The final stage of the mapping process is to identify the various attack surfaces exposed by the application, and the potential vulnerabilities that are commonly associated with each one. The following is a rough guide to some key types of behavior and functionality that you may identify, and the kinds of vulnerability that are most commonly found within each one.