XXE代码审计以及XXE漏洞修复

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值