Babuk v4 Ransomware
Background summary and technical sample analysis
Babuk v4 Ransomware
Background summary and technical sample analysis
Babuk is a ransomware threat discovered in 2021 that attacked at least five big enterprises. The ransomware group behind it follows the Big-Game hunting strategy as a modus operandi.
The first tweet about Babuk ransomware
Right after the attack on Washington D.C Police Department in April, the group announced they wanted to change direction, passing from RaaS to data-theft extortion and eventually becoming open-source.
In September of the same year, the ransomware source code was leaked and became available to the broad public, advised by the notorious malware database vx-underground:
vx-underground advises the source code leak
The malware shares part of its codebase with Vasa Locker , Rook , and DarkAngels ransomwares, and despite the group announcements, its encryption capabilities were enhanced, becoming more efficient during the whole year 2021.
Babuk codebase inheritance tree
The sample :
We are going to perform basic and advanced static analysis of the sample Babuk v4 , you can find it at this link .
MD5 :
a499f810c2e52fe9f8adcd5817b2d985
SHA256 : 245e191bfe998ad9ef2d6b169af22f3c290e9950234f8ddd0f4a03cb3eebf761
Opening the sample with pestudio , we notice that it is importing a wide selection of flagged functions.
pestudio imported functions tab
The summary from Cutter :
Cutter summary dashboard
DIE entropy tab
The static analysis done by Detect It Easy suggests that the sample is not packed . So we can search at the Symbols Tree and open the view to the decompiled code of the entry0 function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
void entry0(void)
{
char cVar1;
undefined4 uVar2;
int32_t iVar3;
undefined4 lpSystemInfo;
int32_t var_74h;
int32_t var_64h;
int32_t var_60h;
int32_t var_5ch;
int32_t var_58h;
uint32_t var_54h;
int32_t var_50h;
int32_t var_4ch;
undefined4 lpString1;
uint32_t var_44h;
uint32_t var_40h;
uint32_t hObject;
undefined4 var_38h;
int32_t var_34h;
int32_t var_30h;
int32_t var_2ch;
int32_t var_28h;
int32_t var_24h;
uint32_t var_20h;
uint32_t lpHandles;
int32_t var_18h;
uint16_t *var_14h;
int32_t var_10h;
int32_t lpString2;
int32_t lpString;
uint32_t nCount;
fcn.0040fde0();
fcn.00412d80();
*(int32_t *)0x414260 = fcn.00404a80();
if (*(int32_t *)0x414260 != 0) {
var_18h = 0;
uVar2 = (*_GetCommandLineW)(&var_18h);
var_38h = (*_CommandLineToArgvW)(uVar2);
(*_SetProcessShutdownParameters)(0, 0);
var_44h = fcn.00404c20(var_18h, var_38h, 0x403c18);
if (var_44h != 0) {
*(uint32_t *)0x414130 = var_44h;
fcn.00404dc0(var_44h);
*(int32_t *)0x41425c = 1;
}
fcn.00404770();
fcn.004049b0();
fcn.004046d0();
(*_SHEmptyRecycleBinA)(0, 0, 7);
(*_GetSystemInfo)(&lpSystemInfo);
var_5ch = var_74h;
var_54h = var_74h * 4;
nCount = var_54h >> 1;
fcn.00412e50(0x4141fc, var_74h * 0x18);
fcn.00412e50(0x41422c, nCount * 3);
lpHandles = fcn.00412e00(nCount << 2);
var_20h = fcn.00412e00(nCount << 2);
if ((lpHandles != 0) && (var_20h != 0)) {
fcn.00412d90(lpHandles, 0, nCount << 2);
fcn.00412d90(var_20h, 0, nCount << 2);
for (var_24h = 0; (uint32_t)var_24h < nCount; var_24h = var_24h + 1) {
uVar2 = (*_CreateThread)(0, 0, fcn.0040a7e0, 1, 0, 0);
*(undefined4 *)(lpHandles + var_24h * 4) = uVar2;
uVar2 = (*_CreateThread)(0, 0, fcn.0040a7e0, 0, 0, 0);
*(undefined4 *)(var_20h + var_24h * 4) = uVar2;
}
lpString2 = fcn.00404c20(var_18h, var_38h, 0x403c24);
lpString = fcn.00404c20(var_18h, var_38h, 0x403c34);
if (lpString2 != 0) {
var_2ch = 1;
var_60h = (*_lstrlenW)(lpString2);
for (var_28h = 0; var_28h < var_60h; var_28h = var_28h + 1) {
if (*(int16_t *)(lpString2 + var_28h * 2) == 0x2c) {
*(undefined2 *)(lpString2 + var_28h * 2) = 0;
var_2ch = var_2ch + 1;
}
}
do {
iVar3 = (*_lstrlenW)(lpString2);
lpString1 = fcn.00412e00(iVar3 * 2 + 2);
(*_lstrcpyW)(lpString1, lpString2);
fcn.0040a9a0(lpString1);
fcn.00412e30(lpString1);
iVar3 = (*_lstrlenW)(lpString2);
lpString2 = lpString2 + 2 + iVar3 * 2;
var_2ch = var_2ch + -1;
} while (var_2ch != 0);
}
if (lpString != 0) {
var_34h = 1;
var_64h = (*_lstrlenW)(lpString);
for (var_30h = 0; var_30h < var_64h; var_30h = var_30h + 1) {
if (*(int16_t *)(lpString + var_30h * 2) == 0x2c) {
*(undefined2 *)(lpString + var_30h * 2) = 0;
var_34h = var_34h + 1;
}
}
do {
iVar3 = (*_lstrlenW)(lpString);
var_14h = (uint16_t *)fcn.00412e00(iVar3 * 2 + 2);
(*_lstrcpyW)(var_14h, lpString);
iVar3 = (*_lstrlenW)(var_14h);
if ((iVar3 == 2) && (var_14h[1] == 0x3a)) {
fcn.0040aad0((uint32_t)*var_14h);
} else {
fcn.0040a5e0(var_14h);
}
fcn.00412e30(var_14h);
iVar3 = (*_lstrlenW)(lpString);
lpString = lpString + 2 + iVar3 * 2;
var_34h = var_34h + -1;
} while (var_34h != 0);
}
if (((lpString == 0) && (lpString2 == 0)) && (iVar3 = (*_OpenMutexA)(0x1f0001, 0, 0x403c40), iVar3 == 0)) {
(*_CreateMutexA)(0, 0, 0x403c60);
var_58h = 0;
cVar1 = fcn.00404b20(var_18h, var_38h, 0x403c80);
if (cVar1 == '\x01') {
fcn.0040a8d0(var_58h);
}
fcn.004044a0();
var_40h = (*_GetLogicalDrives)();
if (var_40h != 0) {
for (var_10h._0_2_ = 0x41; (uint16_t)var_10h < 0x5b; var_10h._0_2_ = (uint16_t)var_10h + 1) {
if ((var_40h & 1) != 0) {
fcn.0040aad0((uint32_t)(uint16_t)var_10h);
}
var_40h = var_40h >> 1;
}
}
cVar1 = fcn.00404b20(var_18h, var_38h, 0x403c88);
if (cVar1 == '\0') {
fcn.0040a8d0(var_58h);
}
}
for (var_4ch = 0; (uint32_t)var_4ch < nCount; var_4ch = var_4ch + 1) {
fcn.00412f70(0x41422c, 0, 1);
}
(*_WaitForMultipleObjects)(nCount, lpHandles, 1, 0xffffffff);
for (var_50h = 0; (uint32_t)var_50h < nCount; var_50h = var_50h + 1) {
fcn.00412f70(0x4141fc, 0, 1);
}
(*_WaitForMultipleObjects)(nCount, var_20h, 1, 0xffffffff);
fcn.004046d0();
for (hObject = 0; hObject < nCount; hObject = hObject + 1) {
(*_CloseHandle)(*(undefined4 *)(lpHandles + hObject * 4));
(*_CloseHandle)(*(undefined4 *)(var_20h + hObject * 4));
}
fcn.00412e30(lpHandles);
fcn.00412e30(var_20h);
}
if (*(int32_t *)0x41425c != 0) {
fcn.00404e00();
}
(*_CryptReleaseContext)(*(int32_t *)0x414260, 0);
}
(*_ExitProcess)(0);
return;
}
Advanced Static Analysis
After analyzing the malware code, we can divide the malware activities into the following phases:
- It will start by obtaining the cryptographic key context and will increase the process completion time of the computer shutdown process.
- Later, it will terminate a predefined list of services and processes, delete shadow copies , and empty the recycle bin .
- After that, it will create several threads (which it will use to traverse and encrypt later); it will discover shared folders, network resources , and disks to know what it can and cannot encrypt (managing exclusion lists too)
- Finally, it will encrypt everything and create the ransom file in each encrypted folder.
Obtaining Key Context
In the beginning, Babuk uses the acquire_CSP function that calls the CryptAcquireContextW API to get an handle to a key container within a Cryptographic Service Provider (CSP) .
Babuk obtains the handle to the CSP
Next, the malware parses the command line arguments and calls the SetProcessShutdownParameters API to increase the time the malware gets to execute in the compromised machine.
Terminating Services and Processes
Than Babuk attempts to close a predefined list of the services and processes :
Services
vss, sql, svc, memtas, mepocs, sophos, veeam, backup, GxVss, GxBlr, GxFWD, GxCVD, GxCIMgr, DefWatch, ccEvtMgr, ccSetMgr, SavRoam, RTVscan, QBFCService, QBIDPService, Intuit.QuickBooks.FCS, QBCFMonitorService, YooBackup, YooIT, zhudongfangyu, sophos, stc_raw_agent, VSNAPVSS, VeeamTransportSvc, VeeamDeploymentService, VeeamNFSSvc, veeam, DVFSService, BackupExecVSSProvider, BackupExecAgentAccelerator, BackupExecAgentBrowser, BackupExecDiveciMediaService, BackupExecJobEngine, BackupExecManagementService, BackupExecRPCService, AcrSch2Svc, AcronisAgent, CASAD2DWebSvc, CAARCUpdateSvc.
The malware obtains a handle to the SCManager with the function OpenSCManagerA . Then, it opens and checks the status of the services by calling QueryServiceStatusEx . If the service is still running, it will enumerate the services that depend on it by calling EnumDependentServicesA , so it will first stop all the dependent services and finally the targetted one , always calling the ControlService function with the SERVICE_CONTROL_STOP flag.
Babuk stops all the dependent services of the target service.
Processes
sql.exe, oracle.exe, ocssd.exe, dbsnmp.exe, synctime.exe, agntsvc.exe, isqlplussvc.exe, xfssvccon.exe, mydesktopservice.exe, ocautoupds.exe, encsvc.exe, firefox.exe, tbirdconfig.exe, mydesktopqos.exe, ocomm.exe, dbeng50.exe, sqbcoreservice.exe, excel.exe, infopath.exe, msaccess.exe, mspub.exe, onenote.exe, outlook.exe, powerpnt.exe, steam.exe, thebat.exe, thunderbird.exe, visio.exe, winword.exe, wordpad.exe, notepad.exe,
Than Babuk uses CreateToolhelp32Snapshot , Process32FirstW , Process32NextW , OpenProcess , and TerminateProcess to enumerate running processes and kill any found to match those in the hardcoded list.
Babuk terminates the processes matching the list.
Delete Shadow Copy
The malware’s following action is deleting the victim machine’s shadow volumes in this way:
- It disables system redirection using Wow64DisableWow64FsRedirection,
- Then calls ShellExecuteW to execute the command “cmd.exe /c vssadmin.exe delete shadows /all /quiet” , which removes the shadow volumes,
- Finally employs Wow64RevertWow64FsRedirection to re-enable file system redirection.
Babuk deletes the shadow volumes
Lastly, Babuk empties the content of recycle bin using the function SHEmptyRecycleBinA .
Babuk empties the recycle bin
Enumerating Shares, Paths and Resources
Shares
Babuk uses the optional arguments shares to enumerate specific network shares.
Babuk parses command line arguments shares and paths
The share discovery employs the API NetShareEnum, which returns an array of SHARE_INFO_0 structures, then parses searching for ADMIN$ shares.
Babuk checks ADMIN$ share
If the check is positive, it calls the find_paths_recursive function, which operates partially like the find_files_recurisive function , pushing the path to the queue. Then popping and encrypting the files it founds enqueued, proceeding with a recursive call in case it finds other directories.
find_paths_recursive routine push, pop and encrypt files
Paths
Babuk does the same with the command line argument paths , used to explore specific filesystem locations, manipulating the path appropriately if it contains a Drive, and then using the find_paths_recursive routine as in the previous case.
Babuk checks if the current path is a drive
Mutex
After the enumeration of shares and paths, the malware checks and creates a mutex named DoYouWantToHaveSexWithCuongDong to avoid starting the encryption if the target is already infected.
Babuck opens and creates a mutex
Resources
In the case attacker specifies the argument sf in the command line, Babuk proceeds to enumerate network resources, using the find_files_network that employs the standard Windows APIs WNetOpenEnumW and WNetEnumResourceW, calling the find_files_network and find_paths_recursive routines recursively.
Babuk parses the sf argument
find_files_network routine enumerate the resources
Finally, Babuk waits for the encryption threads to terminate, calling the WaitForMultipleObjects API, and deletes the shadow copies again.
Babuck waits the threads and removes the shadow volumes
Ultimately it closes the handles to the threads, releases the CSP, and exits, calling the Windows APIs CloseHandle , CryptoReleaseContext , and ExitProcess.
Babuk closes the handles to the threads, then releases the CSP and exits.
Encrypt Everything
Threads and queue
Babuk computes the number of threads for discovering and encrypting the target files and initializes a linked queue it will use to store them.
Babuk creates the secondary threads
The above code is executed inside a loop and creates two threads for each iteration. The thread points to the babuk_thread_encrypt routine that takes one parameter; if its value is 1, the thread will attempt to find the files recursively and then starts the encryption; if its value is 0, it will just begin encrypting the files it finds in the queue.
The secondary threads start either encrypting or enumerating the files
The following drawing shows the way Babuk manages the linked queue:
The operations on the linked queue
The main thread and the slaves push the clear-text files that will encrypt on the queue head; other slaves wait to pop them from the tail. In the find_files_recurisve function, the Master and slaves also create the ransom note file into the directory they traverse before the encryption unless the directory is in the deny list .
Babuk creates the file “How To Restore Your Files.txt”
Babuk writes the hardcoded message to the file it just created
Ecryption
The encryption routine starts renaming the file that has to be encrypted by appending the .babyk extensions:
Babuk renames the files by appending the “ .babyk” extension.
Upon successfully renaming the file, the ransomware generates the victim’s public/private keys using the ChaCha HC-128 ECDH algorithm.
- First, it obtains the 32 random bytes victim’s secret key by calling CryptGenRandom (which uses the CSP handle) .
Babuk generates 32 random bytes for the secret key
- Then , it adjusts the secret key with some “magic” bytes and uses the curve25519_donna function to derive the victim’s public key (needed for the decryption) .
- Finally feeds the attacker’s public key , which was hardcoded by the ransomware builder, to th e curve25519_donna function , obtaining a shared key.
- Hashing the result with SHA256 provides the key for encrypting the files with the ChaCha schema .
Babuk sets up the cryptographic keys
After the set up of the Keys, Babuk creates a structure to hold the encryption meta-data (victim’s public key and its crc32 checksum) to be saved at the end of the encrypted file and proceeds to encrypt the files differentiating in 3 cases.
The following encryption routine fragments compares the result of the SetFilePointerEx function with the hex values 0x1400000 (around 20 MB), 0x500000 (about 5 MB), and 0 bytes to choose the size of the block to be encrypted.
Babuk checks the file size against the hardcoded constants
But the routine does not change substantially: It always uses ReadFile to read a variable amount of bytes in the target file, then encrypts the bytes by calling chacha_encrypt, and finally moves the pointer forwards.
Babuk reads bytes, encrypts, and moves the file pointer
Last but not least, the last fragment of the routine appends the meta-data needed to decrypt the file. That is to say: the attackers need to save the victim’s public key to recover the shared secret and reproduce the symmetric key.
Babuk appends the victim’s public key to the file as metadata
Last Remarks
Conclusions
Babuk is a simple ransomware in that it does not use any obfuscation to hide its IoCs and does not employ any evasion or anti-analysis technique. Moreover, security vendors know it, considering it shares its codebase with several other malicious campaigns; nevertheless, from the analysis, we had the chance to observe how RaaS software executes its TTPs during large-scale campaigns.
Yara Rule
rule BabukRansomwareV4 {
meta:
description = "YARA rule for Babuk Locker v.4 unpacked"
reference = "https://medium.com/@dbragetti/babuk-v4-ransomware-e3a6a1939162"
author = "@dbragetti"
date = "2022-08-10"
rule_version = "v1"
malware_type = "Ransomware"
strings:
$arg_str1 = "shares" wide
$arg_str2 = "paths" wide
$arg_str3 = "sf" wide
$str0= "delete shadows /all /quiet" wide
$str2 = "How To Restore Your Files.txt" wide
$str3 = "DoYouWantToHaveSexWithCuongDong"
$str4 = ".babyk" wide
$str5 = "ADMIN$" wide
$pattern1 = {51003a005c00000057003a005c00000045003a005c00000052003a005c00000054003a005c00000059003a005c00000055003a005c00000049003a005c0000004f003a005c00000050003a005c00000041003a005c00000053003a005c00000044003a005c00000046003a005c00000047003a005c00000048003a005c0000004a003a005c0000004b003a005c0000004c003a005c0000005a003a005c00000058003a005c00000043003a005c00000056003a005c00000042003a005c0000004e003a005c0000004d003a005c000000}
condition:
all of ($str*) and all of ($arg_str*) and all of ($pattern*)
}
References
https://mobile.twitter.com/vxunderground/status/1433758742244478982
https://www.mcafee.com/enterprise/en-us/assets/reports/rp-babuk-ransomware.pdf
https://blog.cyble.com/2021/07/05/deep-dive-into-builder-of-notorious-babuk-ransomware/

{:target="_blank"}](/assets/e3a6a1939162/1*hwHo7jZsENEwPpjpFR8T7A.png)
{:target="_blank"}](/assets/e3a6a1939162/1*muSDjoBE3pUM0zrO-YeQtQ.png)




























