实验吧——WEB-因缺思汀的绕过

因缺思汀的绕过

在这里插入图片描述
拿到题目发现什么都没有,看一下源码
在这里插入图片描述
发现有一个source.txt文件,打开得到php源码

<?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){ #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);
?>

接下来就是分析源码,可以看到我们输入的uname在数据库查询uname和key,再将key和我们输入的pwd比对,相等就打印flag。

首先我们可以看到过滤了一些sql语句

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

因此以前常规的sql注入语句不能再使用

但我们注意到它的查询语句

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

只要在满足不适用它过滤掉的SQL关键词的情况下可以使用 limit 的返回来确定数据库中总共有几行数据,于是我们构造:

1’ or 1 limit 1 offset 0#

1’ or 1 limit 1 offset 1#

1’ or 1 limit 1 offset 2#

我们发现当它是2时返回“一颗赛艇!”,其他都是返回“亦可赛艇!”,说明数据库只有两条数据。

接下来我们只要使得if($key['pwd'] == $_POST['pwd'])判断为true,我们即可拿到flag。

于是可以利用group by pwd with rollup在查询中的一个特点,他可以返回pwd所在的那一条记录,通过limit控制返回哪一条,因此他不可以返回多条,一旦返回2条及以上,pwd就会为空,但同一条记录中的其他字段则是正常的,然后在pwd里不写值,if就为true了。

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44677409/article/details/88994029