0%

Jenkins文件读取漏洞(CVE-2024-23897)

最近实在不知道做什么,跟着p神复现下比较火的漏洞

Jenkins文件读取漏洞(CVE-2024-23897)

环境搭建

用的是vulhub靶场的环境 下载地址

cd进入目录下,依次执行

1
2
3
docker-compose build
docker-compose up -d
docker-compose ps -a

访问8080端口即可

漏洞原理

Jenkins提供了一个命令行的接口,用户可以下载一个命令行客户端jenkins-cli.jar到本地,并调用该客户端来执行一些Jenkins的功能。但是用户使用jenkins-cli.jar时,命令行是传到服务端解析的,而不是在jenkins-cli.jar里解析。这就导致一个问题,就是Jenkins服务端解析命令行时使用了一个第三方库args4j,这个库实现了Linux中一个常见的功能——如果一个参数是以@开头,则会被自动认为是一个文件名,文件内容会被读取作为参数。所以就造成Jenkins文件读取漏洞。

类似的还有PHP5.5以前,设置POST参数时,如果传入的参数值是@开头,则也会被认为是文件名,并读取该文件,造成文件读取漏洞。

Jenkins权限系统

正常情况下,cli这个功能的权限控制方案和Jenkins默认权限方案相同

Jenkins有几种鉴权方案:

  • Anyone can do anything 没有任何权限认证,匿名用户即可登录后台执行Groovy脚本
  • Legacy Mode 旧鉴权模式
  • Logged-in users can do anything 任意登录的用户可以做任何事,这是默认的权限选项
  • Matrix-based security 细颗粒度权限控制,需要安装插件才支持这个鉴权模式

默认安装后是第3种方案,非常简单,没有垂直权限的区分,登录后的用户就是管理员,没有登录的用户就是匿名用户。

这种权限方案中,管理员可以设置“匿名用户可读”选项:

这个选项在后台的“Manage Jenkins” -> “Security”中管理员可以将其开启或关闭,默认是关闭的。实际测试中,如果我们访问Jenkins首页,发现强制跳转到登录页面,或者啥功能都没有直接报权限错误,就说明关闭了“匿名用户读”选项。

我们不妨测试一下关闭了匿名用户可读功能,那么大部分的cli命令也就无法调用,会出现"ERROR: anonymous is missing the Overall/Read permission"的错误:

但有2个命令例外,就是help和who-am-i。这两个命令是无需任何权限的,所以可以用来读取文件

在Vulhub环境中,“匿名用户可读”是开启的,某些Jenkins版本默认安装时可能也是开启的,但通常管理员会关闭这个功能。另外,大部分企业的Jenkins会安装“Matrix-based security”这样的插件来管理权限,也会影响“匿名用户可读”选项的值。总而言之,这个选项的开关取决于管理员是否想让未登录用户看到一些Jenkins的任务。

总结一下就是:

  • 当Jenkins开启了“匿名用户可读”功能,大部分命令都可以被调用
  • 当Jenkins关闭了“匿名用户可读”功能,只有help和who-am-i命令可以被调用

如何读取想要的内容

前文已经知道了文件读取漏洞的原理,利用jenkins-cli.jar将命令传到服务端解析借助args4j库特性解析参数有@开头的文件

要实现任意文件读取,那么就需要返回文件读取后的内容。利用点是如果调用命令行的时候出错,args4j就会把错误返回给客户端而错误信息中就包含文件的内容。

这里p神提到,如果我们使用@将文件内容加载成命令行参数,那么我们读取文件的时候只能读到文件的前几行

比如使用help命令能读取前两行

使用keep-build命令,可以读取文件第3行

读取几行内容终究是不够,前文提到如果Jenkins开启了“匿名用户可读”选项,则大部分命令都可以被调用,其中包括connect-node命令和reload-job命令。这俩命令可以用来读取文件全部内容

Jenkins敏感文件

如果部署Jenkins是Vulhub的Docker镜像,那么Jenkins的数据根目录是在/var/jenkins_home。但并不是所有人都会使用这个目录作为根目录,如果想读取Jenkins相关的文件,必须先知道Jenkins的根目录在哪里。这时可以读取/proc/self/environ也就是环境变量

拿到了Jenkins的根目录,我们就可以来尝试读取下面这些敏感文件。

  • /var/jenkins_home/users/*/config.xml 保存所有用户的信息,包括密码、种子、Token等
  • /var/jenkins_home/secret.key 保存Remember-Me Cookie中的一部分
  • /var/jenkins_home/secrets/master.key 作为AES解密密钥
  • /var/jenkins_home/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac 作为计算hmac签名时的Key

读取用户密码

1
java -jar jenkins-cli.jar -s http://localhost:8080/ -http reload-job "@/var/jenkins_home/users/users.xml"

得到用户名admin_6382705393240952219

接着读取到用户密码

1
java -jar jenkins-cli.jar -s http://localhost:8080/ -http reload-job "@/var/jenkins_home/users/admin_6382705393240952219/config.xml"

总结

跟着p神复现热门漏洞可以说是非常有收获,c1oudfl0w0师傅说RWCTF2024有道题考的就是这个漏洞,可惜当时没去打hhh