LockBit 3.0 (also known as LockBit Black) is a new variant of the LockBit ransomware. It encrypts files, modifies their filenames. LockBit 3.0 was first observed around June 2022.
Figure 1: LockBit 3.0 Builder Leaked on Twitter
This released code enables for comprehensive and unrestricted examination, but regrettably also implies that numerous new groups are developing, employing the same or modified versions of LockBit 3.0 coming from this constructor.
Figure 2: LockBit 3.0 Builder
The builder, once extracted, contains the files shown in Figure 2, with the Build directory empty. Running the Build.bat file, which includes the contents shown in Figure 3, automates the build process and populates the Build directory with a unique instance of the ransomware. The resulting files are shown in Figure 4.
Figure 3: Content of Build.bat
The commands that makeup Build.bat, clear the Build directory and then call keygen to create the public and private encryption keys. The next lines that start with “builder”, create the different variations of the LockBit 3.0 ransomware by supplying the builder with different command line options.
Figure 4: LockBit 3.0 File Listing after Build
Description of Generated Files
The first executable executed in Build.bat is keygen.exe. It generates a unique public-private key pair for each build as well as the decryption ID. Keygen appears to rely significantly on MIRACL, which according to its own description is, “…a C software library that is widely regarded by developers as the gold standard open-source SDK for elliptic curve cryptography.” The generated keys are base64 encoded and saved to files priv.key and pub.key. Then the unencoded first eight bytes of the public key are converted to their hex values and saved to the DECRYPTION_ID.txt file, which functions as a unique victim identification number.
As demonstrated previously in Figure 4, the builder.exe file builds two executables, three dynamic link libraries, and two text files. In order to finish this, it requires the existing config.json (Figure 2), and the priv.key/pub.key files generated in the previous stage by keygen.exe and displayed in Figure 4. The builder.exe file itself also holds important. In its resource section are four executable template files. Each of them are utilized to construct the DLL and EXE encryptors as well as the application used for decryption.
Figure 5: Builder.exe Resources
Description of each resource by its ID:
The configuration file, config.json, provides parameters often linked with ransomware such targeted folders, files to avoid, and processes that should be destroyed. As illustrated in Figure 6, it also provides configuration choices to adjust the behavior of the ransomware, those mentioned below were discovered by default in the builder.
Figure 6: Configuration Options
This builder configuration allows the resultant ransomware to be tuned for a specific target environment. In addition to these configurations there are options for
Since this malware is highly configurable there are many distinct code pathways possible. For the purpose of simplicity, the analysis here will focus on running the ransomware in the default condition, without command line configuration variables. However, to clarify full functioning these choices will be mentioned in relevant code sections.
The first set of code, decompiled for readability, within the program is displayed in Figure 7. This code demonstrates that the executable contains a considerable amount of unnecessary GUI related code mentioned following a call to exit the process, highlighted as kernel32.ExitProcess(). All the ransom functionality occurs in the three functions that occur just before the call to ExitProcess. The main function comprises the greatest chunk of the ransomware functionality. The implementation of unneeded code is not new to malware development, but it is also not particularly prevalent. A strategy like this helps disguise the true goal of the infection from researchers, and can help make malware seem legitimate.
Figure 7: Entry Function
Typical applications either call DLL functions directly or make simple calls to obtain the process addresses of DLL functions. The LockBit builder employs a unique and obscure mechanism for discovering and utilizing external functions. Figure 7 shows a function called "prepare_address_table_lookups" that generates a table of hashes from a series of function calls. The lowercase library and function names are separated by a dot in each entry in this collection (for example, ntdll.findfirstfileexw). LockBit 3.0 searches the Windows System32 folder for the DLLs it need, then manually loads each function, laboriously hashing and matching each function's library and name combination to generate the address table. Once the hashed library and function table is produced, the malware takes care to release and erase all memory to prevent investigation. It should be noted that this is only a fraction of the functions that are called because more functions are fetched and called from the Windows kernel during runtime.
The "check_priv_elevate_if_needed" function, as shown in Figure 7, performs exactly what the name says. Duplicating access tokens to gain membership in privileged groups results in privilege escalation. Understanding this requires a high-level understanding of Windows privileges. In real life, Windows privilege is analogous to a big ring of keys that grants access to otherwise prohibited locations. These keys are known as access tokens in Windows, and each access token can include one or more privilege constants. Each privilege constant defines a specific action or collection of actions in the operating system that can be restricted. For example, practically everyone has a privilege constant named SeShutdownPrivilege, which allows a local user to shut down the operating system. Windows would not enable the shutdown if this privilege constant was not present in the access token. Similarly to how a physical key ring can carry many keys, a single access token can have multiple permission constants.
It is critical to realize that processes and services initiated by the user or on his or her behalf are endowed with or inherit the user's rights. However, not all system processes and services are owned by the user; some are owned by the operating system. These operating system processes and services must have distinct privileges. Simply put, LockBit 3.0 copies an access token from a system process and uses it in a user process to enable functionality that would otherwise be banned.
Duplicating tokens LockBit 3.0 accomplishes various tasks. It will first check for membership in the Domain Admin group to see whether it already has adequate privilege. If this is not discovered, it tries to grant itself a predefined list of fifteen privilege constants, the majority of which failed in testing when executed as an unprivileged user. If LockBit 3.0 still does not have the required privilege, it locates the operating system process explorer.exe and immediately runs ZwOpenProcessToken to read the access token for explorer.exe. Then it invokes NtDuplicateToken with the newly acquired token handle to seek read and write access to the copy's extended characteristics.
Figure 8: Duplicate the explorer.exe Process Token
In this scenario, the Explorer process was specifically targeted. However, when the application runs, the token privileges are checked each time certain processes are contacted, and if extra privileges are discovered, the token is copied. Gaining a token with privileged domain access is highlighted.
One of the first things the malware does in its main function is look for and construct a synchronization mutex. If the mutex is present, the process will terminate, guaranteeing that only one instance of the ransomware is active at any given time. The mutex is created by first calculating the MD5 hash of the supplied public key, which can be found in the pub.key file. The generated MD5 hash is string formatted with "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}". Following that, the MD4 hash of this formatted string is computed and the result is sent to the format string "Global%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%. A completed mutex value, for example, might be Globalea4ee28880136cbc44dff4ad5a53561f.
LockBit 3.0 then verifies that the operating system booted normally. When Windows is booted in safe mode, the ransomware disables most of its functionality and instead creates a registry key that will be executed on the next normal boot.
With the mutex in place and the boot type satisfied, the executable's main purpose is begun in a multi-threaded fashion. Each thread adopts the traits of its tasking. Some run continually for the duration of the process, while others run only once to complete a specified task.
The first thread is responsible for removing Windows Security Services. This is accomplished by utilizing the Trusted Installer service. The Trusted Installer, also known as the "Windows Modules Installer," is typically used to download and install Windows updates and optional components. If the Trusted Installer is not already operating, it is started, and its access token handle is duplicated to give the current thread access to most other services that are running. LockBit 3.0 enumerates the operating services with this token, and any service that matches one of those predefined in config.json is stopped and removed. When the thread is finished, it exits and does not re-start.
Figure 9: Notification Windows Security Center stopped
Figure 10: Error attempting to restart Windows Security Center
During testing, a small taskbar notification displayed briefly to tell the user that the Windows Security Center service had been terminated. However, because the service had been both halted and destroyed, the Windows notification could not be utilized to restart it.
Description of the Service SecurityHealthService provides up-to-date information about the endpoint's security health, including monitoring of Windows and other vendor's tools. wscsvc Service Sense in Windows Security Center Advanced Threat Protection Service for Windows Defender sppsvc Licensing for Microsoft's Software Protection Service WdBoot WdFilter Windows Defender ELAM (Early Launch Antimalware) Driver WdNisDrv Windows Defender Mini-Filter Driver Driver for Windows Defender Antivirus Network Inspection System WdNisSvc Network Inspection Service in Windows Defender Windows Defender Service WinDefend
Table 1: Services Discontinued and Removed
It is crucial to note that the Windows Security Service was specifically targeted because it was specified in the default config.json file. Other services would almost certainly be stopped if threat actors used this construct to list them.
Figure 11: Services stopped and deleted
When the services are deactivated, the malware will start multiple new threads. Figure 12 provides a screenshot of the threads with the longest runtime. The thread that handles files in the Windows Recycle Bin is launched first, followed by threads that monitor for and terminate the SQL process. Then there's a post about attaching ransom notes to directories. Encryption threads are the last to be started. The screenshot below shows three threads devoted to this, but the number of threads is dynamic and will rise or decrease based on available system resources and the amount and kind of things queued for encryption. Network resources specified for encryption, for example, are handled separately from those on the local system.
Figure 12: Some of the LockBit 3.0 Threads
As demonstrated above, there is a specific thread for dealing with files located in the recycle bin. The files in the recycling bin are not encrypted; instead, their contents are replaced with randomly generated bytes in 0x10000 byte blocks before being removed. As a result, even with the decryptor, all files in the recycle bin are unrecoverable.
A separate thread runs continuously, watching for and stopping any SQL process. It does this by getting a list of services every two seconds. Each service name is passed to the function isSQL(), which looks for any occurrence of the case insensitive string SQL. If the name contains this sequence, it is terminated. Unlike many of the other threads, this thread runs for the life of the process ensuring that SQL will not run for more than two seconds while LockBit 3.0 performs ransom activity.
Figure 13: Terminate SQL Service
A topic has been started to discuss the elimination of Volume Shadow Copies. A shadow copy is a snapshot of a volume that duplicates all of the data stored on the volume at a specific point in time. This is finished by calling the IWbemProvider COM object and launching an in-process server to allow requests to the Windows Management Interface. This causes the WMI query "SELECT * FROM Win32_ShadowCopy" to be executed, and then each of the resultant Shadow Copies to be deleted.
The ransom note thread locates and decrypts the embedded ransom note specified in config.json. The notice is sent to every directory that has not been marked for exclusion. Its file name consists of nine alphanumeric letters followed by ".README.txt" (for example, xEC9do6g6.README.txt). The base64 encoding of the first 6 bytes of the MD5 hash of the previously produced mutex GUID precedes the ".README.txt" unique value. Because of this strategy, all ransom notes left on the system have the same name yet are distinct to that system.
The Salsa-20 method is used to encrypt the files. During the encryption threads, memory containing the private key is heavily protected with RtlEncryptMemory and RtlDecyptMemory, which makes the private key available in memory unencrypted only for the period required.
Another thread tries to access the infected system using the users and passwords obtained in the configuration. By default, the usernames and passwords found in the config.json file are those connected with administrative accounts. If any login is successful, the token membership is checked to see if it belongs to a domain admin group and, if so, it is duplicated. Another thread then searches for and enumerates available domain controllers, obtaining their names and trying a remote login with the successful username and password.
Other threads check for connected drives and network resources while giving special attention to those where operating systems are installed. In all cases these newly discovered paths are passed to a function that spawns additional encryption threads.
TLS 1.2 is used for command and control traffic to the addresses indicated in the config.json file. Unfortunately, under this TLS layer, the variables and their values are AES encrypted, and the order is scrambled for each request. The overall syntax of the POST request, however, is similar, as illustrated in Figure 14. A POST request was consistently seen, followed by "/?" and a long string of URL style variable=value pairs separated by an ampersand, followed by the HTTP/1.1 fields. Because the User-Agent string is randomized, it should not be used in signatures; however, the Connection, Accept-Encoding, Content-Type, and Cache-Control fields are constant. The data section's fundamental format was also consistent, however the length varied significantly.
Figure 14: Initial POST Request
Although decrypting the intercepted network traffic would be close to impossible without the encryption key, the below example provides a general understanding of the information transmitted.
Figure 15: JSON Formatted Exfil Data
Post encryption, the desktop background is changed to black with white text similar to the example in Figure 14. Additionally, the icons of encrypted files are changed to the LockBit “B” icon shown in the upper left corner of Figure 16.
Figure 16: Ransom Desktop and LockBit Icon
We tested the decryptor's operation and use once it was produced with the builder. When ran, a window like the one below appears, and the user must click the large button on the right labeled "Decrypt All Encrypted Files." Once clicked, the All Decrypted Files number increases as files are decrypted. As demonstrated here, the application never quit, but it had stopped processing files due to CPU utilization, indicating that it had concluded.
At the end of processing, there was a 64-file difference. The file system was checked for any LockBit named files to account for these 64 files, but no matching files were discovered. The Recycle Bin files could account for some of the 64, but removing 10 files from the recycle bin still left us well short of the total. Aside from these lost files, the Recycle Bin was not restored, and all volume shadow copies were still deleted. The decryptor did work for all general files, files were properly restored, and the Lockbit desktop wallpaper was erased. There were no definitive tests performed to compare the number of encrypted or decrypted files reported by this tool to the number reported by this tool.
Figure 17: LockBit 3.0 Decryptor