Babuk Ransomware v3


This is a short report for the latest Babuk ransomware sample. This sample is marked as version 3 based on the run-once mutex string.

For this new version, the malware author keeps most of the old functionalities the same except for the encryption scheme and the multithreading approach.

Since I have covered Babuk old sample here, I will only discuss the new changes in this report.

For encryption, Babuk uses ChaCha20 encryption, but the Elliptic-curve Diffie–Hellman (ECDH) key generation and exchange algorithm is changed from NIST K-571 to Curve25519, one of the fastest ECDH curves.


Babuk v3 comes in the form of a 32-bit .exe file.

MD5: 8b9a0b44b738c7884e6a14f4cb18afff

SHA256: 704a0fa7de19564bc743fb68aa0652e38bf86e8ab694bc079b15f945c85f4320


alt text

Figure 1: VirusTotal result for Babuk v3

Ransom Note

alt text

Figure 2: Babuk’s new ransom note

New Changes

Run-Once Mutex

In the beginning, Babuk checks if a mutex with the name “babuk_v3” exists through the call to OpenMutexA. If it already exists, the malware exits immediately.

This is commonly used by malware to prevent themselves from having multiple instances running at once.

alt text

Figure 3: Babuk checking for mutex

Command-line Arguments

Babuk can work with or without command line parameters.

The new command line parameters are “lanfirst”, “nolan”, and “shares”.

alt text

Figure 4: Babuk checking for mutex

If a parameter is given, it will process these arguments upon execution and behave accordingly.

CMD Args Functionality
-lanfirst Encrypting other drives on LAN and locally
-nolan Encrypting locally
shares Encrypting shared drives and locally


The multithreading implementation has been changed a lot since the first version. I guess they really tried to improve it after reading what I had to say in the last blog post :relieved:

alt text

Figure 5: Babuk team’s friendly response to my analysis!

The steps taken to improve the ransomware’s threading functionalities are in the right direction since they do increase the encryption speed by quite a bit.

Babuk uses a structure similar to a circular queue (Ring Buffer) backed by an array to store file names to encrypt. The queue size is double the number of processors on the system, which is the same amount of child threads being spawned.

alt text

Figure 6: Queue initialization

This queue is shared and used by child threads.

The parent thread will recursively crawl through directories and enqueue the file names it finds to the head of the queue. The child threads will start dequeuing them at the tail of the queue to begin encryption.

alt text

Figure 7: Babuk’s circular queue illustration

First, Babuk will spawn child threads. The number of threads being spawned is double the number of processors. This is clearly not a good amount so I have no idea why they still use it similar to the previous version.

alt text

Figure 8: Spawning child threads

The Babuk parent thread then proceeds to traverse through an entire drive by checking whether it has encountered a directory or a file.

Upon finding a directory, it will call that function again and go down another layer to recursively traverse that directory.

Upon finding a file, it will enqueue that file to the head of the queue and move on.

alt text

Figure 9: Babuk parent thread traversing through directories and enqueuing files

Each child thread will dequeue a file at the tail of the queue and encrypt it.

alt text

Figure 10: Babuk child threads dequeuing and encrypting files

Here is the implementation for enqueuing and dequeuing files.

alt text

Figure 11: Function to enqueue files

alt text

Figure 12: Function to dequeue files

As we can see, Babuk uses a file queue backed by an array. By keeping track of the head and tail indices, adding and removing file names from the queue take a constant time and are really fast.

With all of these new changes to the implementation, this new version of Babuk is much faster than the original one. Unfortunately, there is still a lot more room for improvement since it is nowhere near Conti and other ransomware in terms of speed and efficiency.

With an array-backed queue, space is limited. As we can see in the enqueue function, there is no check to see if the queue is full before adding more files onto it. In the theoretical case where all the threads are busy encrypting files and the queue is full, the parent thread will continue adding more files. Since this is a circular queue, this will result in files being overwritten with new ones before the child threads have a chance to encrypt them if the parent thread is fast enough.

Moreover, the malware author still sticks with the old recursive approach to traversing files. With only the parent thread traversing entire drives, there will be an extreme amount of overhead from the stack frame since there will be too many recursion layers. This essentially makes the total encryption time dependent on the time it takes for one thread to traverse the entire system.


Encryption scheme remains the same from the original version. However, there is a slight change in the ChaCha20 key generation.

For every file, a random buffer of 32 bytes is generated using CryptGenRandom.

alt text

Figure 13: Generating random buffer

Next, using the this exact piece of Curve25519 implementation, Babuk will generate a public key for the victim from the random buffer using ECDH.

It will also generate a shared secret using its hard-coded public key and the random buffer. This shared secret is eventually used as the ChaCha20 key to encrypt the file.

alt text

Figure 14: Public key and shared secret generation

Finally, the victim’s public key is then written to the end of the file to be used for decryption if the victim decides to pay.

alt text

Figure 15: Victim’s public key being written to the end of file

Not sure if this was intended, but I believe the Babuk group has messed up the public key generation phase.

According to Dan Bernstein who was the author of this Diffie-Hellman function, here is the procedure of generating a public key using Curve25519.

alt text

Figure 16: Curve25519 Public Key Generation

Instead of using 9 followed by all zeroes, Babuk uses an array of all 9 values.

alt text

Figure 17: Babuk’s basepoint constant

Unless the malware author has modified the math in the Curve25519 source code to accommodate for this (which is unlikely), this basepoint constant might not generate a correct public key.

With an incorrect public key, it’s impossible for the malware author to generate the correct shared secret to decrypt files.

Key Findings

The new version of Babuk has been improved to encrypt files at a much faster rate using a better multithreading approach. Despite still having a lot to improve, Babuk has been really effective in attacking many corporations using ChaCha20 encryption as well as Elliptic-curve Diffie–Hellman algorithm.

As suspected, the Babuk team probably uses spear phishing attacks, VPN 0-days, and vulnerable RDP setup to target certain companies. They have dropped this sample specifically targeting a mechanical contractor in Austria according to the ransom note and the conversation with the victim on their website.

alt text

Figure 18: Babuk team asking the victim to provide their company email

Message to newer victims

I recently notice I’m getting a lot more traffic from Europe on this page, which I’m assuming newer victims are viewing this to better their understanding of the ransomware.

This blog post is really out of date because Babuk has evolved a lot, and the malware is drastically different from what I talk about here.

If recent Babuk victims are interested in getting more information about the newer version of this ransomware or require any assistance with analyzing any sample, feel free to reach out to me through my email cdong49@gatech or Twitter!


rule BabukRansomwareV3 {
        description = "YARA rule for Babuk Ransomware v3"
        reference = ""
        author = "@cPeterr"
        date = "2021-01-16"
        rule_version = "v3"
        malware_type = "ransomware"
        tlp = "white"
        $lanstr1 = "-lanfirst"
        $lanstr2 = "-nolan"
        $lanstr3 = "shares"
        $str1 = "BABUK LOCKER"
        $str2 = "babukq4e2p4wu4iq.onion"
        $str3 = "How To Restore Your Files.txt" wide
        $str4 = "babuk_v3"
        $str5 = ".babyk" wide
        all of ($str*) and all of ($lanstr*)