CVE-2024-43044 Jenkins Remoting远程代码执行漏洞分析

Jenkins是一个开源软件项目,是基于java开发的一种持续集成工具,用于监控持续重复的工作。而在此过程中,Agent执行机就是其中关键的一部分,负责执行构建和部署任务。简单来说Agent 就是一个独立的进程或者节点,可以是独立的服务器、虚拟机或者是本地机器,用来执行构建和部署任务,当Jenkins主服务器连接到Agent的时候,就可以在该节点上运行相应的任务

前言

Jenkins是一个开源软件项目,是基于java开发的一种持续集成工具,用于监控持续重复的工作。而在此过程中,Agent执行机就是其中关键的一部分,负责执行构建和部署任务。简单来说Agent 就是一个独立的进程或者节点,可以是独立的服务器、虚拟机或者是本地机器,用来执行构建和部署任务,当Jenkins主服务器连接到Agent的时候,就可以在该节点上运行相应的任务

而Jenkins Remoting远程代码执行漏洞(CVE-2024-43044)的产生原因就是获取到Agent节点机器的权限后,可以通过节点连接到Jenkins Remoting主服务器,获取服务器上的文件内容。

影响版本

Jenkins weekly <= 2.470
Jenkins LTS <= 2.452.3

环境搭建

可以使用vulhub/CVE-2024-23897的环境

version: '2.2'  
services:  
  jenkins:  
    image: vulhub/jenkins:2.441  
    ports:  
      - "50000:50000"  
      - "8080:8080"  
      - "5005:5005"  
    init: true  
    environment:  
      - DEBUG=1

启动之后访问http://127.0.0.1:8080 正常说明搭建成功,使用admin/vulhub可以登录到后台

导航Dashboard -> Manage Jenkins ->Nodes 处新建一个Agent节点

image-20240819092819581.png

选项可以保持默认的,点击save,新建完成之后就可以看到新建成功的节点

image-20240819092911339.png

image-20240819093051238.png
导航Dashboard -> Manage Jenkins -> Plugins 安装插件 Websocket Notifier

image-20240819093534520.png

安装完成之后在节点机器node1连接到Jenkins 主服务器

连接成功后在Jenkins主服务器上可以看到已连接的标识,成功连接之后就可以在Agent节点上部署任务了

image-20240819095256961.png

image-20240819095328807.png

漏洞复现

当获取到node1机器的权限后,可以得到连接到Jenkins主服务器的secret和name,这时需要将连接使用的agent.jar替换成恶意的Agent连接Jar包,https://github.com/v9d0g/CVE-2024-43044-POC

使用恶意的Jar包重新连接到Jenkins主服务器,就可以读取文件

java -jar agent1.jar -url http://192.168.85.129:8080/ -secret xxxxxx -name xxxx

image-20240819100942827.png

漏洞分析

Agent节点连接到Jenkins主服务器使用的是JNLP协议,JNLP(Java Network Launch Protocol)是一个用于从网络启动 Java 应用程序的协议,通常用于在 Jenkins 等 CI/CD 工具中启动构建代理(也称为 "节点")

在agent.jar中可以看到修改的地方在hudson/remoting/RemoteClassLoader.class,利用JD反编译JAR包得到源代码文件后,在IDEA中下断点调试

// 使用下面的命令启动agent.jar
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar agent1.jar -url http://192.168.85.147:8080/ -secret xxxxx -name node1 -workDir ""

先启动agent.jar再开启调试,当输入文件path后程序会在断点处停下

在RemoteClassLoader()方法里,首先会初始化一个channel对象,该对象用于在主服务器和代理节点之间进行通信,它负责管理数据的传输和命令的发送

image-20240819114418794.png

接着会执行到断点处this.proxy.fetchJar(),this.proxy是一个代理对象,fetchJar是proxy对象下的一个方法,当Jenkins主服务器在Agent节点上部署任务时,节点需要从主服务上下载一些必要的JAR包和文件,fetch()会处理与主服务器间的通信,并获取资源内容

image-20240819114504731.png

程序会进入到hudson.remoting.RemoteInvocationHandler#invoke()下,会执行到req.call()

image-20240819120212663.png

接着会进入到hudson.remoting.Request#call(),想Jenkins主服务器发送请求

image-20240819111641694.png

this.response就是返回的资源内容,this.response.returnValue解码之后就是文件的内容

image-20240819141052358.png

漏洞修复

在修改版本中添加了一个判断函数,限制jarUrl只能为插件Jar包

https://github.com/jenkinsci/jenkins/commit/3f54c41b40db9e4ae7afa4209bc1ea91bb9175c0

image-20240819141707412.png

在修复版本的jenkins.security.s2m#validate()中下断点,当使用原来的利用方式再次请求时,程序会自动调用到validate()

image-20240819142254393.png

image-20240819142347019.png

最终会进入到isPluginJar()中,在该方法里会判断jarUrl是否为合法的插件,不是的话会返回false抛出异常

image-20240819142544894.png

image-20240819144422927.png

参考

https://github.com/v9d0g/CVE-2024-43044-POC

0 条评论