malware analysis

Reverse Engineering Ransomware Encryption Routine

Reverse engineer ransomware encryption routines to identify cryptographic algorithms, key generation flaws, and potential decryption opportunities using static and dynamic analysis.

aescryptanalysisdecryptionencryptionmalware-analysisransomwarereverse-engineeringrsa
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Modern ransomware uses hybrid encryption combining symmetric algorithms (AES-256-CBC/CTR, ChaCha20, Salsa20) for file encryption with asymmetric algorithms (RSA-2048/4096, Curve25519) for key protection. The encryption routine typically generates a random symmetric key per file, encrypts file contents, then encrypts the symmetric key with the attacker's embedded public key. Reverse engineering these routines identifies the specific algorithms, key derivation methods, initialization vectors, file targeting patterns, and potential implementation flaws that could enable decryption without paying the ransom. Notable examples include Rhysida (AES-256-CTR + RSA-4096), Qilin.B (AES-256-CTR with AES-NI or ChaCha20 fallback), and Medusa (AES-256 + RSA).

When to Use

  • When performing authorized security testing that involves reverse engineering ransomware encryption routine
  • When analyzing malware samples or attack artifacts in a controlled environment
  • When conducting red team exercises or penetration testing engagements
  • When building detection capabilities based on offensive technique understanding

Prerequisites

  • IDA Pro or Ghidra for static disassembly
  • x64dbg/WinDbg for dynamic debugging
  • Python 3.9+ with pycryptodome, pefile
  • Understanding of AES, RSA, ChaCha20, Curve25519 algorithms
  • Knowledge of Windows CryptoAPI and CNG (BCrypt) functions
  • Sandbox environment for safe execution

Key Concepts

Hybrid Encryption Model

Ransomware generates a unique AES key and IV for each file. The file content is encrypted with this symmetric key. The symmetric key is then encrypted with the attacker's RSA public key (embedded in the binary or fetched from C2). The encrypted key is appended or prepended to the encrypted file. Only the attacker holding the RSA private key can decrypt the per-file symmetric keys.

Cryptographic API Identification

Windows ransomware typically uses CryptoAPI (CryptAcquireContext, CryptGenKey, CryptEncrypt) or CNG (BCryptGenerateSymmetricKey, BCryptEncrypt). Some use OpenSSL or custom implementations. Identifying these API calls provides immediate insight into the algorithm, key size, and mode of operation.

Implementation Flaws

Decryption opportunities arise from: hardcoded encryption keys, weak PRNG for key generation (using GetTickCount or time() as seed), reuse of IVs across files, ECB mode usage, keys remaining in memory post-encryption, and race conditions where keys can be captured during encryption.

Workflow

Step 1: Identify Cryptographic Functions

#!/usr/bin/env python3
"""Identify cryptographic functions in ransomware PE files."""
import pefile
import sys
 
CRYPTO_APIS = {
    # Windows CryptoAPI
    "CryptAcquireContextA": "CryptoAPI context acquisition",
    "CryptAcquireContextW": "CryptoAPI context acquisition",
    "CryptGenKey": "Key generation",
    "CryptDeriveKey": "Key derivation",
    "CryptEncrypt": "Encryption operation",
    "CryptDecrypt": "Decryption operation",
    "CryptImportKey": "Key import (public key?)",
    "CryptExportKey": "Key export",
    "CryptGenRandom": "Random number generation",
    "CryptCreateHash": "Hash creation",
    "CryptHashData": "Hashing operation",
    # Windows CNG (BCrypt)
    "BCryptOpenAlgorithmProvider": "CNG algorithm initialization",
    "BCryptGenerateSymmetricKey": "CNG symmetric key generation",
    "BCryptEncrypt": "CNG encryption",
    "BCryptDecrypt": "CNG decryption",
    "BCryptGenerateKeyPair": "CNG key pair generation",
    "BCryptImportKeyPair": "CNG key import",
    # OpenSSL
    "EVP_EncryptInit_ex": "OpenSSL encrypt init",
    "EVP_EncryptUpdate": "OpenSSL encrypt update",
    "EVP_EncryptFinal_ex": "OpenSSL encrypt final",
    "RSA_public_encrypt": "OpenSSL RSA encryption",
    "AES_set_encrypt_key": "OpenSSL AES key setup",
    # File operations
    "CreateFileW": "File open (target files)",
    "ReadFile": "File read (before encryption)",
    "WriteFile": "File write (after encryption)",
    "FindFirstFileW": "File enumeration (targeting)",
    "FindNextFileW": "File enumeration",
    "MoveFileW": "File rename (extension change)",
    "DeleteFileW": "File deletion (originals)",
}
 
AES_SBOX = bytes([
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
])
 
CHACHA20_CONSTANT = b"expand 32-byte k"
 
 
def analyze_imports(filepath):
    """Analyze PE imports for cryptographic APIs."""
    try:
        pe = pefile.PE(filepath)
    except pefile.PEFormatError:
        print("[-] Not a valid PE file")
        return
 
    print("[+] Cryptographic API Analysis")
    print("=" * 60)
 
    crypto_imports = []
    if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
        for entry in pe.DIRECTORY_ENTRY_IMPORT:
            dll = entry.dll.decode('utf-8', errors='replace')
            for imp in entry.imports:
                if imp.name:
                    name = imp.name.decode('utf-8', errors='replace')
                    if name in CRYPTO_APIS:
                        desc = CRYPTO_APIS[name]
                        crypto_imports.append((dll, name, desc))
                        print(f"  [{dll}] {name}: {desc}")
 
    if not crypto_imports:
        print("  No known crypto APIs found in imports")
        print("  Malware may use custom implementation or dynamic loading")
 
    return crypto_imports
 
 
def find_crypto_constants(filepath):
    """Search for embedded cryptographic constants."""
    with open(filepath, 'rb') as f:
        data = f.read()
 
    print("\n[+] Cryptographic Constants Search")
    print("=" * 60)
 
    # AES S-Box
    offset = data.find(AES_SBOX)
    if offset != -1:
        print(f"  AES S-Box found at offset 0x{offset:x}")
 
    # ChaCha20/Salsa20 constant
    offset = data.find(CHACHA20_CONSTANT)
    if offset != -1:
        print(f"  ChaCha20 constant at offset 0x{offset:x}")
 
    # RSA public key markers
    rsa_markers = [
        b'-----BEGIN PUBLIC KEY-----',
        b'-----BEGIN RSA PUBLIC KEY-----',
        b'\x30\x82',  # ASN.1 SEQUENCE
    ]
    for marker in rsa_markers:
        offset = data.find(marker)
        if offset != -1:
            print(f"  RSA key marker at offset 0x{offset:x}")
 
    # Common ransomware file extension patterns
    import re
    ext_pattern = re.compile(rb'\.\w{3,10}(?=\x00)', re.IGNORECASE)
    extensions = set()
    for match in ext_pattern.finditer(data):
        ext = match.group().decode('ascii', errors='replace').lower()
        target_exts = [
            '.doc', '.docx', '.xls', '.xlsx', '.pdf', '.ppt',
            '.jpg', '.png', '.sql', '.mdb', '.bak', '.zip',
        ]
        if ext in target_exts:
            extensions.add(ext)
 
    if extensions:
        print(f"\n  Target file extensions: {', '.join(sorted(extensions))}")
 
 
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <ransomware_sample>")
        sys.exit(1)
 
    analyze_imports(sys.argv[1])
    find_crypto_constants(sys.argv[1])

Step 2: Analyze Encryption Flow

def analyze_encryption_pattern(filepath):
    """Analyze file encryption patterns from ransomware artifacts."""
    import os
    import struct
 
    with open(filepath, 'rb') as f:
        data = f.read()
 
    file_size = len(data)
    print(f"\n[+] Encrypted File Analysis: {filepath}")
    print(f"  Size: {file_size:,} bytes")
 
    # Check for appended key material (common pattern)
    # Many ransomware families append encrypted key at end of file
    tail_sizes = [256, 512, 1024, 2048]  # Common RSA ciphertext sizes
    for size in tail_sizes:
        if file_size > size + 16:
            tail = data[-size:]
            # High entropy suggests encrypted data
            entropy = calculate_entropy(tail)
            if entropy > 7.5:
                print(f"  Possible encrypted key ({size} bytes) "
                      f"at end of file (entropy: {entropy:.2f})")
 
    # Check for header modifications
    # Many ransomware prepend metadata
    header = data[:64]
    print(f"  First 16 bytes: {header[:16].hex()}")
 
    # Check if original file header is preserved
    known_headers = {
        b'PK': 'ZIP/Office',
        b'\x89PNG': 'PNG',
        b'\xff\xd8\xff': 'JPEG',
        b'%PDF': 'PDF',
        b'\xd0\xcf\x11\xe0': 'OLE (DOC/XLS)',
    }
    for magic, ftype in known_headers.items():
        if header.startswith(magic):
            print(f"  Original format preserved: {ftype}")
            break
    else:
        print("  Original header destroyed/encrypted")
 
 
def calculate_entropy(data):
    """Calculate Shannon entropy of data."""
    from collections import Counter
    import math
 
    if not data:
        return 0
 
    freq = Counter(data)
    length = len(data)
    entropy = -sum(
        (count / length) * math.log2(count / length)
        for count in freq.values()
    )
    return entropy

Validation Criteria

  • Cryptographic algorithms identified (AES, RSA, ChaCha20, etc.)
  • Key size and mode of operation determined
  • Key generation method analyzed for potential weaknesses
  • Per-file key encryption scheme documented
  • File targeting patterns and extension list extracted
  • Embedded public keys extracted for infrastructure correlation
  • Potential decryption opportunities assessed

References

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.9 KB

API Reference: Reverse Engineering Ransomware Encryption

Cryptographic Algorithm Constants

Algorithm Signature Description
AES S-Box starting 0x63 0x7C 0x77 AES Rijndael substitution box
RSA DER 0x30 0x82 prefix ASN.1 RSA key structure
ChaCha20/Salsa20 expand 32-byte k Stream cipher constant
RC4 Sequential 0-255 state Key scheduling algorithm init

Encryption Analysis Techniques

Technique Tool Purpose
Entropy analysis ent, Python Detect encrypted regions
Constant scanning IDA/Ghidra YARA Find crypto implementations
API tracing x64dbg, Frida Trace CryptEncrypt/BCrypt calls
Key extraction Volatility3 Dump keys from memory

Ransomware Encryption Patterns

Pattern Indicator
Full encryption Entropy > 7.9 across entire file
Intermittent High entropy blocks with gaps
Header-only First N bytes encrypted, rest plain
Appended metadata File larger than original (key/IV at end)

Common Ransomware Crypto

Family Algorithm Key Mgmt
LockBit 3.0 AES-256-CBC + RSA-2048 Per-file AES key, RSA-encrypted
BlackCat/ALPHV ChaCha20 + RSA-4096 Rust implementation
Royal AES-256-CBC + RSA-2048 Intermittent encryption
Akira ChaCha20 Partial file encryption

Python Libraries

Library Version Purpose
hashlib stdlib SHA256 hashing
struct stdlib Binary data parsing
re stdlib Pattern extraction
math stdlib Shannon entropy calculation

References

standards.md1.1 KB

Ransomware Encryption Standards Reference

Common Encryption Schemes by Family

Family Symmetric Asymmetric Key Size
Rhysida AES-256-CTR RSA-4096 256-bit
Qilin.B AES-256-CTR/ChaCha20 RSA-4096 OAEP 256-bit
Medusa AES-256 RSA public key 256-bit
LockBit 3.0 AES-256-CTR Curve25519 256-bit
BlackCat/ALPHV AES-128/ChaCha20 RSA-2048 128/256-bit
Conti ChaCha20 RSA-4096 256-bit

Windows Cryptographic API Cheat Sheet

Function Purpose
CryptAcquireContext Acquire crypto provider handle
CryptGenKey Generate symmetric/asymmetric key
CryptImportKey Import key blob
BCryptOpenAlgorithmProvider Open CNG algorithm
BCryptGenerateSymmetricKey Create symmetric key

MITRE ATT&CK Techniques

  • T1486: Data Encrypted for Impact
  • T1490: Inhibit System Recovery
  • T1083: File and Directory Discovery
  • T1082: System Information Discovery

References

workflows.md1.7 KB

Ransomware Encryption Analysis Workflows

Workflow 1: Encryption Routine Identification

[Ransomware Sample] --> [Import Analysis] --> [Find Crypto APIs]
                                                    |
                                                    v
                                           [Identify Algorithm]
                                                    |
                                                    v
                                           [Trace Key Generation]
                                                    |
                                                    v
                                           [Assess Decryption Feasibility]

Workflow 2: Key Recovery Assessment

[Encrypted Files] --> [Analyze File Structure] --> [Locate Encrypted Key]
                                                          |
                                                          v
                                                 [Check for PRNG Weaknesses]
                                                          |
                                                          v
                                                 [Attempt Key Recovery]

Workflow 3: Decryptor Development

[Identified Flaw] --> [Extract Parameters] --> [Build Decryption Logic]
                                                        |
                                                        v
                                               [Test on Sample Files]
                                                        |
                                                        v
                                               [Release Decryptor Tool]

Scripts 2

agent.py6.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for reverse engineering ransomware encryption routines.

Identifies encryption algorithms, extracts key material from
memory dumps or binary analysis, detects IV/nonce patterns,
and documents the cryptographic implementation for decryptor
development.
"""

import json
import sys
import re
import struct
import hashlib
from pathlib import Path
from datetime import datetime


CRYPTO_CONSTANTS = {
    "AES S-Box": bytes([0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5]),
    "AES Inv S-Box": bytes([0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38]),
    "RSA Marker": b"\x30\x82",
    "ChaCha20 Constant": b"expand 32-byte k",
    "Salsa20 Constant": b"expand 32-byte k",
    "RC4 State Init": bytes(range(8)),
    "SHA256 Init H0": struct.pack(">I", 0x6a09e667),
}

RANSOMWARE_PATTERNS = {
    "file_extension_change": re.compile(rb'\.\w{3,10}(?=\x00)'),
    "ransom_note_name": re.compile(rb'(?:README|RECOVER|DECRYPT|HOW.TO)[\w.-]*\.(?:txt|html|hta)', re.I),
    "bitcoin_address": re.compile(rb'[13][a-km-zA-HJ-NP-Z1-9]{25,34}'),
    "onion_url": re.compile(rb'[\w]{16,56}\.onion'),
    "email_address": re.compile(rb'[\w.+-]+@[\w-]+\.[\w.]{2,}'),
}


class RansomwareREAgent:
    """Analyzes ransomware encryption implementation."""

    def __init__(self, sample_path, output_dir="./ransomware_re"):
        self.sample_path = Path(sample_path)
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(parents=True, exist_ok=True)
        self.findings = []

    def identify_crypto_algorithms(self):
        """Scan binary for cryptographic algorithm constants."""
        data = self.sample_path.read_bytes()
        detected = []

        for name, constant in CRYPTO_CONSTANTS.items():
            offset = data.find(constant)
            if offset != -1:
                detected.append({
                    "algorithm": name,
                    "offset": hex(offset),
                    "context": data[max(0, offset - 16):offset + len(constant) + 16].hex(),
                })
                self.findings.append({
                    "type": "Crypto Algorithm Detected",
                    "algorithm": name, "offset": hex(offset),
                })
        return detected

    def extract_encryption_indicators(self):
        """Extract ransomware-specific indicators from the binary."""
        data = self.sample_path.read_bytes()
        indicators = {}

        for name, pattern in RANSOMWARE_PATTERNS.items():
            matches = pattern.findall(data)
            if matches:
                decoded = []
                for m in matches[:10]:
                    try:
                        decoded.append(m.decode("utf-8", errors="ignore"))
                    except (UnicodeDecodeError, AttributeError):
                        decoded.append(m.hex())
                indicators[name] = decoded

        return indicators

    def analyze_encrypted_file(self, encrypted_path, original_path=None):
        """Analyze an encrypted file to determine encryption characteristics."""
        enc_data = Path(encrypted_path).read_bytes()
        analysis = {
            "file_size": len(enc_data),
            "entropy": self._calculate_entropy(enc_data),
            "header_bytes": enc_data[:64].hex(),
            "footer_bytes": enc_data[-64:].hex() if len(enc_data) > 64 else "",
        }

        if analysis["entropy"] > 7.9:
            analysis["encryption_type"] = "Full file encryption"
        elif analysis["entropy"] > 6.0:
            analysis["encryption_type"] = "Partial/intermittent encryption"
        else:
            analysis["encryption_type"] = "Possibly not encrypted or header-only"

        if original_path and Path(original_path).exists():
            orig_data = Path(original_path).read_bytes()
            analysis["size_difference"] = len(enc_data) - len(orig_data)
            if analysis["size_difference"] > 0:
                analysis["appended_bytes"] = analysis["size_difference"]
                analysis["footer_metadata"] = enc_data[len(orig_data):len(orig_data) + 128].hex()

        return analysis

    def _calculate_entropy(self, data):
        """Calculate Shannon entropy of data."""
        if not data:
            return 0.0
        import math
        freq = [0] * 256
        for byte in data:
            freq[byte] += 1
        length = len(data)
        entropy = 0.0
        for count in freq:
            if count > 0:
                p = count / length
                entropy -= p * math.log2(p)
        return round(entropy, 4)

    def extract_key_material(self, memory_dump_path=None):
        """Search for potential encryption key material."""
        search_data = (Path(memory_dump_path).read_bytes()
                       if memory_dump_path else self.sample_path.read_bytes())
        potential_keys = []

        for offset in range(0, min(len(search_data), 10_000_000), 16):
            block = search_data[offset:offset + 32]
            if len(block) < 16:
                break
            entropy = self._calculate_entropy(block)
            if entropy > 4.5 and all(b != 0 for b in block[:16]):
                if not all(b == block[0] for b in block[:16]):
                    potential_keys.append({
                        "offset": hex(offset),
                        "length": len(block),
                        "entropy": entropy,
                        "sha256": hashlib.sha256(block).hexdigest()[:16],
                    })
            if len(potential_keys) >= 50:
                break

        return potential_keys[:20]

    def generate_report(self):
        crypto = self.identify_crypto_algorithms()
        indicators = self.extract_encryption_indicators()
        sha256 = hashlib.sha256(self.sample_path.read_bytes()).hexdigest()

        report = {
            "sample": str(self.sample_path),
            "sha256": sha256,
            "report_date": datetime.utcnow().isoformat(),
            "crypto_algorithms": crypto,
            "ransomware_indicators": indicators,
            "findings": self.findings,
        }
        report_path = self.output_dir / "ransomware_re_report.json"
        with open(report_path, "w") as f:
            json.dump(report, f, indent=2)
        print(json.dumps(report, indent=2))
        return report


def main():
    if len(sys.argv) < 2:
        print("Usage: agent.py <sample_path> [encrypted_file] [original_file]")
        sys.exit(1)
    agent = RansomwareREAgent(sys.argv[1])
    agent.generate_report()
    if len(sys.argv) > 2:
        orig = sys.argv[3] if len(sys.argv) > 3 else None
        analysis = agent.analyze_encrypted_file(sys.argv[2], orig)
        print(json.dumps(analysis, indent=2))


if __name__ == "__main__":
    main()
process.py5.4 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Ransomware Encryption Routine Analyzer

Analyzes ransomware samples to identify encryption algorithms,
key generation methods, and potential decryption opportunities.

Requirements:
    pip install pefile pycryptodome

Usage:
    python process.py --sample ransomware.exe
    python process.py --encrypted-file encrypted.docx.locked
"""

import argparse
import json
import math
import re
import struct
import sys
from collections import Counter
from pathlib import Path

try:
    import pefile
except ImportError:
    pefile = None


CRYPTO_APIS = {
    "CryptAcquireContextA": ("CryptoAPI", "context"),
    "CryptAcquireContextW": ("CryptoAPI", "context"),
    "CryptGenKey": ("CryptoAPI", "keygen"),
    "CryptEncrypt": ("CryptoAPI", "encrypt"),
    "CryptDecrypt": ("CryptoAPI", "decrypt"),
    "CryptImportKey": ("CryptoAPI", "import"),
    "CryptGenRandom": ("CryptoAPI", "random"),
    "BCryptOpenAlgorithmProvider": ("CNG", "init"),
    "BCryptGenerateSymmetricKey": ("CNG", "keygen"),
    "BCryptEncrypt": ("CNG", "encrypt"),
    "BCryptDecrypt": ("CNG", "decrypt"),
    "EVP_EncryptInit_ex": ("OpenSSL", "init"),
    "EVP_EncryptUpdate": ("OpenSSL", "encrypt"),
    "RSA_public_encrypt": ("OpenSSL", "rsa_encrypt"),
    "AES_set_encrypt_key": ("OpenSSL", "aes_init"),
}

AES_SBOX_PREFIX = bytes([0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5])
CHACHA_CONST = b"expand 32-byte k"
SALSA_CONST = b"expand 32-byte k"


def entropy(data):
    if not data:
        return 0.0
    freq = Counter(data)
    length = len(data)
    return -sum(
        (c / length) * math.log2(c / length) for c in freq.values()
    )


def analyze_sample(filepath):
    report = {"file": str(filepath), "crypto_apis": [], "constants": [],
              "embedded_keys": [], "target_extensions": []}

    with open(filepath, 'rb') as f:
        data = f.read()

    report["size"] = len(data)
    report["entropy"] = round(entropy(data), 3)

    # Import analysis
    if pefile:
        try:
            pe = pefile.PE(filepath)
            if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
                for entry in pe.DIRECTORY_ENTRY_IMPORT:
                    dll = entry.dll.decode('utf-8', errors='replace')
                    for imp in entry.imports:
                        if imp.name:
                            name = imp.name.decode('utf-8', errors='replace')
                            if name in CRYPTO_APIS:
                                framework, op = CRYPTO_APIS[name]
                                report["crypto_apis"].append({
                                    "dll": dll,
                                    "function": name,
                                    "framework": framework,
                                    "operation": op,
                                })
        except Exception:
            pass

    # Crypto constants
    if data.find(AES_SBOX_PREFIX) != -1:
        report["constants"].append("AES S-Box")
    if data.find(CHACHA_CONST) != -1:
        report["constants"].append("ChaCha20/Salsa20")

    # RSA keys
    pem_markers = [b'-----BEGIN PUBLIC KEY-----',
                   b'-----BEGIN RSA PUBLIC KEY-----']
    for marker in pem_markers:
        idx = data.find(marker)
        if idx != -1:
            end = data.find(b'-----END', idx)
            if end != -1:
                key_data = data[idx:end + 30].decode('ascii', errors='replace')
                report["embedded_keys"].append({
                    "type": "PEM RSA Public Key",
                    "offset": f"0x{idx:x}",
                    "preview": key_data[:100],
                })

    # Target extensions
    ext_pattern = re.compile(rb'\.(?:doc|docx|xls|xlsx|pdf|ppt|pptx|'
                              rb'jpg|png|sql|mdb|bak|zip|rar|7z|'
                              rb'psd|dwg|vmdk|raw|db)\b', re.I)
    for m in ext_pattern.finditer(data):
        ext = m.group().decode('ascii', errors='replace').lower()
        if ext not in report["target_extensions"]:
            report["target_extensions"].append(ext)

    return report


def analyze_encrypted_file(filepath):
    with open(filepath, 'rb') as f:
        data = f.read()

    report = {
        "file": str(filepath),
        "size": len(data),
        "entropy": round(entropy(data), 3),
        "high_entropy": entropy(data) > 7.9,
        "possible_appended_key": [],
    }

    # Check tail for appended encrypted key
    for key_size in [128, 256, 512, 1024, 2048]:
        if len(data) > key_size + 16:
            tail = data[-key_size:]
            tail_entropy = entropy(tail)
            if tail_entropy > 7.5:
                report["possible_appended_key"].append({
                    "size": key_size,
                    "entropy": round(tail_entropy, 3),
                })

    return report


def main():
    parser = argparse.ArgumentParser(
        description="Ransomware Encryption Analyzer"
    )
    parser.add_argument("--sample", help="Ransomware binary")
    parser.add_argument("--encrypted-file", help="Encrypted file to analyze")
    parser.add_argument("--output", help="Output JSON report")

    args = parser.parse_args()

    if args.sample:
        report = analyze_sample(args.sample)
    elif args.encrypted_file:
        report = analyze_encrypted_file(args.encrypted_file)
    else:
        parser.print_help()
        return

    print(json.dumps(report, indent=2))
    if args.output:
        with open(args.output, 'w') as f:
            json.dump(report, f, indent=2)


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 0.8 KB
Keep exploring