问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Apache ActiveMQ jolokia 远程代码执行漏洞分析(CVE-2022-41678)
漏洞分析
Apache ActiveMQ jolokia 远程代码执行漏洞利用与分析(CVE-2022-41678)
一、漏洞分析 ====== 漏洞点位于/api/jolokia接口,通过webapps/api/WEB-INF/web.xml可得知对应的Servlet是`org.jolokia.http.AgentServlet` ![image-20231130165023885](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-2883850dcd5c75b0e3cc543bef8c2053ee6e46fc.png) 1.1 调用栈分析 --------- 跟进到该类看代码,在handle中调用了handleSecurely() ![image-20231130165421294](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-7630171f151ad72e8921768d74ee0f34b768c33d.png) 跟进handleSecurely方法,这里并没有传递`org.jolokia.jaasSubject`属性,所以执行了`pReqHandler.handleRequest(pReq, pResp);` ![image-20231130170631384](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-3f8630755e96e3e3d231cc094ac6b9a448233c9b.png) 继续跟进handleRequest方法,这里创建了`ServletRequestHandler`对象返回给`json`来处理POST类型的HTTP请求 ![image-20231130171321726](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-1f47d6510489c2c0d08180a68fc3068ae864034b.png) ![image-20231130172341410](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-941134ef2b626a703f023f45c4ab53246a22fcac.png) ![image-20231130172010857](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-35d45a08285c3a9db8b155897e381d5bc1635ed7.png) 这里extractJsonRequest方法的确就是从POST请求的输入流中,读取输入数据,然后解析出JSON格式的数据,转换为JSON对象,然后利用JmxRequestFactory来创建一个JmxRequest对象,其中封装了对JMX管理功能的相关请求信息。然后调用executeRequest处理。 继续跟进executeRequest ![image-20231130172814360](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-7fbd81e096b5f08219a644680f90fe67ae4434ec.png) 这里调用了backendManager.handleRequest,继续跟进 ![image-20231130173030055](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-126f147d5427d67ae5cf4bf1e8a561c1ff145ce6.png) 调用callRequestDispatcher方法,传入JmxRequest请求对象,进行请求调度处理,继续跟进 ![image-20231130173713178](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-c8918d27156c07bfe5d4ce054064318ea1f95524.png) 通过一层层的调度和分发,最终将JMX请求交给了对应的`ExecHandler`来处理EXEC类型的请求。 ```java public Object doHandleRequest(MBeanServerConnection server, JmxExecRequest request) throws InstanceNotFoundException, AttributeNotFoundException, ReflectionException, MBeanException, IOException { // 1. 提取目标MBean中操作的名称、参数类型等元信息 OperationAndParamType types = this.extractOperationTypes(server, request); // 2. 准备参数数组,将请求参数转换为操作方法参数类型 int nrParams = types.paramClasses.length; Object[] params = new Object[nrParams]; List<Object> args = request.getArguments(); // 3. 验证参数数量、类型是否匹配 this.verifyArguments(request, types, nrParams, args); // 4. 将请求参数转换为操作方法的参数类型 for(int i = 0; i < nrParams; ++i) { if (types.paramOpenTypes != null && types.paramOpenTypes[i] != null) { // 使用 OpenTypeConverter 处理复杂类型 params[i] = this.converters.getToOpenTypeConverter().convertToObject(types.paramOpenTypes[i], args.get(i)); } else { // 使用 ToObjectConverter 处理基本类型 params[i] = this.converters.getToObjectConverter().prepareValue(types.paramClasses[i], args.get(i)); } } // 5. 利用JMX API调用目标MBean对象的操作方法 return server.invoke( request.getObjectName(), types.operationName, params, types.paramClasses); } ``` 总结就是: 1. request.getObjectName() 获取了请求中指定的目标MBean的对象名(ObjectName) 2. types.operationName 获取了请求中指定的目标MBean中的方法名 3. params 包含了请求中传入的方法参数 4. types.paramClasses 包含了目标方法的参数类型 5. 然后利用JMX服务器的MBeanServerConnection对象的invoke方法,按照JMX的反射调用机制,动态调用了目标MBean中的指定方法 通过这种方式,请求可以构造一个任意已注册在JMX服务器中的MBean对象以及其方法,然后动态执行其中的方法 1.2 构造RCE --------- 根据补丁来看,修改了jolokia-access.xml文件。在 ActiveMQ 中,`jolokia-access.xml` 文件用于定义哪些 MBean 和操作是允许或拒绝的。 其中新增了对jdk.management.jfr:type=FlightRecorder的限制,拒绝了对该 MBean 的所有属性和操作的访问。 在Apache的官方通告中,也说明了RCE是通过FlightRecorder来实现的,并且告诉了步骤: 1. 调用newRecording 2. 调用setConfiguration,其中包含Webshell数据 3. 调用startRecording 4. 调用copyTo方法来写入WebShell ![image-20231201095124027](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-b4b43ad3075273b46ed69ea77a49ec073a78e7c5.png) 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实例,并进行后续的配置、开始/停止记录等操作 ```java public long newRecording() { MBeanUtils.checkControl(); getRecorder(); // ensure notification listener is setup return AccessController.doPrivileged(new PrivilegedAction<Recording>() { @Override public Recording run() { return new Recording(); } }, null, new FlightRecorderPermission("accessFlightRecorder")).getId(); } ``` **setConfiguration()** 传入Recorder ID和配置文件,解析配置文件,如果符合格式,就会采用该配置文件 ```java public void setConfiguration(long recording, String configuration) throws IllegalArgumentException { Objects.requireNonNull(configuration); MBeanUtils.checkControl(); try { Configuration c = Configuration.create(new StringReader(configuration)); getExistingRecording(recording).setSettings(c.getSettings()); } catch (IOException | ParseException e) { throw new IllegalArgumentException("Could not parse configuration", e); } } ``` 在[Oracle官方文档](https://docs.oracle.com/en/java/javase/17/jfapi/flight-recorder-configurations.html#GUID-51B499C9-CF15-48EE-9AAA-47BB69CBDABF)中有介绍默认模版在`<java_home>/lib/jfr/default.jfc` ![image-20231201112750384](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-e41f72251728a69b00e43cca28ddfeb4c6d15363.png) ![image-20231201112923849](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-52c2bf600ea1798ee967fa0c8a34281b7fbc3d46.png) 构造包含WebShell的配置文件,特殊字符经过html实体编码 ![image-20231201133018224](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-15c10f8fa97c546864236543fbe7140a41401390.png) **startRecording** 传入Recording ID,然后开始录制 ```java public void startRecording(long id) { MBeanUtils.checkControl(); getExistingRecording(id).start(); } ``` **stopRecording**传入Recording ID,结束录制 ```java public boolean stopRecording(long id) { MBeanUtils.checkControl(); return getExistingRecording(id).stop(); } ``` **copyTo** 传入Recording ID和保存路径,这个路径没做限制,我们可以路径穿越到web目录去 ```java public void copyTo(long recording, String path) throws IOException { Objects.requireNonNull(path); MBeanUtils.checkControl(); getExistingRecording(recording).dump(Paths.get(path)); } ``` 二、利用完整思路 ======== 1. 构造恶意请求,传入目标MBean为FlightRecorderMXBean,调用FlightRecorderMXBean的newRecording方法创建一个新的Recording对象 2. 调用setConfiguration方法,设置Recording使用的配置文件,在配置文件中的键名中插入WebShell。由于导出的数据会包含键名,所以当我们在键名中插入WebShell时,导出的数据也会包含该WebShell 3. 调用startRecording开启事件记录 4. 调用stopRecording停止事件记录 5. 调用copyTo方法,将记录的数据保存到指定文件,这里我们可以指定为web应用目录下的一个jsp文件 6. 这样最终就实现了写入一个包含恶意命令执行代码的WebShell文件,之后访问这个WebShell,命令就会被执行 三、漏洞复现 ====== 从[stackoverflow](https://stackoverflow.com/questions/27707190/activemq-jolokia-api-how-can-i-get-the-full-message-body)找到了jolokia api的使用案例 ![image-20231201132405830](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-c5dfd2a05b4040db553a93760c88ee4285fdc5b2.png) **构造数据包:** 1、调用newRecording,获取ID为1 ```http POST /api/jolokia/ HTTP/1.1 Host: 172.23.80.196:8161 Origin:172.23.80.196:8161 Authorization: Basic YWRtaW46YWRtaW4= Content-Type: application/json { "type": "EXEC", "mbean": "jdk.management.jfr:type=FlightRecorder", "operation": "newRecording", "arguments": [] } ``` ![image-20231201133945413](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-d54ecea017846a14fafb0d4aa3cd929f98e09ed5.png) 2、调用setConfiguration构造包含WebShell的配置文件,注意需要把xml数据的双引号转义并去除换行 ![image-20231201134832579](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-230797c06c5a5bfef4262463718485dcddcb6c96.png) 3、开始录制数据 ![image-20231201134950619](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-e21a7f41118b55d9e80f53c0ee8e3cf951ca2c23.png) 4、结束录制 ![image-20231201135020826](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-460e30835b3ee07c58295a37ae819f3111eab1f5.png) 5、调用copyTo,将文件写入webapps/admin/le1a.jsp ![image-20231201135637663](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-56ea241b6714f08dba54445e83fe9d9f33d26e82.png) 6、访问/admin/le1a.jsp,成功弹出计算器,漏洞验证成功 ![image-20231201135554385](https://shs3.b.qianxin.com/attack_forum/2024/01/attach-641a2937c9f1cf9d00a7c02409bb41ceb2346ce8.png)
发表于 2024-01-16 10:19:19
阅读 ( 29347 )
分类:
漏洞分析
1 推荐
收藏
0 条评论
请先
登录
后评论
jweny
16 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!