HPP全局污染实现的sql注入的毛病

农民  论坛元老 | 2024-8-12 18:13:13 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1012|帖子 1012|积分 3036

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目录
实验概述:
实验环境:
代码毛病分析:
 绕过第一个WAF
绕过第二个WAF:
        注入数据库名称:
        注入表名:
        注入列名:
        注入具体值:


实验概述:

1:什么是HPP的全局污染?
        HPP全局污染就是利用了php接收同样的参数是,对参数的处理来实现的一种毛病。本次毛病的实现就是利用该特点来实现的。
        我们利用两个点来实现的:
        (1):当传入两个参数的时候php会解析第二个参数
        (2):而且,我们还利用了web在解析  (.)  时会被解析为下划线(_),比如当我们传递一个i.d进入php时会被解析为i_d。

实验环境:

        搭建环境的代码如下:其中最为主要的逻辑处理的代码为index.php。所有源码可以去我的百度网盘下载;在搭建的时候只必要改一下数据库连接文件db.ini.php。
通过百度网盘分享的文件:daiqile
链接:https://pan.baidu.com/s/1qTAcTsJNHET-G4zkk44hLQ 
提取码:2cks



代码毛病分析:

index.php文件代码展示:
  1. <?php
  2. header("Content-type: text/html; charset=utf-8");
  3. require 'db.inc.php';
  4. // include('db.inc.php');
  5.   function dhtmlspecialchars($string) {
  6.       if (is_array($string)) {
  7.           foreach ($string as $key => $val) {
  8.               $string[$key] = dhtmlspecialchars($val);
  9.           }
  10.       }
  11.       else {
  12.           $string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&amp;', '&quot;', '&lt;', '&gt;', '(', ')'), $string);
  13.           if (strpos($string, '&amp;#') !== false) {
  14.               $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
  15.           }
  16.       }
  17.       return $string;
  18.   }
  19.   function dowith_sql($str) {
  20.       $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);
  21.       if ($check) {
  22.           echo "非法字符!";
  23.           exit();
  24.       }
  25.       return $str;
  26.   }
  27.   foreach ($_REQUEST as $key => $value) {
  28.       $_REQUEST[$key] = dowith_sql($value);
  29.   }
  30.   // 经过第二个WAF处理
  31.   $request_uri = explode("?", $_SERVER['REQUEST_URI']);
  32.   //i_d=1&i.d=aaaaa&submit=1
  33.   if (isset($request_uri[1])) {
  34.       $rewrite_url = explode("&", $request_uri[1]);
  35.       //print_r($rewrite_url);exit;
  36.       foreach ($rewrite_url as $key => $value) {
  37.           $_value = explode("=", $value);
  38.           if (isset($_value[1])) {
  39.               //$_REQUEST[I_d]=-1 union select flag users
  40.               $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
  41.           }
  42.       }
  43.   }
  44.   if (isset($_REQUEST['submit'])) {
  45.       $user_id = $_REQUEST['i_d'];
  46.       $sql = "select * from ctf.users where id=$user_id";
  47.       $result=mysqli_query($conn,$sql);
  48.       while($row = mysqli_fetch_array($result))
  49.       {
  50.           echo "<tr>";
  51.           echo "<td>" . $row['name'] . "</td>";
  52.           echo "</tr>";
  53.       }
  54.   }
  55. ?>
复制代码
对代码进行分析:
        我们可以发现通过url传入的参数首先会颠末dowith_sql()这个函数的过滤,当发现vlue中存在敏感字符时系统直接中断。此为第一个WAF,要是绕不过第一个WAF基本上实现不了注入。
        当通过第一个WAF后来到第二个WAF,在这里又会颠末dhtmlspecialchars()函数的过滤。
只有通过了这两个WAF的严格检测后才可以将i_d中的参数带入到sql语句中进行查询。
测试:
        这是一个正常的访问。

         当传入的参数i_d中存在恶意字符时将中断在第一个WAF。

 绕过第一个WAF

        我们利用第一个点和第二个点来绕过。
        在第一个WAF中没有区分i_d和i.d,相称于是两个i_d,这里接收了第二个。
        构建payload:http://daiqile:12345/index.php?submit=1&i_d=select &i.d=12
我们查看回显界面没有提示“非法字符”,阐明我们绕过了第一个waf来到了第二个waf。
        


绕过第二个WAF:

        在第二个WAF中参数的接收就会区分i_d和i.d。此时接收的就是i_d中的内容,我们在i_d中传入注入语句来进行注入即可。
        构建payload:?submit=1&i_d=-1/**/union/**/select/**/1,2,3&i.d=111
        可以看到回显在第二个字段。

        注入数据库名称:

        由于括号被过滤了,我们不能够直接使用database()来注入数据库的名称。所以我们要换一个方式来进行注入。在information_schema库的schemata表中记录了所有的数据库的名称。我们只必要一个一个进行注入即可注入出所有的数据库。
        这里代表注入出所有的数据库名称,由于这里为ctf比赛的标题,显着这里的数据库为ctf。
        我们也可以使用limit一个一个注入出来。

        注入表名:

        构建payload:如下

        注意点:
        (1):在where条件中,我们不能使用“=”,由于在如下代码中会使用“=”来进行分割,我们使用like来进行替代。
  1.   if (isset($request_uri[1])) {
  2.       $rewrite_url = explode("&", $request_uri[1]);
  3.       //print_r($rewrite_url);exit;
  4.       foreach ($rewrite_url as $key => $value) {
  5.           $_value = explode("=", $value);
  6.           if (isset($_value[1])) {
  7.               //$_REQUEST[I_d]=-1 union select flag users
  8.               $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
  9.           }
  10.       }
  11.   }
复制代码
        (2):由于过滤了单引号,我们不能直接写  table_schema like   ‘ctf’ ;我们必要将ctf转化为十六进制。
这样我们就可以查出表名:

        注入列名:

        构建payload如下:


    这样我们就可以将列名全部注入出来,注意这样注入出的列名是连在一起的。我们可以使用limit一个一个注入出来。
这里的列名为:id,username,flag。

        注入具体值:

        构建payload:这里注入出的值为flag列的值。也可以注入其他的值。

如上:我们就完成了所有的注入。以上就是所有的步骤。本次注入使用到的技巧比较多。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表