Skip to content

Commit

Permalink
Merge pull request #3062 from returntocorp/merge-develop-to-release
Browse files Browse the repository at this point in the history
Merge Develop into Release
  • Loading branch information
colleend authored Aug 23, 2023
2 parents 67723f5 + cccf417 commit a796615
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 371 deletions.
367 changes: 2 additions & 365 deletions contrib/owasp/java/xxe/xmlreader.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,10 @@ public String xmlReaderSec(HttpServletRequest request) {
String body = WebUtils.getRequestBody(request);
logger.info(body);

// ok:owasp.java.xxe.org.xml.sax.XMLReader
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.parse(new InputSource(new StringReader(body))); // parse xml

// fix code start
xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
//fix code end
xmlReader.parse(new InputSource(new StringReader(body))); // parse xml

} catch (Exception e) {
logger.error(e.toString());
Expand All @@ -81,365 +77,6 @@ public String xmlReaderSec(HttpServletRequest request) {
}


@RequestMapping(value = "/SAXBuilder/vuln", method = RequestMethod.POST)
public String SAXBuilderVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXBuilder builder = new SAXBuilder();
// org.jdom2.Document document
builder.build(new InputSource(new StringReader(body))); // cause xxe
return "SAXBuilder xxe vuln code";
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}


@RequestMapping(value = "/SAXBuilder/sec", method = RequestMethod.POST)
public String SAXBuilderSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);

SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// org.jdom2.Document document
builder.build(new InputSource(new StringReader(body)));

} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}

return "SAXBuilder xxe security code";
}

@RequestMapping(value = "/SAXReader/vuln", method = RequestMethod.POST)
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;
}

return "SAXReader xxe vuln code";
}

@RequestMapping(value = "/SAXReader/sec", method = RequestMethod.POST)
public String SAXReaderSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);

SAXReader reader = new SAXReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// org.dom4j.Document document
reader.read(new InputSource(new StringReader(body)));
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "SAXReader xxe security code";
}

@RequestMapping(value = "/SAXParser/vuln", method = RequestMethod.POST)
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;
}
}


@RequestMapping(value = "/SAXParser/sec", method = RequestMethod.POST)
public String SAXParserSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
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);
SAXParser parser = spf.newSAXParser();
parser.parse(new InputSource(new StringReader(body)), new DefaultHandler()); // parse xml
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "SAXParser xxe security code";
}


@RequestMapping(value = "/Digester/vuln", method = RequestMethod.POST)
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";
}

@RequestMapping(value = "/Digester/sec", method = RequestMethod.POST)
public String DigesterSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);

Digester digester = new Digester();
digester.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
digester.setFeature("http://xml.org/sax/features/external-general-entities", false);
digester.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
digester.parse(new StringReader(body)); // parse xml

return "Digester xxe security code";
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}


// 有回显
@RequestMapping(value = "/DocumentBuilder/vuln01", method = RequestMethod.POST)
public String DocumentBuilderVuln01(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(body);
InputSource is = new InputSource(sr);
Document document = db.parse(is); // parse xml

// 遍历xml节点name和value
StringBuilder buf = new StringBuilder();
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(j);
buf.append(String.format("%s: %s\n", node.getNodeName(), node.getTextContent()));
}
}
sr.close();
return buf.toString();
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}


// 有回显
@RequestMapping(value = "/DocumentBuilder/vuln02", method = RequestMethod.POST)
public String DocumentBuilderVuln02(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(body);
InputSource is = new InputSource(sr);
Document document = db.parse(is); // parse xml

// 遍历xml节点name和value
StringBuilder result = new StringBuilder();
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(j);
// 正常解析XML,需要判断是否是ELEMENT_NODE类型。否则会出现多余的的节点。
if (child.item(j).getNodeType() == Node.ELEMENT_NODE) {
result.append(String.format("%s: %s\n", node.getNodeName(), node.getFirstChild()));
}
}
}
sr.close();
return result.toString();
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}


@RequestMapping(value = "/DocumentBuilder/Sec", method = RequestMethod.POST)
public String DocumentBuilderSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(body);
InputSource is = new InputSource(sr);
db.parse(is); // parse xml
sr.close();
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "DocumentBuilder xxe security code";
}


@RequestMapping(value = "/DocumentBuilder/xinclude/vuln", method = RequestMethod.POST)
public String DocumentBuilderXincludeVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setXIncludeAware(true); // 支持XInclude
dbf.setNamespaceAware(true); // 支持XInclude
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(body);
InputSource is = new InputSource(sr);
Document document = db.parse(is); // parse xml

NodeList rootNodeList = document.getChildNodes();
response(rootNodeList);

sr.close();
return "DocumentBuilder xinclude xxe vuln code";
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
}


@RequestMapping(value = "/DocumentBuilder/xinclude/sec", method = RequestMethod.POST)
public String DocumentBuilderXincludeSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setXIncludeAware(true); // 支持XInclude
dbf.setNamespaceAware(true); // 支持XInclude
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(body);
InputSource is = new InputSource(sr);
Document document = db.parse(is); // parse xml

NodeList rootNodeList = document.getChildNodes();
response(rootNodeList);

sr.close();
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "DocumentBuilder xinclude xxe vuln code";
}


@PostMapping("/XMLReader/vuln")
public String XMLReaderVuln(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
// ruleid:owasp.java.xxe.org.xml.sax.XMLReader
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.parse(new InputSource(new StringReader(body)));

} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}

return "XMLReader xxe vuln code";
}


@PostMapping("/XMLReader/sec")
public String XMLReaderSec(HttpServletRequest request) {
try {
String body = WebUtils.getRequestBody(request);
logger.info(body);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
xmlReader.parse(new InputSource(new StringReader(body)));

} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}
return "XMLReader xxe security code";
}


/**
* 修复该漏洞只需升级dom4j到2.1.1及以上,该版本及以上禁用了ENTITY;
* 不带ENTITY的PoC不能利用,所以禁用ENTITY即可完成修复。
*/
@PostMapping("/DocumentHelper/vuln")
public String DocumentHelper(HttpServletRequest req) {
try {
String body = WebUtils.getRequestBody(req);
DocumentHelper.parseText(body); // parse xml
} catch (Exception e) {
logger.error(e.toString());
return EXCEPT;
}

return "DocumentHelper xxe vuln code";
}


private static void response(NodeList rootNodeList){
for (int i = 0; i < rootNodeList.getLength(); i++) {
Node rootNode = rootNodeList.item(i);
NodeList xxe = rootNode.getChildNodes();
for (int j = 0; j < xxe.getLength(); j++) {
Node xxeNode = xxe.item(j);
// 测试不能blind xxe,所以强行加了一个回显
logger.info("xxeNode: " + xxeNode.getNodeValue());
}

}
}

public static void main(String[] args) {
}
Expand Down
4 changes: 0 additions & 4 deletions contrib/owasp/java/xxe/xmlreader.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,11 @@ rules:
$RETURNTYPE $METHOD(...) {
...
$XMLREADER.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
$XMLREADER.setFeature("http://xml.org/sax/features/external-general-entities", false);
$XMLREADER.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
...
}
- pattern-not-inside: |
XMLReader $XMLREADER = ... ;
...
$XMLREADER.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
$XMLREADER.setFeature("http://xml.org/sax/features/external-general-entities", false);
$XMLREADER.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
languages:
- java
Loading

0 comments on commit a796615

Please sign in to comment.