Apache ActiveMQ jolokia 远程代码执行漏洞分析(CVE-2022-41678)
type
status
date
slug
summary
tags
category
icon
password
AI summary
文章首发自:奇安信攻防社区
漏洞点位于/api/jolokia接口,通过webapps/api/WEB-INF/web.xml可得知对应的Servlet是
org.jolokia.http.AgentServlet

调用栈分析
跟进到该类看代码,在handle中调用了handleSecurely()

跟进handleSecurely方法,这里并没有传递
org.jolokia.jaasSubject
属性,所以执行了pReqHandler.handleRequest(pReq, pResp);

继续跟进handleRequest方法,这里创建了
ServletRequestHandler
对象返回给json
来处理POST类型的HTTP请求


这里extractJsonRequest方法的确就是从POST请求的输入流中,读取输入数据,然后解析出JSON格式的数据,转换为JSON对象,然后利用JmxRequestFactory来创建一个JmxRequest对象,其中封装了对JMX管理功能的相关请求信息。然后调用executeRequest处理。
继续跟进executeRequest

这里调用了backendManager.handleRequest,继续跟进

调用callRequestDispatcher方法,传入JmxRequest请求对象,进行请求调度处理,继续跟进

通过一层层的调度和分发,最终将JMX请求交给了对应的
ExecHandler
来处理EXEC类型的请求。- request.getObjectName() 获取了请求中指定的目标MBean的对象名(ObjectName)
- types.operationName 获取了请求中指定的目标MBean中的方法名
- params 包含了请求中传入的方法参数
- types.paramClasses 包含了目标方法的参数类型
- 然后利用JMX服务器的MBeanServerConnection对象的invoke方法,按照JMX的反射调用机制,动态调用了目标MBean中的指定方法
通过这种方式,请求可以构造一个任意已注册在JMX服务器中的MBean对象以及其方法,然后动态执行其中的方法
RCE
根据补丁来看,修改了jolokia-access.xml文件。在 ActiveMQ 中,
jolokia-access.xml
文件用于定义哪些 MBean 和操作是允许或拒绝的。其中新增了对jdk.management.jfr:type=FlightRecorder的限制,拒绝了对该 MBean 的所有属性和操作的访问。
在Apache的官方通告中,也说明了RCE是通过FlightRecorder来实现的,并且告诉了步骤:
- 调用newRecording
- 调用setConfiguration,其中包含Webshell数据
- 调用startRecording
- 调用copyTo方法来写入WebShell

jdk.management.jfr.FlightRecorderMXBeanImpl类是JDK Flight Recorder管理接口的实现类
关于JDK Flight Recorder:
- 它是JVM内置的事件记录和分析工具,可以用来收集JVM的内部运行时信息,分析JVM和Java应用程序的行为。
- 通过它收集到的数据,可以找到各种性能问题并优化Java应用程序。
关于jdk.management.jfr.FlightRecorderMXBeanImpl类:
- 它实现了jdk.management.jfr.FlightRecorderMXBean接口。
- FlightRecorderMXBean接口定义了一系列管理Flight Recorder的方法。
- FlightRecorderMXBeanImpl实现了这些管理方法来控制Flight Recorder的行为。
- 这些方法包括:开始和停止recording,获取recording数据,设置recording的配置等。
- JConsole和其他管理工具可以通过这些MXBean接口来管理Flight Recorder。
接下来我们来跟进代码,看看这几个方法的实现
newRecording() 这里就是new一个Recording对象,返回ID,后续根据ID访问这个recording实例,并进行后续的配置、开始/停止记录等操作
setConfiguration() 传入Recorder ID和配置文件,解析配置文件,如果符合格式,就会采用该配置文件
在Oracle官方文档中有介绍默认模版在
<java_home>/lib/jfr/default.jfc


构造包含WebShell的配置文件,特殊字符经过html实体编码

startRecording 传入Recording ID,然后开始录制
stopRecording传入Recording ID,结束录制
copyTo 传入Recording ID和保存路径,这个路径没做限制,我们可以路径穿越到web目录去
完整思路如下:
- 构造恶意请求,传入目标MBean为FlightRecorderMXBean,调用FlightRecorderMXBean的newRecording方法创建一个新的Recording对象
- 调用setConfiguration方法,设置Recording使用的配置文件,在配置文件中的键名中插入WebShell。由于导出的数据会包含键名,所以当我们在键名中插入WebShell时,导出的数据也会包含该WebShell
- 调用startRecording开启事件记录
- 调用stopRecording停止事件记录
- 调用copyTo方法,将记录的数据保存到指定文件,这里我们可以指定为web应用目录下的一个jsp文件
- 这样最终就实现了写入一个包含恶意命令执行代码的WebShell文件,之后访问这个WebShell,命令就会被执行
漏洞复现
从stackoverflow找到了jolokia api的使用案例

构造数据包:
1、调用newRecording,获取ID为1

2、调用setConfiguration构造包含WebShell的配置文件,注意需要把xml数据的双引号转义并去除换行

3、开始录制数据

4、结束录制

5、调用copyTo,将文件写入webapps/admin/le1a.jsp

6、访问/admin/le1a.jsp,成功弹出计算器,漏洞验证成功!

Loading...