代码编织梦想

目录

前言:

(一)XML 的常见接口

1.XMLReader

2.SAXBuilder

3.SAXReader

4.SAXParserFactory

5.Digester

6.DocumentBuilderFactory

(二)XXE 漏洞审计

(三)XXE 漏洞修复

(四)小结


前言:

XXE XML 外部实体注入。当应用程序在解析 XML 输入时,在没有禁止外部实体的加载而导致加载了外部文件及代码时,就会造成 XXE 漏洞。 XXE 漏洞可以通过 file 协议或是 FTP 协议来读取文件源码,当然也可以通过 XXE 漏洞来对内网进行探测或者功击,如图 2-96 所示。漏洞危害有:任意文件读取、内网探测、攻击内网站点、命令执行、DOS 攻击等。
图 1-0 XXE 漏洞执行流程

 

(一)XML 的常见接口


想要了解 XXE 漏洞,我们首先需要知道常见的能够解析 XML 的方法,在 Java 中我
们一般用以下几种常见的接口来解析 XML 语言。

1XMLReader


        XMLReader 接口是一种通过回调读取 XML 文档的接口,其存在于公共区域中。XMLReader 接口是 XML 解析器实现 SAX2 驱动程序所必需的接口,其允许应用程序设置和查询解析器中的功能和属性、注册文档处理的事件处理程序,以及开始文档解析。当XMLReader 使用默认的解析方法并且未对 XML 进行过滤时,会出现 XXE 漏洞。
try { 
     XMLReader xmlReader = XMLReaderFactory.createXMLReader();
     xmlReader.parse(new InputSource(new StringReader(body))); 
        } catch (Exception e) { 
             return EXCEPT; 
    }

2SAXBuilder


        SAXBuilder 是一个 JDOM 解析器,其能够将路径中的 XML 文件解析为 Document 对 象。SAXBuilder 使用第三方 SAX 解析器来处理解析任务,并使用 SAXHandler 的实例侦听 SAX 事件。当 SAXBuilder 使用默认的解析方法并且未对 XML 进行过滤时,会出现XXE 漏洞
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; 
 }

3SAXReader


DOM4J dom4j.org 出品的一个开源 XML 解析包,使用起来非常简单,只要了解基本的 XML-DOM 模型,就能使用。 DOM4J / XML 文档主要依赖于 org.dom4j.io包,它有 DOMReader SAXReader 两种方式。因为使用了同一个接口,所以这两种方式的调用方法是完全一致的。同样的,在使用默认解析方法并且未对 XML 进行过滤时,其也会出现 XXE 漏洞。
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; 
 }

4SAXParserFactory


SAXParserFactory 使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档。其受保护的构造方法,可以强制使用 newInstance() 。跟上面介绍的一样,在使用默认解析方法且未对 XML 进行过滤时,其也会出现 XXE 漏洞。
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; 
 }

5Digester


Digester 类用来将 XML 映射成 Java 类,以简化 XML 的处理。它是 Apache Commons库中的一个 jar 包: common-digester 包。一样的在默认配置下会出现 XXE 漏洞。其触发的 XXE 漏洞是没有回显的,我们一般需通过 Blind XXE 的方法来利用:
 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; 
 }

6DocumentBuilderFactory


       javax.xml.parsers 包中的 DocumentBuilderFactory 用于创建 DOM 模式的解析器对象,
DocumentBuilderFactory 是一个抽象工厂类,它不能直接实例化,但该类提供了一个
newInstance() 方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对
象并返回。
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 
     StringBuffer buf = new StringBuffer(); 
         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(node.getNodeName() + ":" + node.getTextContent() + "\n");
         } 
     } 
     sr.close(); 
         return buf.toString(); 
     }catch (Exception e) { 
         logger.error(e.toString()); 
         return EXCEPT; 
 }

(二)XXE 漏洞审计


        XXE 漏洞的审计方法和其他漏洞类似,只是搜索的关键字有所不同。这次我们采用了 GitHub 开源的 XXE 靶场: XXE-Lab 来进行审计。通过搜索 XML 的常见关键字,可以快速地对关键代码进行定位,如图 2-1  所示。
图 2-1 搜索关键代码

 

        根据搜索结果可知,使用了“DocumentBuilderFactory.newInstance() ”,因此可通过双击跟进对应代码段查看 XML 是否可控。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 
IOException { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db; 
     String result=""; 
     try { 
             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); 
}
通过通读源码可以发现:程序首先通过“ DocumentBuilderFactory.newInstance() ”获
取一个“ DocumentBuilderFactory ”的实例,随后通过“ DocumentBuilder::parse ”来解析
通过“ request.getInputStream() ”传入的 body 内容,并返回一个 Document 实例,漏洞关
键代码如图 2-2  所示。
图 2-2 漏洞关键代码
继续跟进程序可以发现,其通过 getValueByTagName 函数获取了 username 节点的内容,并在对比数据后将其输出到页面中。也就是说,这里可以通过控制 username 的值来达到回显 XXE 的目的,如图 2-3  所示。
图 2-3 username 值可控

 

        审计到这里,我们已经清楚了漏洞的整个触发流程及原理。接下来,可以构造一个用于 XXE 漏洞审计的常见的 Payload 。常见的 XXE Payload 如下所示:
<!--?xml version="1.0" ?--> 
<!DOCTYPE replace [<!ENTITY file SYSTEM "file:///etc/passwd"> ]> 
<xxe>&file;</xxe>
        该源码中会将 username 节点的内容进行打印,因此我们只需将上面的 XXE 节点换为
username 即可被成功解析并输出, XXE 执行效果如图 2-4  所示。最终的 Payload 如下
<!--?xml version="1.0" ?--> 
<!DOCTYPE replace [<!ENTITY file SYSTEM "file:///etc/passwd"> ]> 
<user>
    <username>&file;</username>
    <password>admin</password>
</user>
图 2-4 XXE 执行效果

(三)XXE 漏洞修复


        对于 XXE 漏洞的防御比较简单,只需在使用 XML 解析器时设置其属性,禁用 DTD或者禁止使用外部实体,一般常见的修复方案如下所示:
//实例化解析类之后通常会支持三个配置
obj.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 
obj.setFeature("http://xml.org/sax/features/external-general-entities", false); 
obj.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        当然,在使用不同的解析库时修复方案也会略有不同。值得注意的是,
DocumentBuilder builder = dbf.newDocumentBuilder(); ”这行代码需要写在 dbf.setFeature()  之后安全措施才能够生效,否则将无法防范 XXE 漏洞。以前面的实例代码为例,我们可以通过如下方法进行修复:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 
IOException { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db; 
     String result=""; 
     try { 
         String FEATURE = null; 
         FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing"; 
         dbf.setFeature(FEATURE, true); 
         FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; 
             dbf.setFeature(FEATURE, true); 
         FEATURE = "http://xml.org/sax/features/external-parameter-entities"; 
         dbf.setFeature(FEATURE, false); 
         FEATURE = "http://xml.org/sax/features/external-general-entities"; 
             dbf.setFeature(FEATURE, false);
        FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; 
             dbf.setFeature(FEATURE, false); 
             dbf.setXIncludeAware(false); 
             dbf.setExpandEntityReferences(false); 
         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); 
}

(四)小结


        为了防御 XXE 漏洞,较为有效的处理方式是开发者在不影响系统业务的前提下做好安全配置。如果系统业务需要引用外部实体,应在后端做好参数校验。
        此外,有许多第三方组件曾被爆出 XXE 漏洞(例如, Spring-data-XMLBean 、 JavaMelody 组件 XXE Apache OFBiz 、微信支付 SDK-XXE ),建议读者朋友关注这类安全问题,避免因为使用第三方组件而引入 XXE 漏洞。

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_61506558/article/details/128060343

[网络安全自学篇] 四十八.Cracer第八期——(1)安全术语、Web渗透流程、Windows基础、注册表及黑客常用DOS命令-爱代码爱编程

这是作者的网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您们喜欢,一起进步。前文分享了微软证书漏洞(CVE-2020-0601),并详细讲解了Windows验证机制、可执行文件签名复现及HTTPS劫持。本文将分享另一个主题——Cracer教程,第一篇文章将详细讲解安全术语、Web渗透流程和Windows基础、注册

XXE漏洞(2)漏洞实战-爱代码爱编程

  本次测试XXE主要在靶机上安装了bWAPP程序,中间有一关为XXE漏洞很好做测试了解XXE漏洞。 靶机:192.168.56.101 攻击机kali:192.168.56.1 目录 了解XXE漏洞原理 漏洞成因 怎么判断网站是否存在XXE漏洞 基本利用 XML漏洞利用 任意文件读取 有回显的xxe利用 读取特殊符号文件 没有回

1.7服务端漏洞——XXE漏洞原理-爱代码爱编程

XXE漏洞原理 1.XXE是什么 XXE全称是——XML External Entity,也就是XML外部实体注入攻击.漏洞是在对不安全的外部实体数据进行处理时引发的安全问题。 xml实体注入就是利用了客户端返回xml提交数据时,注入远程调用xml实体的代码来实现一些想要的功能。 要想搞懂XXE,肯定要先了解XML语法规则和外部实体的定义及调用形式

Java代码审计漏洞挖掘(入门)-爱代码爱编程

出品|MS08067实验室(www.ms08067.com) 双十一最有意义的事情莫过于是学习一门高级渗透技术了! 代码审计属于高级渗透测试服务的一环,顾名思义就是检查源代码中的安全缺陷,检查程序源代码是否存在安全隐患,或者有编码不规范的地方,通过自动化工具或者人工审查的方式,对程序源代码逐条进行检查和分析,发现这些源代码缺陷引发的安全漏洞,并提

【网络安全】JAVA代码审计—— XXE外部实体注入-爱代码爱编程

一、WEB安全部分 想要了解XXE,在那之前需要了解XML的相关基础 二、XML基础 2.1 XML语法 所有的XML元素都必须有一个关闭标签 XML标签对大小写敏感 XML必须正确嵌套 XML 文档必须有根元素 XML属性值必须加引号 实体引用,在标签属性,以及对应的位置值可能会出现<>符号,但是这些符号在对应的XML中都是有特殊含义

渗透测试工程师常见面试33题——应届生-爱代码爱编程

渗透测试工程师常见面试题——应届生 目录(33题) 渗透测试工程师常见面试题——应届生问1:关于sql注入,都分为那些?答1:主要分为两个大类,有回显和无回显。其中无回显的称为盲注,包括时间盲注、DNSlog注入也算一种,布尔盲注;有回显的包括联合注入、报错注入、宽字节注入、堆叠注入、二次注入也算是。问2:你刚才说的DNSlog注入,用到那些函数

10 个 java 安全最佳实践_allway2的博客-爱代码爱编程

Java 安全问题 尽管我们都致力于编写出色的代码,但 Java 安全性并不总是开发人员思维的一部分。但是,防止 Java 安全问题应该与使您的 Java 应用程序具有高性能、可扩展性和可维护性一样重要。 您还应该注意 Java 中的新漏洞,例如Log4Shell (CVE-2021-44228),这些漏洞于 2021 年 12 月披露,影响运行 Ap

web渗透-sql注入_yikjiang_的博客-爱代码爱编程

渗透测试基础 一、渗透攻击流程 二、渗透测试主流工具 域名注册信息查询: Whois在线查询目标网络信息DNS和IP,nslookup 在线漏洞搜索引擎: fofa.info,shodan.io,zoomeyes

portswigger xml外部实体注入(xxe)_weixin_42451330的博客-爱代码爱编程

一、漏洞原理         当应用程序使用 XML 格式传输数据,应用程序使用的是标准库来处理上传到服务器上的 XML 数据。由于XML 规范中包含了各种潜在的危险功能,而标准的解析器支持这些危险的功能,进而导致了XXE漏洞,换句话说就是引用了外部的恶意DTD。 二、常见利用方式         1、利用外部实体检索文件 <!DOCTYPE

java代码审计-爱代码爱编程

一、java编译篇 java编译过程: Java源代码 ——(编译)——> Java字节码 ——(解释器)——> 机器码 Java源代码 ——(编译器 )——> jvm可执行的Java字节码 ——(jvm解释器) ——> 机器可执行的二进制机器码 ——>程序运行 采用字节码的好处:高效、可移植性高 以下示例为.jav

java代码审计详解-爱代码爱编程

一、Fortify代码审计工具 1、Fortify简介 Fortify是Micro Focus旗下AST (应用程序安全测试)产品 ,其产品组合包括:Fortify Static Code Analyzer提供静态代码分析器(SAST),Fortify WebInspect是动态应用安全测试软件(DAST),Software Security Cent