Profero logo
Company
Resources
BlogGithub
CareersTrust Portal
Under Attack?Get Started
Blog

From Drone Strike to File Recovery: Outsmarting a Nation State

By
Guy Barnhart-Magen, Brenton Morris
August 11, 2025
Share this post

https://profero.io/blog/from-drone-strike-to-file-recovery-outsmarting-a-nation-state

Setting the stage

On January 28, 2023, an ammunition factory belonging to the Iranian Defence Ministry in Isfahan was attacked by three drones. Iran later claimed that the drones had caused only minor damage to a building and were shot down.
During the same night, an oil refinery in Tabriz caught fire and there were additional reports of explosions and fires in Karaj, as well as an explosion at an oil facility in Azarshahr.
Israel had no comment regarding the attacks; however, intelligence agencies in the West, as well as in Iran, claimed that the attacks were conducted by Israel as part of an ongoing sabotage campaign against Iran.
After these attacks, an Iranian affiliated account gave statements vowing to destroy Israel and the following was posted to Telegram:

 English translation:

A screenshot of a messageDescription automatically generated

The Beginning of Our Story

After the January 28 attacks, a large organization contacted the Profero Incident Response Team after discovering that employee and other endpoint machines, as well as multiple ESXi servers had been encrypted by ransomware with ransom notes from what was apparently a new cybercrime group who called themselves “DarkBit.”
The encrypted data was very valuable and the client expressed a strong desire to recover what they could, specifically the proprietary data which was stored on the encrypted ESXi servers. The client also suspected this was the work of nation-state-linked attackers.
During the incident, the attackers launched an influence campaign to maximize the damage caused, posting multiple messages on different platforms and attracting as much media attention as they could. The problem? They also ignored all attempts to communicate. We were starting to suspect that this would not be a simple ransomware negotiation.

‍

The incident

Conducting an IR investigation of an incident of this scale is complex. First, it is necessary to develop a detailed understanding of the target organization’s layout. In this case, there were over 30 different departments, each with their own setup, a Class-B IP routable address range and little-to-no centralized control. The attack surface was massive.
To top this off, the sheer number of people involved in such an incident brings its own specific challenges, from navigating the organizational culture to finding the right people to talk to.
One priority remained constant, and was common among all who were impacted: restoring the business operations and recovering data. Once we had a solid grasp of all the moving parts, we took a deep dive into the ransomware behind this mess. Due to the nature of the data encrypted on the ESXi storage, we had our sights set on one file in particular, a ransomware named esxi.darkbit.

‍

esxi.darkbit Analysis

File Overview

The specific tool used by the attackers to encrypt all virtual machines on the target organization’s ESXi servers is called "esxi.darkbit," and was developed in C++.
This tool utilizes the widely-known cryptography library Crypto++ for data encryption.
This tool was designed to encrypt virtual machine disk images on an ESXi server’s VMFS mount.

‍
Here is the file Information:

‍Filename: esxi.darkbit

Size: 1559 KB

SHA256: 0bb1d29ede51d86373e31485d0e24701558e50856722357372518edfb98265a1

MD5: ad2c3054f9de589030269d12a9cbbeeb

Elf Comments: GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4), GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-23)

Command Line Parameters

The tool requires the following command line parameters:

./esxi <path to vmfs> <seconds to sleep before encryption> <list of VMs to encrypt>

Here is an example execution to encrypt two virtual machines stored in /vmfs named esx01 and esx02 without waiting before encrypting:

./esxi /vmfs 0 esx01 esx02

Execution Flow

Once executed, the malware ensures that all VMs are stopped using esxcli:

After this, the malware will fork multiple processes to encrypt files concurrently:

The function labelled encryptDirs walks the directory located at <path to vmfs>/volumes/ and compares the extension of any files located within the following list of file extensions to encrypt:

If the file matches, the malware appends .DARKBIT to the end of the name of each file to encrypt:

The malware then calls the function labelled encryptFile on each file to encrypt.

File Encryption

The malware uses AES with a key size of 16 bytes to encrypt files. The key and IV information are then RSA encrypted using a base64 encoded ASN.1 RSA, with the public key found within the sample.

Each file is encrypted in chunks, and is not entirely encrypted. The size of the chunks to be encrypted and the size of the chunks to be skipped during encryption is determined based on the size of the original file.

If the file size is under 0x640000 bytes (around 6.55MB) then each encrypted chunk will be 0x100000 bytes in length, with the following 0xa00000 bytes skipped. It continues like this until the whole file is encrypted.

If the file is over this limit, then each encrypted chunk will be 0x200000 bytes long and the size of the chunks to skip during encryption is calculated as (FILESIZE / 0x32) – 0x200000.

TextDescription automatically generated

Following this, the malware will seed a random number generator using srand. The seed is calculated by adding the following values together:

  • The current timestamp
  • Process PID
  • Two stack addresses
A picture containing textDescription automatically generated

Next, the malware loops over the file and encrypts each chunk as required using the AES key and IV generated:

TextDescription automatically generated

After this, the key and IV are encrypted using a base64 encoded 2048 byte ASN.1 RSA public key.
Then, the file is appended with a null-terminated string DARKBIT_ENCRYPTED_FILES, followed by 0x100 bytes of RSA encrypted data containing the AES key and IV used to encrypt the file.

TextDescription automatically generated

‍

This image shows the final encrypted data stored at the address in RBX which gets written to the file:

And this image shows the same data appended to our encrypted file:

Corrupted Files

There were several encrypted VMDK files analysed during the IR investigation that revealed traces of corruption or wiper activity.

Some of these files contained multiple encrypted headers at the end of the file in the same way as the file below, which consists of nothing but 0 bytes, and was encrypted during analysis of the ransomware:

A picture containing tableDescription automatically generated

Other files contained chunks of data that had been truncated to repeating values. This indicates that the files had been wiped, as demonstrated in the following real VMDK, “encrypted” by the ransomware during the incident:

TableDescription automatically generated

During testing, we found that the first example of corruption could be reliably reproduced in a lab environment by executing the ransomware file twice at the same time. This leads to a race condition between the two processes which encrypts chunks of data at the same time as each other, and then appends two encrypted headers, thus corrupting the file.

We determined this corruption occurred because multiple ESXi servers were sharing the same VMFS datastore, and thus were encrypted at once. This caused a race condition between the copies of the ransomware running concurrently on the same file system.

The second example of corruption could not be reproduced. Perhaps this was a case of a wiper? Because we did not fully reverse engineer the entire binary, and due to the attackers’ silence, we were aware this was a real possibility.

‍

‍

How Do We Obtain the Decryption Keys?

Ultimately, our clients don’t need to know the intricacies of the encryption process. What they want to know is this: how do we obtain the encryption keys?
In this case, our options were limited, as the attacker refused to answer us.
Without anyone to talk with, we had to figure out whether there was a known decryptor. We began to explore the possibility that this was a modified version of some known ransomware strains, but this led to a dead end.
This left us with only one option.

‍

Can we break it?

Security

When examining a new ransomware strain, there is always the same question in the back of every reverse engineer’s mind: “can we break it?” Too often the answer to this question is assumed to be “no”—but this time, it turned out a little differently.

The ransomware implementation seemed... sloppy. So, we decided to invest the time to fully explore the possibility—after all, who could resist the chance to break the encryption on a possible state-sponsored ransomware?

Validating Their Implementation

Based on our investigation of the encryption implementation, we understood the following:

  • The ransomware uses AES with a key size of 16 bytes to encrypt files. The key and IV information are then RSA encrypted using a base64 encoded ASN. 1 RSA public key found within the sample, and then appended to the encrypted files.
  • During encryption of multiple files, a separate AES key and IV are used for each file.
  • Encryption of each file is done in chunks and not all of the file is encrypted — just enough to render the file useless. The size of the chunks to be encrypted versus the size to be skipped during encryption is decided based on the size of the original file.
A diagram of a black and white diagramDescription automatically generated

The malware uses AES-128-CBC, a known good cipher. The symmetric AES key is encrypted with RSA with a 2048-byte public key, also known to be high quality.

The malware also uses Crypto++ for this, but no dice here as there are no known weaknesses to exploit

We knew that if we could obtain either of the encryption keys (asymmetric or symmetric) we could decrypt the files. We also knew there is no hope of attacking RSA-2048.

AES on the other hand? Well, this depends on the quality of the randomness used to generate the keys on each encrypted host. Considering this potential solution, we sat up in our chairs and worked through the night—we knew we were onto something.

Generating the AES Key and IV

After cleaning it up, the code to seed the random number generator used by the malware essentially looked like this:

srand(pid + time() - 8 + <address of a stack variable> + <address of another stack variable>)
iv = concat(16 * calls to rand())
key = concat(16 * calls to rand())

Any weaknesses here? Well, kind of.
First, we saw we could reduce the parameters we needed to calculate to 3 down from 4, as both stack variable addresses could be calculated if we knew the base-stack address. In our case, all the affected hosts had ASLR enabled, leaving us with a very large—yet still finite—key space, ranging from 0x0 - 0xFFFFFFFF. This has about 20G of possibilities.
Second, we could tackle the current Unix time of the encryption simply by reading the modified time of the encrypted files and trying all values up to a few seconds prior to this timestamp. This is a much smaller key space than the first value we needed to calculate.
Finally, we needed to know the process ID. Unfortunately, we could not obtain this ID via any logs on the hosts; however, this is also a small key space, with only around 10,000 possible values.

This left us with a total key space of approximately 2^39 possible values….leading us to one conclusion that was becoming increasingly obvious:

But before we could start increasing the temps in our data center, how would we know if we found the right key? Luckily for us, VMDK files have a known file header which we could use as our decryption anchor. If we were evaluating a key and IV combination and it gave us a valid VMDK header, we would know we had succeeded. That meant we only needed to attempt to decrypt the first 16 bytes of our encrypted files on each cycle—not bad at all!

At this stage, we took stock of our assumptions and capabilities, determining whether we could scale this operation:

  • We reviewed our understanding of ASLR, timing and PID
  • We ensured we could find a key quickly enough for each VMDK file we wanted to decrypt
  • We confirmed our ability to write our own decryptor to use the keys obtained and attempt to fix the corruption errors seen on some files—developed by fully reverse-engineering and documenting the encryption process

This was starting to sound doable to us. So, we made some calls, and secured the use of some serious computing power and got started.

‍

Brute forcing the encryption key

We made use of an AES-128-CBC key breaking harness to test if our theory was correct, as well as a decryptor which would take an encrypted VMDK and a key and IV pair as input to produce the unencrypted file.
The harness ran in a high-performance environment, allowing us to speed through the task as quickly as possible, and after a day of brute-forcing, we were successful!
We had proven it was possible, and obtained the key. We then continued to brute force another VMDK, but this method wasn’t scalable for two reasons:

  1. Each VMDK file would take us a day to decrypt
  2. The harness sits in an HPC environment and is limited in scaling capability

While expensive, it ended up being possible. We decided to once again take a look at any potential weaknesses in the crypto.

Cryptographic Weaknesses

AES-128-CBC is an AES mode based on chaining the result of the previous encrypted block to the current one. Due to this, an initialization vector (IV) is required to encrypt the first block, as there is no previous block.

A diagram of a block chainDescription automatically generated

We didn’t know the IV, but we did know the values being encrypted by the first block, because VMDK files have a known header structure! This allowed us to greatly reduce the possible values of the first block, even if we still had to try a few possibilities for a couple values.
This is what we had (marked in green), and this is what was missing (marked in red):

A diagram of a block chainDescription automatically generated

Knowing these values allowed us to perform a cryptanalysis attack, dramatically minimizing the size of the key space, which in turn vastly reduced the necessary time to compute each key!
There is a well-known attack on AES-128-CBC first block, if ~50 bits or more are known. We were at this threshold, and therefore could make use of the magic bytes, and other parameter data stored in the first block, to utilize this attack.
And the best part? This could be performed on a regular machine, with no need for high-performance computing.

‍

A Stupid Idea?

As we began to work on speeding up our brute force, one of our team members? had an interesting idea. VMDK files are sparse, which means they are mostly empty, and therefore, the chunks encrypted by the ransomware in each file are also mostly empty.
Statistically, most files contained within the VMDK filesystems won’t be encrypted, and most files inside these file systems were anyways not relevant to us/ our task/ our investigation.
So, we realized we could walk the file system to extract  what was left of the internal VMDK filesystems... and it worked! Most of the files we needed could simply be recovered without decryption.

‍

A collage of images of human brain and a sphereDescription automatically generated

“If it’s stupid but it works, then it’s not stupid”

Sometimes simplest is best. While not always the coolest, seemingly simple, logic-based approaches solve 90% of the problems. In the end, we were able to recover the data we needed via a combination of file system walking and brute forcing.

‍

Attackers’ Mistakes

For one, it is clear to us based on the attackers’ lack of communication and simultaneous media campaign to publicize the attack that their actual goal was not to ransom our client, but to create chaos.

In order to better achieve their goals, they probably should have used a wiper, instead of a ransomware tool more suited to speed than security.
Additionally, if they had engaged in a meaningful negotiation attempt, we might not have defaulted to breaking their crypto.
They also left enough clues for investigators to determine their identity, which destroyed any chance of negotiations although this did not seem to bother them.
Ultimately, they could have designed a better, more solid crypto system—their basic ideas were good, but they failed in the many details of the implementation.

‍

Takeaways

This incident generated major lessons learned—here are just a few:

  • Encrypted files are not always the end of the story. Crypto is hard to understand and even harder to implement correctly. Attackers often make mistakes and if the data is valuable, it is always worth checking their work.
  • There are workarounds for many issues: a dead end is not always a dead end.

Finally, if it works, it’s not stupid.

‍

Share this post
Guy Barnhart-Magen, Brenton Morris

Related posts

Read related insights

View all

AtomicStealer Spreading via Fake Apple Support Websites

Uncovering AtomicStealer campaign using a fake Apple Support website designed to trick users into running a malicious bash command, infecting their machine.

Read Now

The $5 Million Letter: When Physical Mail Becomes Digital Extortion

How sophisticated criminals are using old-school tactics and psychological warfare to extort businesses without ever touching their systems

Read Now

New Attack Vector - AI - Induced Destruction

The New Attack Vector No One Saw Coming, how "helpful" AI assistants are accidentally destroying production systems - and what we're doing about it.

Read Now
View all
Profero logo
Subscribe
By subscribing you agree to with our Privacy Policy and provide consent to receive updates from our company.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Solution
Get StartedUnder Attack?
About
CompanyCareers
Resources
BlogGithubTrust Portal
Contact
X/Twitter
LinkedIn
© 2024 Profero. All rights reserved.
Privacy PolicyTerms of Service
By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.
ManageDenyAccept
Privacy Preferences
Essential cookies
Required
Marketing cookies
Personalization cookies
Analytics cookies
Reject all cookiesAllow all cookiesSave preferences