Spring MVC xml绑定pojo造成的XXE

0x00 背景


什么是XXE ? 就是我们所说的所谓xml实体注入.这里不去讲所有xml语法规范了,稍微就说一下XML entity:

[cce]entity翻译为”实体”。它的作用类似word中的”宏”,也可以理解为DW中的模板,你可以预先定义一个entity,然后在一个文档中多次调用,或者在多个文档中调用同一个entity(XML定义了两种类型的entity。一种是我们这里说的普通entity,在XML文档中使用;另一种是参数entity,在DTD文件中使用。)。
[/cce]

entity的定义语法为:

[cce]#!xml

[/cce]

如果要引用一个外部资源:

[cce]#!xml
 
]>
[/cce]

ENTITY可以使用SYSTEM关键字,调用外部资源,而这里是支持很多的协议,如:http;file等

然后,在其他DoM结点中可以使用如:&test;引用该实体内容.

那么,如果在产品功能设计当中,解析的xml是由外部可控制的,那将可能形成,如:文件读取,DoS,CSRF等漏洞.

这里只介绍文件读取漏洞,其他可以自己google了解.

0x01 原理


规范没有问题,xml解析器有些也没有问题,有问题的是使用他的人.

java SAX解析器 demo:

Test.java

[cce]#!java
public static void main(String[] args) throws  Exception {
SAXReader reader = new SAXReader();
//禁止
//reader.setFeature(“http://xml.org/sax/features/external-general-entities”, true);
Document dom = reader.read(“E:/1.xml”);
Element root = dom.getRootElement();
Iterator it = root.elementIterator();
while (it.hasNext()) {
Element elements = it.next();
System.out.println(elements.getText());

}
}
[/cce]

解析的xml,1.xml:

[cce]#!xml

]>

&xxe;

[/cce]

实体调用的资源,1.log:

[cce]XXE test!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
[/cce]

先说一点,解析器一般会支持所有xml规范的.使用file协议,理论上,我们至少可以读取到当前系统的任意文件内容.如:读取E盘符下的1.log文件内容.

然后被root的子节点,name内容域引用.解析结果,如图:

2014050722403743880.png

接下来讲,spring MVC在xml格式到java对象反序列化中,可能存在的XXE 形成的文件读取:

spring 是提供xml请求内容绑定到pojo的功能(也可以理解成javabean什么的(有区别,可以自己去看看),spring  在这里规范化了,所以就跟着叫),用得比较多的还有表单绑定,json绑定。

spring mvc JAXB xml to pojo unMarshaller  demo:

spring-servlet.xml:

[cce]#!xml


  
  
 
 
   
                                   
               
               
           
       
   

 


       
       


                                    net.spring.controller.User
           
       


[/cce]

HelloWorldController.java:

[cce]#!java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloWorldController { 
@RequestMapping(“/hello”)
public  ModelAndView helloWorld(@RequestBody User user) {

System.out.println(“xxxxxxxxxx”+user.getName());
return new ModelAndView(“hello”, “user”, user); 

}
[/cce]

User.java(xml绑定的pojo):

[cce]#!java
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name=”user”)  
public class User {
private String name;

public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
}
[/cce]

发包,xml绑定pojo,如图:

2014050723155955348.png

pojo User对象的name属性被污染,如图:

2014050723180180429.png

如果,攻击者最终能看到这个name值(直接显示到页面或存储到数据库再现实到页面什么的),就是文件读取漏洞了!

不管是其他语言或场景,原理就这么回事。

spring 早已经修补,这里主要给个漏洞场景,现在基本没什么危害吧?因为这个功能使用不常见,但走在前面的框架使用者肯定会使用这个功能,可能需要等个十年左右:

https://jira.spring.io/browse/SPR-10806

当然,还存在一个小而很有意思的问题,过一段时间的文章中可能会讲到。

Comment

评论:虽不懂java,不过漏洞不错,看了下StAX的修补方案,明显有问题,不过在3.2.6好像还是修复了。

评论:Good job 你是一个安全研究的程序猿

评论:昨天发的某站提供的xml格式化存在实体注入漏洞。在群里面发的测试:http://p2j.cn/?p=1269

评论:赞!

评论:为什么在 http 头 能拿到 xml ? 这里不懂, 你直接访问到了他的 配置文件吗?

评论:大概懂了一点点- –

发表评论

电子邮件地址不会被公开。 必填项已用*标注