从JDK源码来看XXE的触发原理和对应的防御手段

news2024/12/23 23:35:45

前言

这几天继续在重写GadgetInspector工具,进一步的增强该自动化工具的source点和sink点,同时增强过程中的漏报和误报的问题。

这里主要是对其中有关于XXE中的两点sink进行几点分析。

sinks

DocumentBuilder类

这个JDK中内置的类是一种的DOM型的解释器,该种Parser的特点是将完整的xml文档内容加载到树结构中去,然后我们通过遍历结点来获取我们需要的内容。

首先编写一段实例代码,来使用DocumentBuilder类来读取xml文档的内容。

Employee.xml

<employees>
    <employee id="111">
        <firstName>Rakesh</firstName>
        <lastName>Mishra</lastName>
        <location>Bangalore</location>
    </employee>
    <employee id="112">
        <firstName>John</firstName>
        <lastName>Davis</lastName>
        <location>Chennai</location>
    </employee>
    <employee id="113">
        <firstName>Rajesh</firstName>
        <lastName>Sharma</lastName>
        <location>Pune</location>
    </employee>
</employees>

DOMParserDemo.java

public class DOMParserDemo {
    public static void main(String[] args) throws Exception{
        // 获取DOM Builder Factory
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // 获取DOM Builder
        DocumentBuilder builder = factory.newDocumentBuilder();

        // 加载xml文档
        Document document = builder.parse("Employee.xml");

        // 建立一个链表存放Employee对象
        List<Employee> employeeList = new ArrayList<>();

        // 提取数据
        NodeList nodeList = document.getDocumentElement().getChildNodes();

        // 迭代进行读取xml文档
        for (int i = 0; i < nodeList.getLength(); i++) {
            // 获取对应结点,这里的结点是employee标签
            Node node = nodeList.item(i);

            if (node instanceof Element) {
                // 创建一个Employee空对象
                Employee employee = new Employee();
                // 获取xml文档中的id值
                employee.id = node.getAttributes().getNamedItem("id").getNodeValue();
                // 获取子结点信息
                NodeList childNodes = node.getChildNodes();
                for (int j = 0; j < childNodes.getLength(); j++) {
                    // 获取对应结点
                    Node node1 = childNodes.item(j);
                    if (node1 instanceof Element) {
                        // 获取对应的信息
                        String content = node1.getTextContent().trim();
                        switch (node1.getNodeName()) {
                            case "firstName":
                                employee.firstName = content;
                                break;
                            case "lastName":
                                employee.lastName = content;
                                break;
                            case "location":
                                employee.location = content;
                                break;
                        }
                    }
                }
                // 将获取的每一个对象添加进入列表中去
                employeeList.add(employee);
            }
        }
        // 打印数据
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
    }
}

这种方式就是遍历xml文档中的一个一个的文档来进行对应信息的读取。

image-20221218203218462.png

这里只是一个简单的使用该种解释器进行xml文档的读取。

我们主要是进行XXE的展示。

XXE.xml

<?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE test [
        <!ENTITY xxe SYSTEM "http://127.0.0.1:9999">
    ]>
<doc>&xxe;</doc>

主要的漏洞点是在调用DocumentBuilder#parse方法进行xml文档的加载的时候,如果加载的是上面给出的xml内容,将会导致XXE。

image-20221218203915774.png

简单的调试了一下。

resolveEntity:95, ChainingEntityResolver (weblogic.xml.jaxp)
resolveEntity:110, EntityResolverWrapper (com.sun.org.apache.xerces.internal.util)
resolveEntityAsPerStax:997, XMLEntityManager (com.sun.org.apache.xerces.internal.impl)
startEntity:1212, XMLEntityManager (com.sun.org.apache.xerces.internal.impl)
scanEntityReference:1908, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
next:3061, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
next:602, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanDocument:505, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
parse:842, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:771, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:243, DOMParser (com.sun.org.apache.xerces.internal.parsers)
parse:339, DocumentBuilderImpl (com.sun.org.apache.xerces.internal.jaxp)
parse:163, RegistryDocumentBuilder (weblogic.xml.jaxp)
parse:177, DocumentBuilder (javax.xml.parsers)
main:22, DOMParserDemo (study.xmlParser)

在将xml文档路径传入了DocumentBuilder#parser方法之后。

image-20221218220213785.png

将会将其转换为InputSource类传入DocumentBuilderImpl#parser方法中进行解析。

image-20221218220853160.png

这里将会调用DOMParser#parser继续进行解析。

image-20221218221015832.png

按照其中的逻辑将会一次性加载xml文件的所有内容,之后通过调用parse方法进行解析。

最后经过一系列的解析,特别是通过调用XMLDocumentFragmentScannerImpl#scanEntityReference方法的调用来扫描获取xml文件中的实体,之后方法中调用了XMLEntityManager#startEntity方法进行实体的处理。

image-20221218221758389.png

在该方法中存在有是否是外部实体的判断,如果存在有外部实体,将会调用resolveEntityAsPerStax方法来获取外部实体中的信息,这里将会发起一个请求,也即能达到前面截图中的效果。

防御方法

  1. 可以采用禁用所有DTDs的方式.

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true);

  2. 如果业务需要存在有DTD的使用,我们可以转而求其次,禁用XML中的外部实体和参数实体.

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setFeature(“http://xml.org/sax/features/external-general-entities”, false); //防止外部实体
    dbf.setFeature(“http://xml.org/sax/features/external-parameter-entities”, false); //防止参数实体

  3. 较为完整的修复方式。

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    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);
    DocumentBuilder builder = dbf.newDocumentBuilder();
    builder.parse(xxxx);

SAXParser类

接下来的一个XXE的sink点就是在SAXParser#parser方法的调用中,这种方式的xml文档的解析,主要是依靠的SAX Parser这个,这个解析器的不同于DOM
Parser,这个解释器是不会直接将完整的XML文档加载进入内存中,这种解释器转而逐行进行XML文档的解析,当他们遇到不同的元素的时候触发不同的事件,例如:开始标签
/ 结束标签 / 字符类似的数据等等事件类型,这种解释器是一种基于事件的解释器。

这里也是简单的举一个例子,使用的xml文件也是上面已经提到了的Employee.xml文件内容

而对于读取xml文件的实例。

SAXParserDemo.java

public class SAXParserDemo extends Exception {
    public static void main(String[] args) throws Exception{
        // 创建SAXParser Factory
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        // 创建自定义的handler对象
        SAXHandler saxHandler = new SAXHandler();
        // 加载xml文档,加上自定义的handler对象
        saxParser.parse("Employee.xml", saxHandler);
        // 打印结果
        for (Employee employee : saxHandler.employeeList) {
            System.out.println(employee);
        }
    }

}
class SAXHandler extends DefaultHandler {
    // 定义属性
    List<Employee> employeeList = new ArrayList<>();
    Employee employee = null;
    String content = null;

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        switch (qName) {
            case "employee":
                // 如果遇到了employee标签采用的逻辑
                employee = new Employee();
                employee.id = attributes.getValue("id");
                break;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        switch (qName) {
            // 遇到结束标签采用的逻辑
            case "firstName":
                employee.firstName = content;
                break;
            case "lastName":
                employee.lastName = content;
                break;
            case "location":
                employee.location = content;
                break;
            case "employee":
                employeeList.add(employee);
                break;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        content = String.copyValueOf(ch, start, length).trim();
    }
}

这种解释器的方式,主要是在传入xml文件路径的时候,同时传入了一个handler对象,这个对象是继承了DefaultHandler这个内置的默认Handler对象的。

在这个类中定义了很多方法。

image-20221218224652398.png

在查看这个类的结构的时候,其中这个类是实现了几个接口的,其中实现的有一个接口是ContentHandler,在这个接口中定义了多个和XML文档内容有关的方法。

  • startDocument()

  • endElement()

  • endDocument()

  • startElement()

有关这些方法的作用,也是很明显,运行一下子看看效果。

image-20221218225941740.png

如果我们将XML文档的地址替换成XXE.xml路径,同样将会触发XXE,同样简单的调试了一下。

startElement:36, SAXHandler (study.xmlParser)
startElement:509, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
startElement:745, XMLDTDValidator (com.sun.org.apache.xerces.internal.impl.dtd)
scanStartElement:1359, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanRootElementHook:1289, XMLDocumentScannerImpl$ContentDriver (com.sun.org.apache.xerces.internal.impl)
next:3132, XMLDocumentFragmentScannerImpl$FragmentContentDriver (com.sun.org.apache.xerces.internal.impl)
next:852, XMLDocumentScannerImpl$PrologDriver (com.sun.org.apache.xerces.internal.impl)
next:602, XMLDocumentScannerImpl (com.sun.org.apache.xerces.internal.impl)
scanDocument:505, XMLDocumentFragmentScannerImpl (com.sun.org.apache.xerces.internal.impl)
parse:842, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:771, XML11Configuration (com.sun.org.apache.xerces.internal.parsers)
parse:141, XMLParser (com.sun.org.apache.xerces.internal.parsers)
parse:1213, AbstractSAXParser (com.sun.org.apache.xerces.internal.parsers)
parse:643, SAXParserImpl$JAXPSAXParser (com.sun.org.apache.xerces.internal.jaxp)
parse:392, SAXParser (javax.xml.parsers)
parse:274, SAXParser (javax.xml.parsers)
main:20, SAXParserDemo (study.xmlParser)

对于这种解释器,和上面的一种不同在于,前面主要是调用的DOMParser类进行解析,而这里主要是调用了SAXParser类进行解析。

在对应的parse方法中。

image-20221219192432895.png

传入了两个参数,一个是XML文档的路径,一个是自己实现的继承了DefaultHandler类的类对象

在将XML文档路径封装成了InputSource对象之后进行解析的逻辑。

image-20221219192713039.png

这里不同于前面的,这里在创建了一个XMLReader对象之后,设定了对应的Handler对象。

独特的点体现在调用XMLDocumentFragmentScannerImpl#scanDocument方法进行XML的扫描的过程中

在扫描到ROOT Element位置的时候,将会触发对应的Hook点。

image-20221219194828661.png

具体点就是调用了scanRootElementHook方法。

image-20221219195111257.png

image-20221219195122866.png

这里是配置了对应的Handler的,这里将会在AbstractSAXParser#startElement方法的调用中,调用其中的ContentHandler的对象方法进行处理。

image-20221219195254624.png

防御方法。

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);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
SAXParser parser = spf.newSAXParser();
parser.parse(InputSource, (HandlerBase) null);

f.setFeature(“http://xml.org/sax/features/external-general-entities”, false);
spf.setFeature(“http://xml.org/sax/features/external-parameter-entities”, false);
spf.setFeature(“http://apache.org/xml/features/nonvalidating/load-external-dtd”, false);
SAXParser parser = spf.newSAXParser();
parser.parse(InputSource, (HandlerBase) null);

最后

分享一个快速学习【网络安全】的方法,「也许是」最全面的学习方法:
1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)

2、渗透测试基础(一周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等

3、操作系统基础(一周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)

4、计算机网络基础(一周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现

5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固

6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)

在这里插入图片描述

恭喜你,如果学到这里,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web 渗透、安全服务、安全分析等岗位;如果等保模块学的好,还可以从事等保工程师。薪资区间6k-15k。

到此为止,大概1个月的时间。你已经成为了一名“脚本小子”。那么你还想往下探索吗?

想要入坑黑客&网络安全的朋友,给大家准备了一份:282G全网最全的网络安全资料包免费领取!
扫下方二维码,免费领取

有了这些基础,如果你要深入学习,可以参考下方这个超详细学习路线图,按照这个路线学习,完全够支撑你成为一名优秀的中高级网络安全工程师:

高清学习路线图或XMIND文件(点击下载原文件)

还有一些学习中收集的视频、文档资源,有需要的可以自取:
每个成长路线对应板块的配套视频:


当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。

因篇幅有限,仅展示部分资料,需要的可以【扫下方二维码免费领取】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/358979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基础组件之内存池

内存池技术 操作系统在运行进程的过程中&#xff0c;会产生内存碎片&#xff0c;降低了内存的使用率。内存池技术就是为了解决/减少内存碎片的一种方法&#xff0c;内部底层的具体实现根据不同业务场景使用不要的方式&#xff0c;以下是一种好理解的方式&#xff0c;供大家一起…

光学分辨率光声显微镜中基于深度学习的运动校正算法

在这项研究中&#xff0c;我们提出了一种基于深度学习的方法来校正光学分辨率光声显微镜 (OR-PAM) 中的运动伪影。该方法是一种卷积神经网络&#xff0c;它从具有运动伪影的输入原始数据建立端到端映射&#xff0c;以输出校正后的图像。首先&#xff0c;我们进行了仿真研究&…

PYTHON爬虫基础

一、安装package 在使用爬虫前&#xff0c;需要先安装三个包&#xff0c;requests、BeautifulSoup、selenium。 输入如下代码&#xff0c;若无报错&#xff0c;则说明安装成功。 import requests from bs4 import BeautifulSoup import selenium二、Requests应用 了解了原理…

关于IDEA中Thread.activeCount()的问题记录

回顾&#xff1a; Thread类的activeCount()方法用于返回当前线程的线程组中活动线程的数量。返回的值只是一个估计值&#xff0c;因为当此方法遍历内部数据结构时&#xff0c;线程数可能会动态更改。总之它返回当前线程的线程组中活动线程的数量。 在研究多线程对同一变量的修…

【FAQ】集成分析服务的常见问题及解决方案

常见问题一&#xff1a;如何验证Analytics是否上报/接入成功&#xff1f;以及关键日志含义是什么&#xff1f; 在初始化Analytics SDK前添加SDK日志开关如下&#xff1a; HiAnalyticsTools.enableLog (); 2.初始化SDK代码如下&#xff1a; HiAnalyticsInstance instance Hi…

kettle安装部署_简单认识_Spoon勺子界面---大数据之kettle工作笔记002

然后我们来看一下这个kettle的安装,很简单,下载解压就可以了 上面的地址是官网很烂 下面的地址好一些 这个是官网可以看到很慢,很不友好 这个是下面那个地址,可以看到 最新的是9.0了,一般都用 一般都用8.2 这里下载这个就可以了 下载以后可以看到有个pdi

【代码随想录训练营】【Day19休息】【Day20】第六章|二叉树|654.最大二叉树|617.合并二叉树|700.二叉搜索树中的搜索|98.验证二叉搜索树

最大二叉树 题目详细&#xff1a;LeetCode.654 这道题在题目几乎就说明了解题的思路了&#xff1a; 创建一个根节点&#xff0c;其值为 nums 中的最大值&#xff1b;递归地在最大值左边的子数组上构建左子树&#xff1b;递归地在最大值右边的子数组上构建右子树&#xff1b;…

计算机系统基础知识

计算机的基本组成 计算机组成逻辑图 计算机部件作用 一级部件作用 运算器&#xff1a;计算机的执行部件&#xff0c;受控制器控制&#xff0c;执行算术运算或逻辑运算控制器&#xff1a;决定计算机运行过程的自动化。不仅能保证程序指令的正确执行&#xff0c;还能处理异常事…

12款适合小团队协作、任务管理和进度跟踪的在线任务管理的工具推荐?

国内外12款主流任务管理软件测评: 1.开发任务管理PingCode; 2.多合一项目任务管理Worktile;3.个人和小团队项目任务管理Notion; 4.企业任务管理平台SmartTask; 5.小团队任务管理Teambition;6.IT任务追踪管理Jira等。无论是做好工作任务管理还是个人任务管理&#xff0c;从来都不…

web网页如何实现响应式导航栏--移动端导航栏

背景&#xff1a; 一提到响应式导航栏&#xff0c;大家第一反应可能就是bootstrap响应式导航栏&#xff0c;这个响应式的一般是针对屏幕变小时&#xff0c;视口出现导航栏&#xff0c;可是&#xff0c;展示到移动端的时候&#xff0c;并没有变化&#xff1f;&#xff1f;&#…

LabVIEW利用矢量量化直方图开发人脸识别

LabVIEW利用矢量量化直方图开发人脸识别通常&#xff0c;人脸识别系统会检查场景的静止图像或视频图像&#xff0c;然后使用存储的人脸数据库识别或验证场景中的一个或多个人。我程序专注于静止图像人脸识别&#xff0c;使用来自众所周知的人脸数据库的人脸图像&#xff0c;用于…

Prometheus之pushgateway

Pushgateway简介 Pushgateway是Prometheus监控系统中的一个重要组件&#xff0c;它采用被动push的方式获取数据&#xff0c;由应用主动将数据推送到pushgateway&#xff0c;然后Prometheus再从Pushgateway抓取数据。使用Pushgateway的主要原因是&#xff1a; Prometheus和targ…

Teradata 离场,企业数据分析平台如何应对变革?

近日大数据分析和数仓软件巨头 Teradata&#xff08;TD&#xff09;宣布基于中国商业环境的评估&#xff0c;退出在中国的直接运营。TD 是全球最大的专注于大数据分析、数仓和整合营销管理解决方案的供应商之一&#xff0c;其早在 1997 年就进入中国&#xff0c;巅峰期占据半数…

基于卷积神经网络图像风格迁移系统的设计与实现(flask系统)

1.摘要 Leon Gatys 等人研发的深度神经网络使用神经的表达来分离任意图片的内容和风格&#xff0c;为生成艺术图片提供一个神经算法。本文基于Style Transfer算法&#xff0c;使用风格成本函数训练CNN&#xff0c;用卷积神经网络提取图像特征&#xff0c;依次提取内容图像的内…

数据库面试——锁的12连问,赶紧收藏!

目录 1. 为什么需要加锁 2. InnoDB有哪些锁&#xff1f; 2.1 共享/排他锁 2.2 意向锁 2.3 记录锁&#xff08;Record Lock&#xff09; 2.4 间隙锁&#xff08;Gap Lock&#xff09; 2.5 临键锁(Next-Key Lock) 2.6 插入意向锁 2.7 自增锁 3. 什么是死锁&#xff1f;如…

从红队视角看AWD攻击

AWD的权限维持 攻防兼备AWD模式是一种综合考核参赛团队攻击、防御技术能力、即时策略的比赛模式。在攻防模式中&#xff0c;参赛队伍分别防守同样配置的虚拟靶机&#xff0c;并在有限的博弈时间内&#xff0c;找到其他战队的薄弱环节进行攻击&#xff0c;同时要对自己的靶机环…

20230220华南金牌主板u盘启动

20230220华南金牌主板u盘启动 2023/2/20 10:29 百度搜索&#xff1a;华南金牌主板u盘启动 https://www.zhihu.com/question/498121895?utm_id0 华南金牌主板b85u盘启动怎么设置? 华南金牌主板b85u盘启动怎么设置 海的那边 上小学后才发现还是幼儿园好混…… 华南一般是F7和F1…

ADRC自抗扰控制总结

目录 前言 1.ADRC形式 1.1形一 1.2形二 2.被控对象 3.仿真分析 3.1仿真模型 3.2仿真结果 4.学习问题 前言 前面的3篇文章依次介绍了微分跟踪器TD、状态观测器ESO和非线性状态误差反馈NLSEF三部分内容&#xff0c;至此ADRC的结构已经介绍完毕&#xff0c;现在对分块学习…

【数据结构与算法】2.八大经典排序

文章目录简介1.分析排序算法2.插入排序2.1.直接插入排序2.2.希尔排序3.选择排序3.1.直接选择排序3.2.堆排序3.2.1.堆的数据结构3.2.2.算法实现4.交换排序4.1.冒泡排序4.2.快速排序5.归并排序6.基数排序7.八大排序算法总结简介 排序对于任何一个程序员来说&#xff0c;可能都不会…

从技术上来看,互联网技术开始衍生和蜕变出更多的新技术

很多人在看待产业互联网的问题上&#xff0c;一味地割裂它与互联网之间的联系&#xff0c;甚至还有人将产业互联网看成是对于传统互联网的颠覆。如果仅仅只是以这样的眼光来看待产业互联网&#xff0c;那么&#xff0c;他们势必是无法完整把握产业互联网的本质内涵和原始奥义的…