前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Jenkins文件读取漏洞拾遗(CVE-2024-23897)

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

作者头像
phith0n
发布于 2024-01-28 02:26:57
发布于 2024-01-28 02:26:57
8.2K00
代码可运行
举报
运行总次数:0
代码可运行

Jenkins 未授权文件读取漏洞(CVE-2024-23897)今天闹得沸沸扬扬,我也来简单分析一下这个漏洞,并看看这个文件读取如何利用。

首先说的是,由于Jenkins存在版本和插件差异,所以利用时可能也有不一样之处,本文内容不一定适用于所有Jenkins server。我们这里使用Vulhub的环境(2.441)来做分析和演示:https://github.com/vulhub/vulhub/tree/master/jenkins/CVE-2024-23897

0x01 漏洞原理

漏洞的原理比较简单,本文就不以跟代码记流水帐的形式分析代码了,文字描述一下。

Jenkins提供了一个命令行的接口,用户可以在下载一个命令行客户端jenkins-cli.jar到本地,并调用该客户端来执行一些Jenkins的功能。本来是一个很常见的功能,但设计中神奇的是,用户使用jenkins-cli.jar时,命令行是传到服务端解析的,而不是在jenkins-cli.jar里解析。

这就导致了一个问题,因为Jenkins服务端解析命令行时使用了一个第三方库args4j,这个库实现了Linux中一个常见的功能——如果一个参数是以@开头,则会被自动认为是一个文件名,文件内容会被读取作为参数。

星球里以前讨论过类似的问题,比如curl参数注入中可以利用@来读取和上传文件:https://t.zsxq.com/nAyFuBi

PHP5.5以前,设置POST参数时,如果传入的参数值是@开头,则也会被认为是文件名,并读取该文件,造成文件读取漏洞。在PHP 5.5以后增加了CURLOPT_SAFE_UPLOAD选项并默认为true,用以杜绝这个问题:https://t.zsxq.com/YVbIYny

回到Jenkins,因为Jenkins是在服务端解析的命令行参数,又支持args4j的这个特性,所以造成文件读取漏洞。

要调试该漏洞,只需在Jenkins启动时设置一个环境变量“DEBUG=1”,即可开启JVM的远程调试端口。如果使用Vulhub环境,直接连接5005端口进行远程调试,方法曾在这个帖子里介绍过:https://t.zsxq.com/14N7DfqYr

0x02 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首页,发现强制跳转到登录页面,或者啥功能都没有直接报权限错误,就说明关闭了“匿名用户读”选项。

如果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命令可以被调用

0x03 如何读取想要的内容

前面说了,Jenkins文件读取漏洞的原理是args4j在解析命令行的时候会把@后面的字符作为文件名,并读取文件内容作为参数的值。

但是作为攻击者,我们必须想办法让Jenkins或args4j,将读到的文件内容返回给我们,才能最终达到任意文件读取的目的。好在,当我们调用命令行时,如果出错,args4j就会把错误返回给客户端,而错误信息中就包含文件的内容。

但这里有个问题是,如果我们使用@将文件内容加载成命令行参数,则会遇到一个棘手的问题——文件中的空白字符,会分割参数。比如,如果有一个文件内容有4行:

代码语言:javascript
代码运行次数:0
运行
复制
1
2
3
4

那么,命令行解析时会变成下面这个样子:

代码语言:javascript
代码运行次数:0
运行
复制
java -jar jenkins-cli.jar -s http://localhost:8080/ -http help 1 2 3 4

此时,1、2、3、4会变成help命令的4个参数。而解析命令行时通常只会取前面一些参数,报错也就只会把这些参数报出来,导致我们读取文件的时候只能读到文件的前几行。

比如,使用help命令,能读到文件的前2行:

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

但此时会有一个有趣的问题:如果一个文件只有一行(如/var/jenkins_home/secret.key 和 /var/jenkins_home/secrets/master.key),使用help读取就会出现“ERROR: You must authenticate to access this Jenkins.”的错误:

前面不是说调用help命令可以不需要权限吗?实际上,help命令会先检查命令的参数个数是否正确,后再检查权限,如果我们能让检查命令参数个数的步骤就出错,就能正常返回错误信息了。

所以,可以人为地给help命令后增加一个新参数,比如:

代码语言:javascript
代码运行次数:0
运行
复制
java -jar jenkins-cli.jar -s http://localhost:8080/ -http help 1 "@/var/jenkins_home/secret.key"

此时help后有两个参数,参数个数太多导致出错,第二个参数被爆出,就是我们要读的文件内容:

读一两行这种做法终究比较鸡肋,是否有命令可以读取完整文件内容呢?

其实,前面我也说了,如果Jenkins开启了“匿名用户可读”选项,则大部分命令都可以被调用,其中包括connect-node命令和reload-job命令。这俩命令可以用来读取文件全部内容:

0x04 了解Jenkins敏感文件

知道了如何读取文件,那么我们在实战中应该读取哪些文件呢?

如果部署Jenkins使用的是官方或Vulhub的Docker镜像,那么Jenkins的数据根目录是在/var/jenkins_home。但并不是所有人都会使用这个目录作为根目录,如果像读取Jenkins相关的文件,必须先知道Jenkins的根目录在哪里。

这时可以读取/proc/self/environ和/proc/self/cmdline,这两个文件中包含的是当前进程的环境变量和cmd启动命令行,其中就会包含Jenkins的根目录。

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

  • /var/jenkins_home/users/*/config.xml
  • /var/jenkins_home/secret.key
  • /var/jenkins_home/secrets/master.key
  • /var/jenkins_home/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac

在后面对代码的分析中,我们能慢慢地了解这些文件的具体作用。

0x05 读取用户密码

默认未使用第三方登录的Jenkins中,用户相关信息是存储在文件中,而Session信息是存储在内存中。所以,在拥有文件读取漏洞后,首先想到的就是是否可以读取用户密码。

我们先读取/var/jenkins_home/users/users.xml,可以获取用户列表和每个用户信息所在的文件目录:

我画红框的就是admin用户所在目录,我们读取这个目录下的config文件:/var/jenkins_home/users/admin_2676914209327834400/config.xml

可见,我们拿到了三个重要信息:

  • 用户密码,使用JBCript哈希编码
  • 用户Token,使用sha256哈希编码
  • 用户种子,这个后面会用到

第一个,用户密码是以#jbcrypt前缀开头,但实际上调试可发现这就是一个BCrypt算法计算出来的hash值。我们将这个哈希值前面的#jbcrypt:去掉,并将第一个2a改成2y,就成为一个标准的bcrypt哈希值了。

由于我们已知管理员的密码是字符串“vulhub”,我们计算一下它是否能对应上这个bcrypt哈希值:

能够对应上,说明算法是bcrypt。对于这类hash值,我们只能硬跑破解,运气好可以跑出来明文。

第二个,用户Token。这个值并不是每个用户都有,通常只有用户生成了Token才会有。而且储存在文件中的Token是原始Token经过sha256后的结果,无法还原出原始Token,所以利用不了。

第三个,用户种子,这个值在Remember-Me Cookie中会用到。

0x06 Remember-Me Cookie是怎么工作的?

那么,说到Remember-Me Cookie,Jenkins的Remember-Me Cookie是怎么工作的呢?

remember-me Cookie的生成与校验是在hudson.security.TokenBasedRememberMeServices2#makeTokenSignature函数中,这个函数代码很简单:

可以看见,由用户名、Token过期时间戳、userSeed、Key四个部分拼接组成的字符串,被使用Mac.mac函数签名以后,成为最后的Token。

这里就带来几个问题:

  • userSeed是什么?
  • Key是什么?
  • Mac.mac函数是什么算法?

我们在函数尾下断点,可以发现Key就是/var/jenkins_home/secret.key的内容:

这里的userSeed是前面读取的用户种子,Key是前面读取的secret.key文件的值,这两个值都可以通过漏洞读取到。

跟进Mac.mac函数后可以发现,最后实际上是使用了javax.crypto.Mac来计算hmac,hmac算法使用的salt来自于下面这个函数:

可见,这里首先从/var/jenkins_home/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac文件中读取出一个密文,并使用AES解密,解密时使用的密钥来自于masterKey

这个masterKey的名字好像比较熟悉?确实就和前面读取的/var/jenkins_home/secrets/master.key有关。master.key文件的内容,使用Util.toAes128Key转换成适合AES128算法长度的Key,就是AES密钥:

所以,最后所有的敏感文件作用都屡清楚了:

  • /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

这里面,前三个文件都可以直接读取,但读取第四个文件时我遇到了问题。

0x07 二进制文件读取问题

第四个文件是一个二进制文件,我们对文件读取的数据包抓包,可以拿到最原始的返回数据:

可见,这个返回数据里有大量的ef bf bd,这就是UTF-8字符集无法识别时的“占位符”。我曾在星球里分享过Burpsuite发包时遇到过类似问题:https://t.zsxq.com/NzfuJ2r,可以复习一下。

也就是说,读取二进制文件时会因为非UTF-8字符集的问题导致有大量字符被“占位符”替代,无法读到完整的hmac salt。

官方漏洞通告里也提到了这个问题:

For example, attempting to read random binary data using UTF-8, roughly half of all bytes will be replaced with a placeholder for an illegal value. For 32 byte random binary secrets, as commonly used in Jenkins for HMAC-SHA256, this would require attackers to correctly guess on average 16 bytes, which is infeasible. In contrast, with the encoding Windows-1252, only 5 out of 256 possible values are illegal and would be replaced with a placeholder.

在UTF-8字符集情况下,32字节长度的二进制字符可能有16个字节都是占位符;而如果是Windows-1252字符集,则256个字符中只有5个字符是占位符。

而正常来说,Linux系统下部署的Jenkins都是默认的UTF-8字符集,而部分Windows下部署的Jenkins可能会是其他字符集。如果按照16:32这个比例来看,当前环境是根本无法正确读到二进制文件的。

那么,是否有办法在客户端设置字符集呢?

我在抓cli请求包的时候,关注到协议中是存在一个字符集的设置的:

阅读代码可以发现,这个字符集可以通过Java客户端的file.encoding来配置。我尝试将其设置为UTF-16BE:

代码语言:javascript
代码运行次数:0
运行
复制
java -Dfile.encoding=UTF-16BE -jar jenkins-cli.jar -s http://localhost:8080/ -http who-am-i "@/var/jenkins_home/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac"

此时再抓包查看返回

可以发现,返回的错误信息确实变成UTF-16编码了,但其中仍然包含大量fd ff这样的占位符,并不能实现读取二进制文件内容的目标。

我尝试了Java中其他的编码,都是相同的问题。我们看下args4j中解析@符号的代码,可以发现其使用的是new BufferedReader(new FileReader(f))来读取文件:

查看FileReader函数的文档可以看出,如果其构造函数不传入第二个参数,会使用默认的charset打开文件。而默认charset就是当前服务端的file.encoding设置。因为这部分代码在args4j中,在读取文件的时候就已经使用UTF-8编码,导致二进制信息的丢失,后续客户端传入的charset是什么都不会影响返回结果中的占位符了。

那么实际上伪造remember-me这条路就死了,就像官方漏洞通告里说的,目标环境需要支持读取二进制文件(比如默认字符集是Windows-1252的Windows系统)。

0x08 总结

分析了这么多,大概核心的内容都已经说明了。总结一下,CVE-2024-23897漏洞的利用有下面两个比较核心的限制:

  • 是否开启“匿名用户可读”选项
  • 服务端字符集是否兼容读取二进制文件

第一个问题的结果会影响攻击者是否能够读取文件的全文,包括用户的密码等信息;第二个问题的结果影响攻击者是否能够伪造任意用户的remember-me Cookie。

当然,还是最开始说的,本文仅限于Vulhub环境中的Jenkins版本(2.441)。其他环境的Jenkins的相关细节会有许多不同,比如,旧版本Jenkins用户密码是加密而不是哈希,可以利用诸如jenkins-decrypt这样的工具来解密密码,还可以利用一些插件来进一步攻击。这部分细节就留给大家自行深入研究了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
TO GOOD TO GO筹集3100万美元对抗食物浪费
TO GOOD TO GO,这家让你在食物浪费之前购买食物的初创公司正在筹集3110万美元的资金;blisce正在领导这轮融资,并投资1540万美元。现有投资者和员工也参与其中。虽然这家公司已经存在了一段时间,但这是第一次从风投公司融资。
用户8054111
2021/01/14
9110
美悬赏1500万美元寻勒索软件团伙Conti 的关键人物信息
据Bleeping Computer网站5月7日消息,为了能帮助识别和定位臭名昭著的勒索软件团伙 Conti 的主要核心人员及同谋,美国国务院开出了1500 万美元的高额赏金。
FB客服
2022/06/08
2340
美悬赏1500万美元寻勒索软件团伙Conti 的关键人物信息
物种功能,多样性分解及功能多样性
Ecol. Lett. | 普莱斯方程的生态学应用:解析群落组成变动对生态系统功能的影响
Listenlii-生物信息知识分享
2020/07/14
3.7K1
物种功能,多样性分解及功能多样性
【史上最全】计算机的编年史
前几天我写算力简史的时候,顺便整理了一份计算机技术的编年史(将近一万字)。今天发给大家,以供参考。
鲜枣课堂
2023/08/21
1.2K0
【史上最全】计算机的编年史
跨境电子商务税收合规平台Taxdoo筹集了2100万美元的A轮融资
Taxdoo是一家针对跨境电子商务公司构建了所谓的“财务合规自动化平台”的创业公司,已筹集了2100万美元的新资金。
甜甜圈
2020/12/18
8580
AI日报|跃问App上架加入AI助理竞争!GPTZero获千万美元A轮融资,创始人不到30岁!
AI日报|Luma推出AI视频模型,又一Sora级选手登场?SD3 Medium发布,图中文效果改善明显
可信AI进展
2024/06/17
3060
沃森和特朗普:一家伟大美国企业的兴与衰
---- 新智元编译 来源:cacm.acm.org 作者:Thomas Haigh 编译:Shawn、May 【新智元导读】Thomas Haigh是威斯康星大学密尔沃基分校历史系副教授,主要关注信息技术史以及商业史。最近,经常有关于美国之伟大、美国为何不再伟大以及如何让美国再次伟大的讨论,但是伟大这件事十分复杂,我们对伟大的定义已经随着时间发生了改变。在本文中,Thomas Haigh将从IBM的历史中寻找答案,探讨这家伟大的美国企业的兴与衰。 数十年以来,IBM一直都是世界上最大、最赚钱、最受
新智元
2018/05/29
7370
历史上最伟大的12位程序员
所谓程序员,是指那些能够创造、编写计算机程序的人。不论一个人是什么样的程序员,或多或少,他都在为我们这个社会贡献着什么东西。然而,有些程序员的贡献却超过了一个普通人一辈子能奉献的力量。这些程序员是先驱
程序员互动联盟
2018/03/13
1.9K0
历史上最伟大的12位程序员
最新!全球顶级对冲基金持仓公布,文艺复兴规模超1600亿美元
公众号根据全球各地对冲基金公司向美国证监会(SEC)提交了其13F报告。对其持仓做了全面的分析。所有数据都是根据最新编写。希望大家有所收获!
量化投资与机器学习微信公众号
2020/09/03
2.1K0
最新!全球顶级对冲基金持仓公布,文艺复兴规模超1600亿美元
本周(6.14-6.30)FF首轮融资终落地 | 投融资汇总
本周硬科技领域投融资事件一共51起,人工智能领域发生25起融资事件,占比49%;区块链领域发生13起融资事件,占比25%;物联网领域发生4起融资事件,占比8%;3R(VR/AR/MR)和生物医疗领域分别发生3起融资事件,分别占比6%;新能源领域发生2起融资事件,占比4%;光电芯片发生1起融资事件,占比2%。
镁客网
2018/07/31
6440
本周(6.14-6.30)FF首轮融资终落地 | 投融资汇总
Midjourney|文心一格prompt教程[技巧篇]:生成多样性、增加艺术风格、图片二次修改、渐进优化、权重、灯光设置等17个技巧等你来学
我认为学习图片类的 prompt,跟学习画画是类似的,最好的学习方法不是直接用模板。
汀丶人工智能
2023/05/19
1.1K0
Midjourney|文心一格prompt教程[技巧篇]:生成多样性、增加艺术风格、图片二次修改、渐进优化、权重、灯光设置等17个技巧等你来学
法拉第未来任命临时CFO,并宣布已收到5500万美元融资 |镁客网每周硬科技领域投融资汇总(10.22-10.28)
Faraday Future将从下个月起将所有员工的薪水削减25%,以保存现金,当前这家初创公司正在为推出首款电动汽车筹措新资金。
镁客网
2023/01/04
7320
法拉第未来任命临时CFO,并宣布已收到5500万美元融资 |镁客网每周硬科技领域投融资汇总(10.22-10.28)
世界算力简史(上)
1946年2月14日,在美国宾夕法尼亚州东南部的费城,人们正在像以往一样正常工作和生活。
鲜枣课堂
2023/08/21
4030
世界算力简史(上)
J. Chem. Inf. Model.|局部骨架多样性增强的分子生成模型用于开发NLRP3抑制剂
今天为大家介绍的是成都赜灵生物医药科技有限公司/四川大学华西医院生物治疗全国重点实验室陈俐娟教授团队在Journal of Chemical Information and Modeling上发表的文章Local Scaffold Diversity-Contributed Generator for Discovering Potential NLRP3 Inhibitors。成都赜灵生物医药科技有限公司成立于2019年,是一家专门从事创新药物研究及产业化的生物医药科技公司,构建了完整的新药研发体系,自主研发能力覆盖创新药物的靶点研究与机理验证、人工智能分子设计、临床前评价、CMC研究、临床方案设计与执行、新药注册等各个环节,打造了具有特色的创新药物发现平台。目前公司已获得5张临床试验批件,其中获美国FDA临床试验批件1张。成都赜灵建立了差异化并具有市场竞争力的丰富研发管线:1、治疗血液系统淋巴瘤化药Ⅰ类新药注射用甲磺酸普依司他;2、治疗骨髓纤维化Ⅰ类新药马来酸氟诺替尼;3、治疗自身免疫性疾病炎症性肠病(IBD)和类风湿关节炎(RA)的选择性JAK3小分子抑制剂药物ZL-82。公司核心品种甲磺酸普依司他和马来酸氟诺替尼在临床上已初步显示出良好的临床疗效,具有成为Best-in-Class和First-in-Class药物的潜力。
DrugAI
2024/01/25
2510
J. Chem. Inf. Model.|局部骨架多样性增强的分子生成模型用于开发NLRP3抑制剂
跨年AI应用指南:有人获30万美元年薪新工作,GPTs可能彻底改变人类社会
奈飞在1999年推出DVD邮件订阅服务后,用了三年半的时间才拥有了100万用户;Airbnb用了两年半的时间吸引了100万用户;Facebook用了10个月时间取得这样的成绩;音乐流媒体服务Spotify只用了5个月就达到了这个受众规模,而Instagram在2010年用不到3个月的时间吸引到100万用户。
小腾资讯君
2024/01/23
1620
跨年AI应用指南:有人获30万美元年薪新工作,GPTs可能彻底改变人类社会
算力简史(完整版)
引言:今天这篇文章,我将给大家详细介绍一下人类算力的演进过程。这是一段波澜壮阔的历史,值得我们驻足与回忆。
鲜枣课堂
2023/11/17
6110
算力简史(完整版)
2021年资产管理与托管银行行业发展研究报告
资产管理与托管银行是主要从事投资管理和与其相关的有偿托管和证券业务。包括经营共同基金和封闭式基金的公司以及单位信托公司。不包括那些主要从事商业贷款、投资银行业、经纪业和其它特殊金融业务的银行和金融机构。
资产信息网
2022/04/22
8420
2021年资产管理与托管银行行业发展研究报告
Docker中容器的随机命名方式
使用 docker 创建容器时,如果没有用 --name 指定,docker 会为用户选择一个名称, 格式是两个带有下划线的单词,如xxx_yyyy
fliter
2023/09/05
4910
Docker中容器的随机命名方式
宾大苏炜杰:从「匮乏」走向「丰富」
初识苏炜杰,他与许多青年学者一样,外表温文尔雅、略带腼腆,但一谈起学术和 AI 的未来发展,就充满激情。 看他的简历,成长经历一帆风顺:本科就读于富有盛誉的北京大学数学科学学院,接着在美国斯坦福大学攻读博士,师从美国国家科学院院士、麦克阿瑟天才奖得主 Emmanuel Candès 和美国国家科学院和工程院双院院士 Cynthia Dwork。紧接着跳过博士后阶段,执教于培养了埃隆·马斯克和沃伦·巴菲特的沃顿商学院,并联合指导常青藤名校宾夕法尼亚大学在机器学习领域的发展。 他的团队在机器学习优化算法、可信
AI科技评论
2022/03/29
4620
机器学习学术速递[9.6]
【1】 Computing Graph Descriptors on Edge Streams 标题:基于边缘流的图描述子计算 链接:https://arxiv.org/abs/2109.01494
公众号-arXiv每日学术速递
2021/09/16
1.1K0
推荐阅读
相关推荐
TO GOOD TO GO筹集3100万美元对抗食物浪费
更多 >
目录
  • 0x01 漏洞原理
  • 0x02 Jenkins权限系统
  • 0x03 如何读取想要的内容
  • 0x04 了解Jenkins敏感文件
  • 0x05 读取用户密码
  • 0x06 Remember-Me Cookie是怎么工作的?
  • 0x07 二进制文件读取问题
  • 0x08 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档