文章目录
- XMLReader
- SAXReader
- SAXBuilder
- DocumentBuilder
- Unmarshaller
- **SAXParserFactory**
- XMLReaderFactory
- Digester
- 总结
XMLReader
public String XMLReader(@RequestBody String content) {
try {
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
// 修复:禁用外部实体
// xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
xmlReader.parse(new InputSource(new StringReader(content)));
return "XMLReader XXE";
} catch (Exception e) {
return e.toString();
}
}
抓包然后 xml 外部实体应用
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE test [<!ENTITY xxe SYSTEM "http://u0ea91.dnslog.cn">]><root>&xxe;</root>
修复
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 修复: 禁用外部实体
// factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder builder = factory.newDocumentBuilder();
SAXReader
SAXReader是第三方的库,该类是无回显的
public String SAXReaderVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXReader reader = new SAXReader();
// org.dom4j.Document document
reader.read(new InputSource(new StringReader(body))); // cause xxe
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
SAXBuilder
AXBuilder是一个JDOM解析器,能将路径中的XML文件解析为Document对象
public String SAXBuilder(@RequestBody String content, String entity) {
try {
if (entity !=null && entity.equals("true") && Security.checkXXE(content)) {
return "检测到XXE攻击";
}
SAXBuilder saxbuilder = new SAXBuilder();
// saxbuilder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxbuilder.build(new InputSource(new StringReader(content)));
return "SAXBuilder 解析成功";
} catch (Exception e) {
return e.toString();
}
}
DocumentBuilder
这是JDK自带的类,以此产生的XXE是存在回显的
public String DocumentBuilder(@RequestBody String content, String entity) {
try {
if (entity !=null && entity.equals("true") && Security.checkXXE(content)) {
return "检测到XXE攻击";
}
// DocumentBuilderFactory是用于创建DOM模式的解析器对象,newInstance方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader sr = new StringReader(content);
InputSource is = new InputSource(sr);
Document document = builder.parse(is);
// 获取<person>标签名
NodeList nodeList = document.getElementsByTagName("person");
Element element = (Element) nodeList.item(0);
return String.format("姓名: %s", element.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
} catch (Exception e) {
return e.toString();
}
}
Unmarshaller
public String Unmarshaller(@RequestBody String content, String entity) {
try {
if (entity !=null && entity.equals("true") && Security.checkXXE(content)) {
return "检测到XXE攻击";
}
JAXBContext context = JAXBContext.newInstance(Student.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
XMLInputFactory xif = XMLInputFactory.newFactory();
// fixed: 禁用外部实体
// xif.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
// xif.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
// 默认情况下在1.8版本上不能加载外部dtd文件,需要更改设置。
// xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true);
// xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(content));
Object o = unmarshaller.unmarshal(xsr);
return o.toString();
} catch (Exception e) {
// e.printStackTrace();
return e.toString();
}
}
SAXParserFactory
该类也是JDK内置的类,但他不可回显内容,可借助dnslog平台
public String SAXParserVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.parse(new InputSource(new StringReader(body)), new DefaultHandler()); // parse xml
return "SAXParser xxe vuln code";
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}
XMLReaderFactory
public String xmlReaderVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.parse(new InputSource(new StringReader(body))); // parse xml
return "xmlReader xxe vuln code";
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
Digester
public String DigesterVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
Digester digester = new Digester();
digester.parse(new StringReader(body)); // parse xml
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "Digester xxe vuln code";
总结
白盒测试就看关键类 XMLReader,SAXBuilder,SAXReader 。。。
黑盒测试就抓包看看有没有传 xml 数据的,有传的直接改了外部实体引用试试。其实 php和 java 的 xxe 没什么区别