#介绍
老漏洞了,原理也很简单,随便分析一波。
漏洞编号为CVE-2013-4152,根据官方提示,xxe漏洞,漏洞的位置包括oxm,嗯,现学现卖,直接翻到文档学习一波
https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#oxm
根据官方写一个demo
````
public class Application {
private static final String FILE_NAME = "src/main/java/test/settings.xml";
private Settings settings = new Settings();
private Marshaller marshaller;
private Unmarshaller unmarshaller;
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void saveSettings() throws IOException {
FileOutputStream os = null;
try {
os = new FileOutputStream(FILE_NAME);
this.marshaller.marshal(settings, new StreamResult(os));
} finally {
if (os != null) {
os.close();
}
}
}
public void loadSettings() throws IOException {
FileInputStream is = null;
try {
is = new FileInputStream(FILE_NAME);
this.settings = (Settings) this.unmarshaller.unmarshal(new StreamSource(is));
} finally {
if (is != null) {
is.close();
}
}
}
public static void main(String[] args) throws IOException {
ApplicationContext appContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
Application application = (Application) appContext.getBean("application");
application.saveSettings();
application.loadSettings();
}
} ----------------------------------
````
public class Settings {
private boolean fooEnabled;
public boolean isFooEnabled() {
return fooEnabled;
}
public void setFooEnabled(boolean fooEnabled) {
this.fooEnabled = fooEnabled;
}
}
````
测试完xml解析之后,写了一个web项目,验证一下,核心代码如下:
````
@Controller
public class XmlController {
@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/xml")
@ResponseBody
public String login(@RequestBody User user) {
String username = user.getUserName();
String userpassword = user.getUserPassword();
String result;
if (username.equals("admin") && userpassword.equals("admin888")){
result = "{'status':'ok', 'message': 'login success', 'username': " + username+ "}";
}else {
result = "{'status':'error', 'message': 'login fail', username': " + username+ "}";
}
return result;
}
}
```` -----------------------------------
````
@XmlRootElement(name = "user") public class User {
private String userId;
private String userName;
private String userPassword;
@XmlElement
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
@XmlElement
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
@XmlElement
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
````
正常测试XML如下
curl -i -X POST -H “Content-Type:application/xml” -d “
xml:
有回显 curl -i -X POST -H “Content-Type:application/xml” -d “ <!DOCTYPE a [<!ENTITY xxe2 SYSTEM "file:///etc/passwd">]>
” http://127.0.0.1:8080/CVE-2013-4152/login
漏洞造成的原因是由于unmarshal函数中直接解析xml文件,没什么好分析的。
官方修复的补丁 https://github.com/spring-projects/spring-framework/pull/317/commits/2843b7d2ee12e3f9c458f6f816befd21b402e3b9
指的说明的是网上很多关于xxe漏洞的修复方案中只提到
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
各种类型的具体修复方案见下面 DOM
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setExpandEntityReferences(false);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(externalSource);
SAX
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
xmlReader.parse(new InputSource(externalSource));
StAX
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // disable DTDs entirely for that factory
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); // disable external entities
XMLStreamReader reader = factory.createXMLStreamReader(externalSource);
Spring OXM
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setExpandEntityReferences(false);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(externalSource);
DOMSource source = new DOMSource(document);
Jaxb2Marshaller jaxb2Marshaller = ...
Object unmarshalled = jaxb2Marshaller.unmarshal(source);
CVE-2013-4152补丁设置xmlReader.setFeature(“http://xml.org/sax/features/external-general-entities”,false);可以防止外部实体被解析
###参考文档
http://blog.csdn.net/scmrpu/article/details/50423701
https://security.tencent.com/index.php/blog/msg/69