背景:工作中遇到该漏洞,因此尝试复现一下该漏洞
前期工作:需要在vulhub中启动Jenkins/CVE-2024-23897,由于之前装的版本比较早没有该漏洞,需要升级
git clone https://github.com/vulhub/vulhub.git
也就是将之前的vulhub给删掉然后重新下载,这个很容易下载失败,多下几次就行了
漏洞背景介绍
官方背景:https://github.com/vulhub/vulhub/blob/master/jenkins/CVE-2024-23897/README.zh-cn.md
Jenkins是一个开源的自动化服务器。
Jenkins使用args4j来解析命令行输入,并支持通过HTTP、Websocket等协议远程传入命令行参数。args4j中用户可以通过@字符来加载任意文件,这导致攻击者可以通过该特性来读取服务器上的任意文件。
该漏洞影响Jenkins 2.441及以前的版本。
漏洞复现
- 启动服务
docker compose up -d
发现之前有wordpress的服务占了8080端口,在该漏洞的目录下修改docker-compose.yml文件
将映射的端口改为8888
访问成功的页面如下:
2.利用其原理,下载官方提供的命令行客户端,在http://192.168.190.136:8888/jnlpJars/jenkins-cli.jar下载。使用该工具可以读取目标服务器的/proc/self/environ文件——找到Jenkins的基本目录:JENKINS_HOME=/var/jenkins_home
3. 这里涉及到一个小的知识点:Jenkins有4种鉴权方式(以下引用phith0n大佬的文章)
- Anyone can do anything 没有任何权限认证,匿名用户即可登录后台执行Groovy脚本
- Legacy Mode 旧鉴权模式
- Logged-in users can do anything 任意登录的用户可以做任何事,这时默认的权限选项
- Matrix-based security 细颗粒度权限控制,需要安装插件才支持这个鉴权模式
默认是Logged-in users can do anything 这种方式,因此登陆即管理员权限,没有登录即匿名用户,这种权限方案中,管理员可以设置“匿名用户可读”选项。
这个选项在后台的“Manage Jenkins” -> “Security” 中管理员可以将其开启或关闭,默认是关闭的。实际测试中,如果我们访问Jenkins首页,发现强制跳转到登录页面,或者啥功能都没有直接报权限错误,就说明关闭了“匿名用户读”选项。
如果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命令可以被调用
4.直接使用connect-node命令读取完整文件内容
java -jar jenkins-cli.jar -s http://192.168.190.136:8888/ -http connect-node "@/etc/passwd""
默认未使用第三方登录的Jenkins中,用户相关信息是存储在文件中,而Session信息是存储在内存中。所以,在拥有文件读取漏洞后,首先想到的就是是否可以读取用户密码。这里读取/var/jenkins_home/users/users.xml,可以获取用户列表和每个用户信息所在的文件目录:
这里即为admin用户所在的目录,尝试读取这个目录下的config文件:
得到用户密码和用户种子,用户密码使用JBCript哈希编码,是以#jbcrypt前缀开头,但实际上调试可发现这就是一个BCrypt算法计算出来的hash值。我们将这个哈希值前面的#jbcrypt:去掉,并将第一个2a改成2y,就成为一个标准的bcrypt哈希值了。