Bypassing Web application Firewall — Part 3
HTTP Parameter Pollution & Encoding Techniques
HTTP Parameter Pollution is an attack where we have the ability to override or add HTTP GET/POST parameters by injecting string delimiters. HPP can be distinguished in two categories, client-side and server-side, and the exploitation of HPP can result in the following outcomes:
TTP Parameter Pollution — PP
Override existing hardcoded HTTP parameters
Access and potentially exploit uncontrollablevariables
WAFs, which is the topic of interest, many times perform query string parsing before applying the filters to this string. This may result in the execution of a payload that an HTTP request can carry. Some WAFs analyze only one parameter from the string of the request, most of the times the first or the last, which may result in a bypass of the WAF filters, and execution of the payload in the server.
Let’s examine the following HTTP Request from a user to the web application:
Now, let’s change the request to see the response of the server:
After this, the request executed in the server will be:
This is a result of a WAF that didn’t correctly parse all the parameters of a request, and now the user can supply specially crafted parameters, like the “action=withdraw” in the example, and perform a malicious action in the server side.
In all the attacks we saw, and that we are going to see, a way to bypass many restrictions is to encode our strings, and there are many ways to do this. Encoding is useful, for example, in HPP that we saw earlier, and we may trick a WAF that cannot normally be bypassed to allow us in if it does not use decode schemes, or if it does not include encoded strings in its filter rules. The same applies to SQL Injection and XSS attacks that we are going to see later in this course.
As you will see, there are many encoding types that may be supported from a different layer of the server. So, a request that we may make will pass from most of these layers, some of them will try to decode it. Our job here is to find which decode method, or methods, the layer that we are attacking is using and try to use others, or double encode our string to be able to bypass the layer of our scope. Let’s examine some of the encoding methods.
URL Encoding (Hex Encoding)
URI standards permit URLs to contain only the printable characters in the US-ASCII charset. Also, some characters are restricted because they have special meaning in the URL scheme or the HTTP Protocol. This scheme is mostly used to encode problematic characters, like these with special meaning, so that they can be transported over HTTP without any conflicts. This works by using the hex equivalent for certain characters, such as for ‘ or for< , which we can understand by the% prefix, followed by each character 2 digit ASCII code in hexadecimal. Some char- acters that we may face are:
Let’s see an SQL example from part 3:
This SQL query string, URL encoded, will be like this:
We can easily encode and decode with this method with the following website: http://meyerweb.com/eric/tools/dencoder/
Another rather simple way of encoding is using a null byte () prior to any characters that the WAF filter is blocking. For example, the SQL Query we used earlier will be:
‘ union select password from mySQL.user limit 1 /*
WAFs will commonly ignore everything after the null but pass the entire string to the web server where it is processed.
Adding inline comments can help the string to bypass the WAFs filters and reach its target. This is mostly used in SQL queries, where we can add comments in the form of or /**/SELECT/**/ . For example, the SQL query used earlier, will be:
Or, if we want to step it up a bit, we can use ways like the following: ‘/**/uni/**/on/**/sel/**/ect/**/password/**/from/**/mySQL.user/**/limit/**/1 Where we can separate SQL keywords with comments.
Dropping a space or adding spaces that won’t affect the SQL statement may be a good strategy in an attack to bypass WAF filters. For example:
Or even adding a special character, like new line or tab that won’t change the SQL statement execution, can be effective.
Here we can change the way we sent the SQL queries in an SQL attack to WAF by inserting a special character in the middle of a keyword that will be removed by the WAF, and the query will be executed correctly in the final tar- get. The previous example will be something like this:
‘ uni<on sel<ect password from mySQL.user limit 1 /*
It is similar to the comment way we saw earlier, but here if we determine a character that is blocked by the WAF, we can use it for ouradvantage.
Char() function in MySQL can be used to replace English char variables. For example, let’s take the following example that can be used for exploitation of the DVWA:
UNION select table_schema,table_name FROM information_Schema.tables where ta- ble_schema = “dvwa” -
This statement with character encoding will be:
As you can see here, we replaced the “dvwa” with which is the MySQL char() function that uses ASCII codes inside and we use it to inject into MySQL without using double quotes that many times gets filtered by WAFs. also works on almost all other databases but sometimes it can only hold one character at a time, like for example char(0x##)+char(0x##)+… So if the one way does not work for us, we have to try an- other.
Many times keywords themselves are blocked from the WAF. An encode way to bypass this filter is by replacing the keywords we use with others, so once the WAF strips the keyword, our desired keyword will remain, and be executed in the next layer. Taking our SQL example:
Here is an example that the WAF is blocking the select keyword. Once the query passes and gets filtered, the mid- dle select keyword will be deleted and the sel from the start and ect from the end will get merged and form a new select keyword that will get executed in the server.
With string concatenation, we can break up SQL keywords and bypass WAF filter rules. Concatenation syntax varies based on the database engine. For example, in a MS SQL engine, the select 1 statement can be changed as below
EXEC(‘SEL’ + ‘ECT 1’)
As we will see in our examples, this is an effective way to bypass WAFs.
As we said in the start of this section, there are many layers that may exist until our malicious code reaches its desti- nation. Until now, we examined single ways to encode our strings, but what happens when more than one decode takes place in the chain? The answer is simple, we encode more than one time.
Let’s take a scenario where the web server does URL decoding but WAF also does URL decoding for security pur- poses. Our SQL injection example this time will be:
This string is the same as in our URL Encoding example but it has been encoded one more time in the same way. In this situation and when the WAF decodes this string, it will fail to block it, because it is still encoded and it cannot find the malicious string. In the stage of the web server, the string will be decoded again, and executed correctly.
The double encoding way can be used in many situations and combinations. We have to fingerprint correctly the
server side and the WAF to be able to know what decodes take place and perform the corresponding encodings.
Bypassing WAF with SQL Injection
Until now, most of our examples used SQL queries for WAF Bypassing. This happens because the most com- mon attack used in WAF bypassing is SQL Injection. But let’s start with SQL itself. SQL (acronym for Structured Query Language) is a query language used in the design
and management of databases. Most of the products used today are relational databases, like SQL Server, MySQL and other. Databases have data stored inside a table-like structure that has rows and columns.
The queries that you may have seen many times in this course are strings that with the use of select statement re- trieve data from the database in the call of the client. Except for select, there are some other statements that are mostly used in SQL Injection, which are the following:
query to retrieve some data from the server, the UNION operator can be used to add another SELECT statement and have both select statements executed in the database. For example, let’s take the following query:
Here the query is called to return all the records from the table users that have the fname field equal to Tom. (The * character is a wildcard in SQL and selects all the columns in a table) Now, the use of the UNION operator in this query is pretty simple:
Here, the query does everything that it did earlier, and it adds in the results the records of the passwords row in the users table. So, you can understand that by supplying this UNION operator on a vulnerable web application that al- ready supplies a query to the database, it will add the query of our choice in this “equation”. Let’s now see what ex- actly is SQL Injection and how we can use it in WAF Bypassing.
SQL Injection is a code injection attack where the attacker supplies a malicious crafted query to the database with the intention of data extraction from it. It is a really common vulnerability,despitethefactthatitisoneoftheolder ones. To see how this vulnerability works, imagine a search field in a website where we supply a names, and it returns info about that corresponding name. The database executes the following query:
If this database is vulnerable and we supply a ‘ it will return an error because we will have the following results in the query:
An example attack in this situation would be:
HerewesuppliedOR’1'=’1' -whichresultedinalogicalexpressionthatalwaysresultsasTrue,because every time, and with the or operator, we need only one of the two to be true for the query to return everything in the users table. The double — symbol is added, so everything else after them is commented out and not executed.
Blind SQL Injection is the most common type of SQL injec- tion, and its difference from the simple one is that the re- sults of this type of injection are not visible to the attacker. The page will not display the results as in the previousexample but it will display them depending on the logical statement results that will occur from our injection. It is a dif- ficult vulnerability to exploit because it needs time to test many things one by one, and most of them will be unsuc- cessful requests. Let’s take the previous example with the name search field. In a situation like this, which is the most common one in a penetration test, the query happens completely on the server; we don’t know the names of the database, table, or fields, nor the query string. In this situation, the simple that we provided earlier, will give us no result, and this is what a blind SQL injection does.
This time we need to supply something like this:
As you can see, here it is needed for both of the Boolean expressions to be true, for tom to equal a record in the da- tabase and 1=1 to be true, which always happens. If this returns a result, it means that it is vulnerable to Blind SQL Injection and we can continue to fingerprint the database.
A good example on how to continue would be:
The “part checks to see if the version of MySQL is version 5 (through the check), and if it is running version 5 then the page will just load normally because SQL will run without a prob- lem. And this is the way of blind sql injection. We have to supply questions to the database that if they are true, the page that corresponds to the first part of the string that we supplied will load.
These types of attacks are tested many times by automated tools, like sqlmap, but be careful, because these types of tools are really noisy and can result in numerous junk reports in the database you are testing, a thing that you surely don’t want.
Finally, after the MySQL fingerprinting example we saw, there is another similar way to find and fingerprint an Oracle based database by submitting the following query in the database:
In situations like these, not only can we retrieve information about the database software, but the details about the version are also returned, so there is no way to check for a specific version, but we can just supply the @@version in the query for MySQL. If the underlying database is not up to date, new vectors of attack, such as buffer overflows,could be explored.
It is also possible to exploit the vulnerability with the method of blind-SQL Injection by replacing SQL functions that get to WAF filter rules with their synonyms. For example:
Let’s now see some examples of filter rule bypass on WAF, with SQL Injection.
WAF Filter Rules Bypass with SQL Injection
As we said, filter rules are the main aspect of security of a WAF, and we need to be able to bypass them if a WAF ex- ists in front of a server we want to scan. Now, let’s say that we are testing the http://website.com/?id=1 which has the parameter and it seems vulnerable from our basic
steps. A first way to supply a query that gives us the filter rule is a simple one like:
Here the query is normal with no encoding, and WAF detects it immediately and blocks us. Now, there are many ways to bypass this rules as we saw earlier, so let’s examine some examples:
In this situation, we replace the substring() function with mid(), which can have positive results, as many of the WAFs filter only a small amount of functions.
Here, we concatenate our string with the concat() function, that may help us in situations that the WAF filters the whole query. By concatenating it, we are sure that our query will not be blocked from this type of filter.
Many WAFs filter only one layer of brackets, so an effective way of bypass is to add more layers that will trick the
WAF to think that there is nothing malicious inside the bracket.
Now let’s see some real world filter bypass examples for industry used WAFs.
PHPIDS — PHP Intrusion Detection System PHPIDS (PHP Intrusion Detection System) is an open source PHP Web Application Intrusion Detection System. Because of its nature, it is widely known and used, and you can find it in many web servers. PHPIDS has some default filter rules that you can find in its GitHub page. Now, let’s
perform our first attack in a system that uses a MySQL database:
Supplying this, the WAF blocks us, because as you can see, it is pretty straight forward that we are supplying an SQL query. Let’s change this query to something like this:
Here you can see that we changed the Where user=1 with the limit statement, which is used to retrieve records from one or more tables in a database and limit the number of records returned based on a limit value. So, even not knowing the rule, and changing the query like this, we now know one of the rules.
Continuing, let’s give a really simple but powerful query we saw earlier, the 1 OR1=1.
We can see here that the WAF blocks us, and it is normal as it is a pretty standard and well known malicious query. But, its bypass is pretty easy too. We just have to change the numbers with their hex equivalents to be able to by- pass the WAF and reach the target SQL database:
Finally, in version 0.6.1.1 of PHPIDS that we are checking out, a bypass similar to the generic one we saw earlier takes place, and if we replace the substring() function, with the mid() one, we can bypass the firewall.
In mod_security’s 2.5.9 version, we have many filters that can be bypassed. Twoof the common ones that we saw again until now are the substring — mid alteration and the hex encoding of the expression. We can also alternate
which will bypass the filter correctly. Also, this WAF is filtering the drop statement that we can change with this:
HPP Exploitation with SQL Injection
We talked about HTTP Parameter Pollution in the start of this module, and now that we have an idea of the SQL In- jectionattacks,let’scombinethemtoexploitHPP. We have to start by saying that an HPP attack’s success de- pends on the environment of the application that we are
attacking. Now, the logic behind this attack is that we can separate a query into many parts by adding parameters.
In the final destination, this query will be merged and get executed by the server if the web site has the HPP Vulner- ability. This vulnerability will look something like this in the SQL request code that a web application performs:
And it can be exploited by the logic we saw earlier:
As you can understand, we used many &id parameters to concatenate the query, and we used SQL comments to comment out these parameters in the final SQL server destination. With this technique, only the query is left in the end to be executed. So, combining the code that the form executes and the query we supply in the parameter, we
HTTP Parameter Fragmentation — HPF
HTTP Parameter fragmentation is similar to HPP but with the addition that we are not using the same parameter again and again. In HPF, we are attacking web pages that have more than one parameter, and the SQL query we are trying to inject gets fragmented into as many pieces
as the numbers of the available parameters. An example of the vulnerable code could be:
As you can see, this page produces a query with two parameters, a and b, and sends both of them to the server. By supplying the following:
we are commenting out all the following query from after the injected one, and this request doesn’t allow anyone to conduct the attack, because we can see in the vulnerable code that it has the AND operator, so it needs both the parameters.
To exploit code like this, we can change our previous query to something like this:
Here you can see that we are separating the query in both of the parameters, so the code gets True, as both the parameters exist, and we add the SQL comment in the right places, so the parameters will be commented out in the end, and the query will be merged into one piece. The final query from the first vulnerable code, will be:
Another example with more than two parameters could be:
The same applies here, with three part fragmentation, because we have three parameters. The final SQL parameter in this situation, will be:
Bypassing WAFs with SQL Injection Normalization
Many times in the previous examples, we talked about normalization without really mentioning it. Normalization is the process of adding comments and other symbols that the WAF strips inside keywords that the WAF also strips, so the final result will be our desired query that we
want to be executed in the database. It is a really good WAF bypassing method, but we have to know some of the
filters that the WAF uses for the attack to success.
In the example we saw earlier that didn’t let anyone conduct an attack, due to filtering from the WAF
If there is a corresponding vulnerability here in the WAF, this request will be successfully performed in the server. After being processed by WAF, the request will become:
This example works in case of cleaning of dangerous traffic by the WAF, and not in case of blocking the entire re- quest or the attack source. Similarly, the following request doesn’t allow anyone to perform this query:
But if we change it to something like this, and the WAF is vulnerable to normalization techniques:
This query will be executed completely in the SQL database, and it will look something like this:
This example works in case of excessive cleaning of incoming data (replacement of a regular expression with the empty string). As you can understand, instead of the comment symbol, any symbol sequence that WAF cuts off can be used (e.g., #####, ), but we have to know, and we can find it out by fingerprinting the filter rules of the WAF.
Buffer Overflow + SQL Injection = Bypass WAF
For those who don’t know, “a buffer overflow, or buffer overrun, is an anomaly where a program, while writing data to a buffer, overruns the buffer’s boundary and over- writes adjacent memory locations.” We can exploit this vulnerability that exists in some WAFs that have special coding background.
WAF Bypass with SQL Injection Examples
Let’s close the section of SQL Injection WAF Bypass with some practical examples. As we saw in the start, one of the most common ways of bypass is with encoding. But we just saw encoding of a whole keyword, or even dou- ble encoding. If we see that none of this works, we can
also advance it a bit, and only encode a part of a keyword, and this is a way that not many manufacturers have in mind. So, in this situation, we replace some characters with their HEX(URL-encoded) equivalents. For example:
So now the WAF will have the original and the hex encoded keyword in the filter rules, but it is really difficult to have all the possible alterations inside, so trying a different character each time can give us the golden ticket. As you can see here, we just supplying union select, with some characters encoded to HEX.
The apostrophe is a commonly blocked character by WAFs, because it usually causes problems with SQL databases. Now, in this example, if the WAF filters and removes the apostrophe, the resulting query will give 15 union select 1,2, and this is a pretty easy bypass that happens really often. Some more examples that can give you ideas about how you can use encoding cleverly to bypass WAFs can be seen below:
As you can see, the possibilities are endless, and WAF bypassing, when we are heading for SQL Injection, stops only by our imagination. There are many things we can do, many encoding schemes we can combine, and all these get multiplied when we have deep knowledge of SQL Injection and queries and we can make many variations of the same query.
Originally published at https://learncybersec.blogspot.com.