漏洞分析 | Jenkins 未授权文件读取漏洞(CVE-2024-23897)

Jenkins是一个流行的开源持续集成(CI)和持续交付(CD)工具,它可以帮助团队自动化软件开发中的各种任务和流程,从而提高效率和质量。

Jenkins 有一个内置的命令行界面 (CLI),可以从脚本或 shell 环境访问 Jenkins。由于Jenkins使用 args4j 库解析CLI命令参数的功能存在缺陷,攻击者可利用该漏洞读取Jenkins 控制器文件系统上的任意文件,并结合其他功能可能导致任意代码执行。目前漏洞POC已公开,风险较高。

▌漏洞原理

Jenkins提供了一个命令行的接口,用户可以下载一个命令行客户端jenkins-cli.jar到本地,并调用该客户端来执行一些Jenkins的功能。

用户使用jenkins-cli.jar时,命令行是传到服务端解析的,而不是在jenkins-cli.jar里解析。
Jenkins服务端解析命令行时使用了一个第三方库args4j,这个库实现了Linux中一个常见的功能——如果一个参数是以@开头,则会被自动认为是一个文件名,文件内容会被读取作为参数。
Jenkins是在服务端解析的命令行参数,又支持args4j的这个特性,所以造成文件读取漏洞。
该漏洞需要Jenkins启动时设置一个环境变量“DEBUG=1”。

▌漏洞影响

Jenkins 2.441及以前的版本。

▌靶场环境

Docker-compose.yaml

本次部署的jenkins的版本为2.441。

▌攻击流程

本地起docker环境后,通过本地直接下载
  • 可以直接使用官方提供的命令行客户端,在http://localhost:8080/jnlpJars/jenkins-cli.jar下载,jenkins-cli.jar文件。
  • 使用jenkins-cli.jar文件查看当前jenkins版本,可以看到版本为2.441。
  • 在进行攻击的时候有多种参数攻击方式,不同的方式读取的行数有区别
    • 造成这样的原因是
      • 使用@将文件内容加载成命令行参数,文件中的空白字符,会分割参数。例如
        • 所以1、2、3、4会变成help命令的4个参数。而解析命令行时通常只会取前面一些参数,报错也就只会把这些参数报出来,导致我们读取文件的时候只能读到文件的前几行。

    • 这样读取的方式略显鸡肋,所以有以下两个方法,可以进行读取全部内容
    • connect-node
      reload-job
    • 在读取过程中,都需要知道绝对路径的地址,可以按照以下步骤进行读取,通过读取环境变量以及CMD启动命令,了解jenkins根目录。
      • /proc/self/environ

        /proc/self/cmdline
    • 通过Jenkins的根目录,再进行读取下面这些敏感文件。
  • 旧版本Jenkins用户密码是加密而不是哈希,可以利用诸如jenkins-decrypt这样的工具来解密密码。

▌解决方案

更新至最新版本以解决该漏洞,现Jenkins2.442、LTS 2.426.3已禁用相关命令解析器功能。

网络访问控制:配置适当的网络防火墙规则,限制对Jenkins服务器和应用的访问。只允许来自受信任的IP地址或网络范围的请求通过,并阻止外部非授权访问。

▌塞讯验证规则

针对该漏洞的攻击模拟已经加入到塞讯安全度量验证平台中,您可以在塞讯安全度量验证平台中搜索关键词“CVE-2024-23897”“Jenkins”获取相关攻击模拟验证动作,从而验证您的安全防御体系是否能够有效应对该漏洞,平台以业界独有方式确保您的验证过程安全无害。