Deutsh
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

引言
XPath报错学过的人都很熟悉,用哪些函数、如何构造等。
但我有这样一个疑问:为什么数据库(无论是MySQL还是Oracle等)可以执行对XML文档进行操作的函数,这应该不属于数据库的范畴吧?
经查询还是自己肤浅了,原来数据库为了保存XML类型的数据,并不能直接保存,而是要对这些数据进行处理,以MySQL为例,他组织XML文档的内容有以下几种方式:
使用DBMS将文档存储为文本
使用DBMS将文档存储为数据元素
设计一个用于存储本机XML文档的专用系统
从现有的关系数据库创建或发布自定义XML文档
所以为了将XML数据转换为上述数据类型,则需要在数据库中对XML文档进行操作,所以数据库中自然就包含了这些函数
原理
主要依托于两个函数extractvalue()
和updatexml()
⚠️ mysql要求其版本 > 5.1.5
extractvalue(XML_document, XPath_string)
: 对XML文档进行查询的函数updatexml(XML_document, XPath_string, new_value)
: 更新XML文档的函数XML_document
: string格式,为xml文档对象的名称XPath_string
: xpath格式的字符串(XML路径)
问题主要出现在XPath_string
参数
XML文档中查找字符位置是用 /xxx/xxx/xxx/…格式,如果写入其他格式(并不是所有除了/xxx/xxx/xxx的格式都会报错,有些字符会报错),会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容
若我们构造一个特殊的错误
select extractvalue('anything',concat('~',(select database())));
这时就返回了我们要查询数据库的名字
若此处格式正确,即使查询不到也不会报错
具体构造
id=-1" and(select extractvalue(anything,concat('~',(select database()))))
anything
可替换为任意值'~'
可以换成’#’
、’$'
等不满足xpath格式的字符- 有一个特殊的select:
select version() = select @@version
extractvalue()
能查询字符串的最大长度为32,如果结果超过32,就要用substring()函数截取或limit分页,一次查看最多32位
id=-1" and(select updatexml("anything",concat('~',(select database())),"anything"))
updatexml与extractvalue用法类似
具体案例见SQLi-LABS-Basic Challenges文章
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)