There is a growing possibility of encountering some sites on the Internet that hide parameters passed to an application using the mod_rewrite Apache module. Often, web developers have an illusion that this can protect a web application against attacks, such as SQL Injection, Cross-Site Scripting, etc. In fact, this is a common delusion, similar to the delusion that hiding “fingerprints” of services improves the security of the services. There is no doubt that the use of mod_rewrite for hiding parameters passed to an application, just as hiding fingerprints, is a certain obstacle for an attacker. However, as they say, “there is no such obstacle that could not be surmounted”.
- search engine optimization (SEO);
- protection against direct downloads via hiding real location of a file;
- hiding the hierarchy of incoming web application parameters, directories and scripts via centralized dynamic modification;
- access control; mod_rewrite has the ability to check HTTP header values (including cookie value) for compliance with the rules and perform (or not to perform) redirection depending on the results of the check.
- It is difficult to recognize the real purpose of an URL element. For instance, with a hyperlink of the type \”http://www.example.com/main/search/search_bar\”, it is impossible to understand, which of the URL elements is the relative path from the web server root directory, which element represents the script name, and which one is the script parameter. It really complicates web application structure analysis.
- It is difficult to determine the programming language used for developing the application. The \”http://www.example.com/main/articles/article.html\” link may refer to a PHP, ASP, or Perl server script, or a static HTML page.
- The existence of regular expressions, which can be used in the rewrite rules of mod_rewrite, allows filtering of input parameters (the example is provided further in the text).
- When using automated vulnerability search, it is necessary to substitute certain characters (e. g. \”%2F\” (hexadecimal encoding) or \”%252F\” (double encoding) for slash \”/\”), since they are processed as early as on the stage of URL parsing by mod_rewrite.
- the use of multiple parameters in one request (the number of parameters is limited to URL maximum length: by default, to 8 192 characters for Apache 2.x and to 16 384 characters for IIS);
- the use of the binary search method (dichotomy) for determining necessary parameters;
- dictionary brute force, that is the use of well-known parameters and prefixes, such as id, count, etc., in combination with parameter names brute force (combined attacks);
- different ways of analyzing results;
- the possibility of recursive search for parameters (to search for the whole set of parameters of one script).
1. Determination of a real server script name
Sometimes, rules may rewrite any URLs, starting with a web server root directory, i.e. the
\”http://www.example.com/index.php\” request will already refer to an absolutely different script (RewriteRule ^(.+)$ script.php?$1). In such case, there is no point in further checking.
- common variable names (id, path, page, debug, cat, etc.) – the dictionary of common names;
- short variable names (1-5 characters) in the alphabet [a-z0-9-_] – brute force;
- «hybrid» names – using the following formulas:
- for the code that uses different suffixes and prefixes in variable names;
- array variables (param).
- the GLOBALS arrays (http://example.com/index.php?GLOBALS%5Bvar%5D=value);
- common _SERVER variables (in some cases they can also be rewritten);
- variables in combination with their zend_hash_key (to bypass vulnerable unset() functions).
- Numerical value: 0,1,2,… It is the simplest variant. The following 3 variants may be enough – 0, 1, and more than 1. The advantage is that the request string length is minimal, which minimally affects performance.
- Invalid value: «‘», «../», «a», etc. Invalid values are various character sets, which can lead to potential errors, the signatures of which allow determining the existence of a parameter.
- Fixed parameter value. For example, if the \”http://example.com/main/search/search_bar\” URL exists, it is required to fix the response of the script to the search_bar value and substitute this value for all parameters. The response that matches the standard value will allow determining the parameter which defines a specific position in a URL. (*)
- Random number. Generation of long enough random numbers (5-9 characters long) allows searching the script responses for matches. Random numbers increase the probability that there will be no type II errors (false positives).
(*) – For instance, the \”http://example.com/main/search/test\” URL refers to a search script with the «test» parameter. The purpose is to find the original search bar parameter, so it is required to fix the signature from \”http://example.com/main/search/test\” (e. g. \”the test request results\”) and perform the brute force of all parameters, using \”test\” as parameter value. The required parameter can be found through examining responses for the existence of the signature.
Create a request of the following type: \”http://example.com/script.php?param1=value¶m2=value&…&abc=value\”. The length of the URL request is limited to 8192 characters (for the Apache server). It means that all alphabetic parameters [a-z0-9] up to 4 characters long will require approximately 5880 requests to be bruteforced. If the Internet bit rate is acceptable, the brute force attack takes from 3 to 5 minutes.
- Determination using response length:
- The fastest and simplest method. It only requires finding out the length of the standard request (without parameters) and compare it to the length of responses with parameters.
- This method is inapplicable in the situations, when the script generates a response with unique content every time (banners, random content, the existence of a request string in a response).
- Determination using the signatures of variable random values:
- Decrease in number of false positives.
- Necessity to remove false positives, related to a normal situation when a random value is included in a response (for example, when request data are normally included in a response).
- Decrease in speed due to the increase in the length of parameter values (from 1-2 characters to 5-7 characters, which increases the required brute force time to 1.5-2 times for parameters that are up to 4 characters long).
- Determination using fixed responses (*)
(*) – For instance, when the purpose is to determine parameters on the page \”http://example.com/main/search/search_bar\”, it is required to substitute the \”search_bar\” value for all variables and monitor the response. The valid parameter will be the one that was included in the request, the response to which matches the content of the initial page.
- Determination using error signatures
- Brute force using alphabet, common parameters (specified in the params.txt file), or in combined mode («common parameter name» + «delimiter (_,-)» + «brute force»). It is also possible to set a flag to ensure the representation of every variable as an array (param);
- Use of dichotomy for parameters search;
- Search using response length (it is required to specify the initial page and its size);
- Possibility of specifying an initial page with parameters (e. g. \”http://example.com/index.php?page=admin\”) to search for multiple nested parameters (specified parameters will naturally be excluded from the check);
- Possibility of specifying characters that will be used as variable values.
Some of these mechanisms are implemented in the MaxPatrol Compliance and Vulnerability Management System.
Examples of the program’s performance:
Brute force up to 3 characters: