WhisperGate Published: 2022-01-19 · Archived: 2026-04-05 23:03:43 UTC Table of content⌗ 1. Introduction 1. Samples 2. Environment 1. Tools 3. Analysis 1. Behavioral analysis 2. Static analysis 1. The PE 2. Code analysis 3. Extracting boot sector code 4. Reversing boot sector code 4. The end Introduction⌗ On 05.01.2022, Ukrain had to face a massive cyber attack. This attack was able to take down IT infrastructure of several organizations completely. Microsoft incident response team recently released samples of malware used in the campaign. Samples⌗ virustotal filescan.io Environment⌗ Windows 10 guest (Virtualbox) Windows 10 host Tools⌗ IDA x32dbg bochs https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 1 of 11 Analysis⌗ Behavioral analysis⌗ malware needs administrative privileges in order to be successful. Malware does not create any network traffic, registry modifications or file modifications Upon restarting, device will boot into a screen displaying the following ransom note. Static analysis⌗ The PE⌗ According to detect it easy, the file is a 32 bit PE file. https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 2 of 11 it is compiled and linked using MinGW (GCC 6.3.0) and GNU linker. die shows entropy as 6.07208, which is high but it also says executable is not packed. As usual, entropy in the .text section is higher than in the other sections. https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 3 of 11 strings in the binary are not encrypted. several strings shown in the above diagram gives hints about malware’s capabilities such as disk corruption. Also, note that it shows a bitcoin wallet and a tox ID that can be used as signatures. - 1AVNM68gj6PGPFcJuftKATa4WLnzg8fpfv - 8BEDC411012A33BA34F49130D0F186993C6A32DAD8976F6A5D82C1ED23054C057ECED5496F65 Executable does not have many imports. There’s no APIs related to cryptography eventhough malware claims to encrypt the files. Code analysis⌗ IDA shows that PE contains two TLS callbacks. Initially suspected these were for anti-debugging purposes but turns out to be no. https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 4 of 11 first TLS callback starts calling some function pointers if Reason is DLL_THREAD_ATTACH . the second TLS callback simply returns if Reason is something other than DLL_THREAD_DETACH or DLL_PROCESS_DETACH , suggesting this may be de initializing whatever initialized by the tlscallback1 . https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 5 of 11 start function calls sub_4011b0 after setting the app type. sub_4011b0 calls function sub_403b60 that is responsible for main functionality of the malware. the function copies 2048 bytes at global offset `` into the stack. https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 6 of 11 offset contains bytes of compiled x86 real mode boot sector code, along with the boot signature 0x55AA . Then it calls CreateFileW passing \\\\.\\PhysicalDrive0 as filename argument. returned handle is then passed to WriteFile along with the stack buffer that contains boot sector code. If the call is successful, it will overwrite MBR (master boot record) with a custom boot sector. After BIOS has done selecting the boot device it will load overwritten MBR into memory and the CPU will start executing a parasite bootloader. Also, note that malware does not encrypt anything. https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 7 of 11 buffer containing boot sector code can be extracted by placing a breakpoint at the address where it is accessed and using the show in dump feature in x32dbg. extracted buffer can be then saved as a raw binary file for further analysis. Reversing boot sector code⌗ cs segment register is initially initialized to 0x0, it is used to zero out ax and set up other segment registers. then loads the ransom note into si register. https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 8 of 11 Next instruction calls print_loop , which then calls print_char after loading al with the byte at si . And it will repeat this operation until [si] is null. print_char uses BIOS interrupts to put a single character into the screen. A BIOS interrupt call is a feature of BIOS that allows bootloaders and early kernels to access BIOS services such as video memory access and low-level disk access. To use BIOS interrupts, ah register should be initialized to the function number. parameters passed down through registers and similar to x86 syscalls, int instruction is used to do the software interrupt along with the BIOS service number For instance, in the above image, malware loads Display character function number 0x0e into ah and calls BIOS video service. More about BIOS interrupts - Ralf Brown’s BIOS interrupt list. After printing the ransom note, the overwritten code jumps into another label which then jumps to label corrupt_c Two insutrctions after segment register initialization sets word at 0x7c78 to 0x0000 and dword at 0x7c76 to 0x7c82 (‘AAAA’). https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 9 of 11 This basically initializes the DAP (Disk Address Packet) structure. DAP is a structure that should be initialized in memory in order to use Logical block addressing with interrupt 0x13. This structure is then should be passed through si register. layout of the structure Offset Size Description 0 1 size of packet (16 bytes) 1 1 always 0 2 2 number of sectors to transfer (max 127 on some BIOSes) 4 4 transfer buffer (16 bit segment:16 bit offset) (see note #1) 8 4 lower 32-bits of 48-bit starting LBA 12 4 upper 16-bits of 48-bit starting LBA before the interrupt call int 0x13 , which is used for low-level disk access, ah register is initialized to 0x43, BIOS function number for writing sectors to the disk. following registers are also initialized al - 0x0 (close clock write) dl - 0x80 (hard disk) si - 0x7c72 (DAP) The si register is loaded with address 0x7c72 , which must be the disk address packet. The next few instructions check whether an extended write operation is successful or not. if cf is set (errors) control flow gets redirected to loc_7c45 , else, to loc_7c5d . at loc_7c45 , it increments the last element in the byte array by 1 and moves 0x1 to [0x7c7a] . int next instruction zero out [0x7c7e] . https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 10 of 11 loc_7c5d adds 0xc7 to [0x7c7a] and 0x0 [0x7c7e] . clc clears the carry flag. Both blocks jumps back to corrupt_c . The loop will continue until the hard disk is completely overwritten by AAAA s. The end⌗ quick analysis report of WhisperGate stage 01 ends here. #Spread Anarchy! Source: https://rxored.github.io/post/analysis/whispergate/whispergate/ https://rxored.github.io/post/analysis/whispergate/whispergate/ Page 11 of 11