实验吧-因缺思汀的绕过

时间:2022-07-22
本文章向大家介绍实验吧-因缺思汀的绕过,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

实验吧-因缺思汀的绕过

题目链接:http://www.shiyanbar.com/ctf/1940

查看源码,可以看到注释里提示了源码的位置,访问source.txt得到源码,然后开始审计吧!先把源码贴出来

<?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){   
        print "水可载舟,亦可赛艇!";
        exit();
    }
}

$filter = "and|select|from|where|union|join|sleep|benchmark|,|(|)";
foreach($_POST as $key=>$value){ 
    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);
    if($key['pwd'] == $_POST['pwd']) {
        print "CTF{XXXXXX}";
    }else{
        print "亦可赛艇!";
    }
}else{
    print "一颗赛艇!";
}
mysql_close($con);
?>

通读源码可以发现,我们输入的username与password都使用了黑名单过滤,这也告诉我们是有机会的,毕竟黑名单存在绕过的可能性。黑名单如下:

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

过滤了之后,执行了一条sql语句:

$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";

这条语句拼接了我们输入的uname,也就是说注入点只可能存在于uname字段,接下来判断了sql语句的查询结果是否只有一条数据,如果成立就把我们post过去的密码与数据库中存储的密码进行比对,如果相同就打印flag!

mark 这儿也就是我们需要绕过的地方,其中最主要的又是绕过密码的比较。我一开始的思路是使用union语句构造一个类似于下面的语句:

}' union select 123,123#

然后密码输入123,就可以绕过了。但是发现绕不过它的过滤条件,搞了半天结果还是自己sql语句玩的不够熟练,,这里是巧妙地用了select过程中用group by with rollup这个统计的方法进行查询。group by with rollup会在统计后的产生一条null信息,然后在pwd里不写值,if就为true了。

所以只要我们用户名输入如下语句:

}' or 1 group by pwd with rollup limit 1 offset 2#

(该数据表中只有两条信息) 然后密码部分保持为空就可以得到flag。

mark