XML原理
XXE:XML External Entity 即XML外部实体注入攻击。是由于程序在解析输入的XML数据时,解析了攻击者伪造的外部实体,通过外部实体SYSTEM请求本地文件uri,通过某种方式返回本地的文件内容,导致了XXE漏洞。
java中出现的场景
poc.xml
<!ELEMENT example ANY >
<!ENTITY file SYSTEM "http://localhost:10000" >
]>
<example>&file;</example>
DocumentBuilderFactory
漏洞代码
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
// dbf.setExpandEntityReferences无法防止xxe
dbf.setExpandEntityReferences(false);
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
Document document = documentBuilder.parse(new File("poc.xml"));
修复代码
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);
dbf.setXIncludeAware(false);
// dbf.setExpandEntityReferences无法防止xxe
dbf.setExpandEntityReferences(false);
DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
DOMParser
漏洞代码
DOMParser domParser = new DOMParser();
domParser.parse(new FileInputStream(new File("src/main/java/xxe/poc.xml")));
修复代码
DOMParser domParser = new DOMParser();
// Do not expand entity references domParser.setAttribute(DOMParser.EXPAND_ENTITYREF, false);
domParser.parse(new FileInputStream(new File("poc.xml")));
SaxBuilder
漏洞代码
File file = new File("poc.xml");
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build(file);
修复代码
File file = new File("src/main/java/xxe/poc_bind.xml");
SAXBuilder sb = new SAXBuilder();
sb.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
sb.setFeature("http://xml.org/sax/features/external-general-entities", false);
sb.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
sb.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
SAXParserFactory
漏洞代码
SAXParserFactory spf = SAXParserFactory.newInstance();
File file = new File("poc.xml");
SAXParser parser = spf.newSAXParser();
parser.parse(file, (HandlerBase) null);
修复代码
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
File file = new File("poc.xml");
SAXParser parser = spf.newSAXParser();
parser.parse(file, (HandlerBase) null);
SAXReader
漏洞代码
File file = new File("poc.xml");
SAXReader saxReader = new SAXReader();
saxReader.read(file);
修复代码
File file = new File("poc.xml");
SAXReader saxReader = new SAXReader();
saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
saxReader.read(file);
SAXTransformerFactory
漏洞代码
File file = new File("poc.xml");
StreamSource source = new StreamSource(file);
SAXTransformerFactory sf = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); sf.newTransformerHandler(source);
修复代码
File file = new File("poc.xml");
StreamSource source = new StreamSource(file);
SAXTransformerFactory sf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
sf.newTransformerHandler(source);
SchemaFactory
漏洞代码
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
File file = new File("poc.xml");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
StreamSource source = new StreamSource(file);
Schema schema = factory.newSchema(source);
修复代码
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
File file = new File("src/main/java/xxe/poc.xml");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
StreamSource source = new StreamSource(file);
Schema schema = factory.newSchema(source);
TransformerFactory
漏洞代码
TransformerFactory tf = TransformerFactory.newInstance();
File file = new File("poc.xml");
StreamSource source = new StreamSource(file);
tf.newTransformer().transform(source, new DOMResult());
修复代码
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
File file = new File("poc.xml");
StreamSource source = new StreamSource(file);
tf.newTransformer().transform(source, new DOMResult());
Validator
漏洞代码
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
Validator validator = schema.newValidator();
File file = new File("poc.xml");
StreamSource source = new StreamSource(file);
validator.validate(source);
修复代码
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
Validator validator = schema.newValidator(); validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
File file = new File("poc.xml");
StreamSource source = new StreamSource(file);
validator.validate(source);
XMLInputFactory
漏洞代码
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
File file = new File("poc.xml");
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(new FileInputStream(file));
try {
while (reader.hasNext()) {
int type = reader.next();
if (type == XMLStreamConstants.START_ELEMENT) {//开始节点
System.out.print(reader.getName());
} else if (type == XMLStreamConstants.CHARACTERS) {//表示事件字符
System.out.println("type" + type);
} else if (type == XMLStreamConstants.END_ELEMENT) {//结束节点
System.out.println(reader.getName());
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
修复代码
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
File file = new File("poc.xml");
...
XMLReaderFactory
漏洞代码
XMLReader reader = XMLReaderFactory.createXMLReader();
File file = new File("poc.xml");
reader.parse(new InputSource(new FileInputStream(file)));
修复代码
XMLReader reader = XMLReaderFactory.createXMLReader();
File file = new File("poc.xml");
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
reader.parse(new InputSource(new FileInputStream(file)));
XLSX中xxe漏洞(CVE-2014-3529)
漏洞触发条件
-
poi-ooxml-3.10-FINAL.jar及以下版本
漏洞代码
File file = new File("test.xlsx");
XSSFWorkbook xssfSheets = new XSSFWorkbook(new FileInputStream(file));
XSSFSheet sheet = xssfSheets.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
for (Row row:sheet){
for(Cell cell:row){
System.out.println(cell.getStringCellValue()+" ");
}
}
poc构造
1. 使用Excel新建一个xlsx文件
2. 修改后缀名为zip,并使用zip解压缩
3. 在[Content_Types].xml文件上增加恶意数据
漏洞修复
-
poi升级到3.10以上
从代码层讲解漏洞原理,学习更多技术,关注我:
原文始发于微信公众号(编码安全研究):XXE 漏洞代码及修复代码整理
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论