HacKerQWQ的博客空间

javaweb代码审计(XXE漏洞)

Word count: 811Reading time: 4 min
2021/12/05 Share

XXE漏洞

XXE(XML External Entity Injection),中文称作XML外部实体注入。和SQL注入、XSS、XPath注入等类似,都是违反了“数据与代码分离原则”的产物。

XXE危害:配合各种协议和老哥们的骚思路,可以读取任意文件、执行系统命令、探测内网端口、攻击内网网站等。

XML常见接口

XMLReader

SAX2(Simple API for XML 2)

XMLReader接口是XML解析器实现SAX2驱动程序所必需的接口,当XMLReader使用默认的解析方法并且没有对XML进行过滤时,会造成XXE漏洞。

1
2
3
4
5
6
try{
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.parse(new InputSource(request.getInputStream()));
}catch (Exception e){
e.printStackTrace();
}

SAXBuilder

SAXBuilder是JDOM解析器,使用第三方SAX解析器来处理解析任务,当使用默认解析方法时,会造成XXE。

1
2
3
4
5
6
7
8
9
10
11
try{
String body = WebUtils.getRequestBody(request);
logger.info(body);

SAXBuilder builder = new SAXBuilder();
// org.jdom2.Document document
builder.build(new InputSource(new StringReader(body)));
return "SAXBuilder xxe vuln code";
}catch(Exception e){
e.printStackTrace();
}

SAXReader

DOM4J是dom4j.org出品的一个开源XML解析包,有DOMReaderSAXReader两种方式,使用的是同一个接口

1
2
3
4
5
6
7
8
9
10
try{
String body = WebUtils.getRequestBody(request);
logger.info(body);

SAXReader builder = new SAXReader();
// org.dom4j.Document document
reader.read(new InputSource(new StringReader(body)));//cause xxe
}catch(Exception e){
e.printStackTrace();
}

SAXParseFactory

1
2
3
4
5
6
7
8
9
10
11
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());
return "SAXParser xxe vuln code"
}catch(Exception e){
e.printStackTrace();
}

Digester

它是Apache Commons库中的一个jar包:common-digester

1
2
3
4
5
6
7
8
9
try{
String body = WebUtils.getRequestBody(request);
logger.info(body);

Digester digester = new Digester();
digester.parse(new StringReader(body));
}catch(Exception e){
e.printStackTrace();
}

DocumentBuilderFactory

DocumentBuilderFactory是一个抽象工厂类,不能直接实例化,但是提供了newInstance()方法,会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
try{
String body = WebUtils.getRequestBody(request);
logger.info(body);

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
String Reader sr = new StringReader(body);
InputSource is = new InputSoure(sr);
Document document = db.parse(is);//parse xml
// 遍历xml节点name和value
StringBuffer buf = new StringBuffer();
NodeList rootNodeList = document.getChildNodes();
for(int i=0;i<rootNodeList.getLength();i++){
Node rootNode = rootNodeList.item(i);
NodeList child = rootNode.getChildNodes();
for(int j=0;j<child.getLength();j++){
Node node = child.item(i);
buf.append(node.getNodeName()+":"+node.getTextContent()+"\n");
}
}
sr.close();
return buf.toString();
}catch(Exception e){
e.printStackTrace();
}

XXE的payload

https://hackerqwq.github.io/2020/08/05/XXE%E6%B3%A8%E5%85%A5payload/

XXE漏洞修复

可以通过设置XML解析器的属性,禁用DTD或者禁用外部实体来达到防御XXE攻击的效果

1
2
3
4
//实例化解析类之后通常会支持三个配置
obj.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
obj.setFeature("http://xml.org/sax/features/external-general-entities",false);
obj.setFeature("http://xml.org/sax/features/external-parameter-entities",false);

需要注意的是当使用DocumentBuilder进行解析时,需要先设置属性再获取解析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
String result = "";
try{
String FEATURE = null;
FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing";
dbf.setFeature(FEATURE,true);
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(false);
db = dbf.newDocumentBuilder();
Document doc = db.parse(request.getInputStream());
...
}catch(Exception e){
e.printStackTrace();
}

XXE漏洞代码审计关键字

1
2
3
4
5
6
XMLReader
SAXBuilder
SAXReader
SAXParserFactory
Digester
DocumentBuilderFactory
CATALOG
  1. 1. XXE漏洞
  2. 2. XML常见接口
    1. 2.1. XMLReader
    2. 2.2. SAXBuilder
    3. 2.3. SAXReader
    4. 2.4. SAXParseFactory
    5. 2.5. Digester
    6. 2.6. DocumentBuilderFactory
    7. 2.7. XXE的payload
  3. 3. XXE漏洞修复
  4. 4. XXE漏洞代码审计关键字