java XXE代码审计
java 解析xml的方法越来越多,常见的是使用DOM,JDOM,DOM4J,SAX等四种方式
使用DOM解析XML
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result="";
try {
//DOM Read XML
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(request.getInputStream());
String username = getValueByTagName(doc,"username");
String password = getValueByTagName(doc,"password");
if(username.equals(USERNAME) && password.equals(PASSWORD)){
result = String.format("<result><code>%d</code><msg>%s</msg></result>",1,username);
}else{
result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,username);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());
} catch (SAXException e) {
e.printStackTrace();
result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());
}
response.setContentType("text/xml;charset=UTF-8");
response.getWriter().append(result);
}
使用DOM读取xml时候正确的设置,重点在于
DocumentBuilder builder = dbf.newDocumentBuilder();这句话应当防止在设置语句之后才能够生效
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
FEATURE = "http://javax..XMLConstants/feature/secure-processing";
dbf.setFeature(FEATURE, true);
FEATURE = "http://apache.org//features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
FEATURE = "http://.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://apache.org//features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder builder = dbf.newDocumentBuilder();
// 读取文件内容
FileInputStream fis = new FileInputStream("path/to/xxe");
InputSource is = new InputSource(fis);
Document doc = builder.parse(is);
使用DOM4J解析xml
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result="";
try {
//DOM4J Read XML
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(request.getInputStream());
String username = getValueByTagName2(document,"username");
String password = getValueByTagName2(document,"password");
if(username.equals(USERNAME) && password.equals(PASSWORD)){
result = String.format("<result><code>%d</code><msg>%s</msg></result>",1,username);
}else{
result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,username);
}
} catch (DocumentException e) {
System.out.println(e.getMessage());
}
response.setContentType("text/xml;charset=UTF-8");
response.getWriter().append(result);
}
正确设置应当是
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org//features/disallow-doctype-decl", true);
reader.setFeature("http://apache.org//features/nonvalidating/load-external-dtd", false);
reader.setFeature("http://.org/sax/features/external-general-entities", false);
reader.setFeature("http://.org/sax/features/external-parameter-entities", false);
reader.parse(new InputSource(InputSource));
使用JDOM解析xml
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String result="";
try {
//JDOM2 Read XML
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(request.getInputStream());
String username = getValueByTagName3(document,"username");
String password = getValueByTagName3(document,"password");
if(username.equals(USERNAME) && password.equals(PASSWORD)){
result = String.format("<result><code>%d</code><msg>%s</msg></result>",1,username);
}else{
result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,username);
}
} catch (JDOMException e) {
System.out.println(e.getMessage());
}
response.setContentType("text/xml;charset=UTF-8");
response.getWriter().append(result);
}
使用JDOM解析时的正确设置应当是
第一种
SAXBuilder builder = new SAXBuilder(true);
Document doc = builder.build(InputSource);
第二种
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org//features/disallow-doctype-decl", true);
builder.setFeature("http://.org/sax/features/external-general-entities", false);
builder.setFeature("http://.org/sax/features/external-parameter-entities", false);
builder.setFeature("http://apache.org//features/nonvalidating/load-external-dtd", false);
Document doc = builder.build(InputSource)
使用SAX 解析xml
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//https://blog.csdn.net/u011024652/article/details/51516220
String result="";
try {
//SAX Read XML
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxparser = factory.newSAXParser();
SAXHandler handler = new SAXHandler();
saxparser.parse(request.getInputStream(), handler);
//为简单,没有提取子元素中的数据,只要调用parse()解析xml就已经触发xxe漏洞了
//没有回显 blind xxe
result = String.format("<result><code>%d</code><msg>%s</msg></result>",0,1);
} catch (ParserConfigurationException e) {
e.printStackTrace();
result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());
} catch (SAXException e) {
e.printStackTrace();
result = String.format("<result><code>%d</code><msg>%s</msg></result>",3,e.getMessage());
}
response.setContentType("text/xml;charset=UTF-8");
response.getWriter().append(result);
}
正确设置应当是
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org//features/disallow-doctype-decl", true);
spf.setFeature("http://.org/sax/features/external-general-entities", false);
spf.setFeature("http://.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org//features/nonvalidating/load-external-dtd", false);
SAXParser parser = spf.newSAXParser();
parser.parse(InputSource, (HandlerBase) null);
参考
更多xml解析类正确设置修复可以参考:https://www.redhatzone.com/ask/article/1535.html;
更多xml解析具体操作可参考:http://www.51gjie.com/java/738.html;
https://xz.aliyun.com/t/2761
php 代码审计
XXE漏洞于php版本无关,主要是libxml的拓展。2.9以后默认不使用外部实体,导致php的xxe几乎消亡。
SimpleXMLElement
<?php
$data = file_get_contents('php://input');
$xml = new SimpleXMLElement($data);
echo $xml->name;
?>
DOMDocument
<?php
$data = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($data);
print_r($dom);
?>
simplexml_load_string
<?php
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);
echo $xml->name;
?>
修复方法
libxml_disable_entity_loader(ture)设置为ture时则禁止加载外部实体,设置为flase时允许加载外部实体;
参考
http://www.codesec.top/archives/PHPXXEAudit
https://www.cnblogs.com/Rightsec/p/10263454.html