Black Kingdom Ransomware

Black Kingdom Ransomware

Executive Summary

Hot on the heels of 'Dearcry'[1], yet another ransomware threat has been observed as targeting Microsoft Exchange servers vulnerable to recently reported critical vulnerabilities[2].

Dubbed 'Black KingDom', this ransomware threat has reportedly been deployed through a web-shell that is installed on vulnerable Microsoft Exchange servers following the exploitation of the vulnerability chain that results in both remote code execution (RCE) and elevated privileges.

Seemingly in an attempt to capitalize on these high impact Microsoft Exchange server vulnerabilities, the ransomware appears somewhat 'cobbled together' in Python, using code elements identical to 'snippets' shared on legitimate development forums along with sub-optimum methods and unused or defunct lines of code.

To allow the execution of the ransomware without the need for a Python interpreter or specific modules to be already present, a likely scenario on an enterprise Microsoft Exchange server, the threat is packaged as a Windows executable using 'PyInstaller' including all dependencies.

Although not observed, the ransom note suggests datgithuba may have been stolen from the compromised host and could be released should the ten thousand US dollars ($10,000) ransom, in Bitcoin (BTC) not be paid (Figure 1).

Black Kingdom Ransomware_0

Figure 1 - Ransom note window displayed at the conclusion of the encryption process

Typically, groups conducting 'steal, encrypt and leak' or double extortion tactics will maintain some form of online presence with which to apply further pressure on victims through 'naming and shaming', nothing of this nature has been observed thus far for 'Black KingDom'.

Notably, of the samples analysed, the threat actor has utilized hard-coded credentials to send a 'key file' from each victim to the 'Mega' file-sharing service albeit this account appears to be inaccessible and therefore the threat actor will not be receiving the keys required for decryption.

That being said, and in a potential stroke of luck for victims with hosts that were unable to communicate with Mega, potentially from 22 March 2021 onwards, the ransomware includes a failover hardcoded encryption key, eebf143cf615ecbe2ede01527f8178b3, that, if combined with the initialization vector that is prepended to each encrypted file, could allow the AES-256 CBC encrypted data to be decrypted. As a proof-of-concept (PoC), a decryption script written in Python is provided within 'Appendix A' of this report to assist those that may have data encrypted with this failover key.

Unfortunately, for those that did successfully communicate their encryption key, the value is a random string generated upon each execution of the ransomware and therefore the likelihood of recovery is incredibly low.

In either case, victims of ransomware attacks are typically best to initialize their disaster recovery procedures and avoid making ransom payments as these often serve as to only perpetuate threats of this nature.

Initial Compromise

Whilst not directly observed, reports suggest that Microsoft Exchange servers targeted with Black KingDom were initially compromised through the following vulnerabilities, as seen in the high-profile HAFNIUM attacks as well as recent Dearcry ransomware attacks:

  • CVE-2021-26855 - Server-side request forgery (SSRF) vulnerability, also known as 'ProxyLogon', allowing threat actors to send arbitrary HTTP requests and authenticate as the Exchange server .
  • CVE-2021-26857 - Insecure deserialization vulnerability, allowing untrusted data to be processed, in the Exchange Unified Messaging Service leading to code execution with SYSTEM privileges.
  • CVE-2021-26858 - Post-authentication arbitrary file write vulnerability allowing files to be written to any path on the Exchange Server.
  • CVE-2021-27065 - Another post-authentication authenticated arbitrary file write vulnerability.

Subsequently, the ransomware is reportedly downloaded and executed via a malicious web-shell, that being a malicious script providing file system and remote process execution capabilities, and would gain elevated privileges through the exploitation of CVE-2021-26857.

Configuration

Upon execution, the ransomware initially generates a random encryption key based on an MD5 cryptographic hash of a random sixty-four character string, composed of uppercase letters and numbers (Figure 2).

Black Kingdom Ransomware_1

Figure 2 - Random string and MD5 hash method to generate the key used for encryption

Note: Those following this report with their own copy of the ransomware will find our line numbers are 'plus one' due to the insertion of a 'safety line' to prevent inadvertent execution of malicious code during analysis.

For later use in linking this encryption key to the victim, a victim identifier, referred to as gen_id, is also generated as a twenty character random string of letters and numbers which is later appended to the ransom note which is present within the ransomware script as a base-64 encoded string.

Notably, a truncated version of this base-64 encoded ransom note is also allocated to an unused variable which is passed to the Python length function, len. Serving no purpose, code elements such as these combined with the overall structure of the script are consistent with our observation that this code appears to have been hastily prepared.

Prior to commencing the call home and main encryption processes, there should be opportunity for the encryption phase to be delayed, if implemented correctly, by executing the ransomware with a command line argument (Figure 3).

Black Kingdom Ransomware_2Figure 3 - Delayed encryption

Regardless of the command line argument status, the encryption phase proceeds immediately due the sys.argv[1] statement returning a string value rather than an expected integer as expected by the time.sleep() function to specify a number of seconds to wait.

Key Exfiltration

In a pseudo-call home communication, albeit to a publicly accessible service rather than to a server under the control of the threat actor, the ransomware attempts to transfer a single text file to an account on the 'Mega' filesharing service.

This text file, named <VICTIM_ID>_<VICTIM_DOMAIN>.TxT, contains victim identifiers along with the encryption key (Figure 4) and is therefore, in many cases, critical to the successful recovery of encrypted data.

Time: <CURRENT_TIME>
ID : <VICTIM_IDENTIFIER>
KEY: <VICTIM_KEY>
USER: <VICTIM_USERNAME>
DOMAIN: <VICTIM_DOMAIN>

Figure 4 - Key data sent to the threat actor via 'Mega'

Providing failover capabilities should communications fail for any reason, the chackkey() function includes a base-64 encoded hexadecimal encryption key that is consistent across all the samples analysed with a value of eebf143cf615ecbe2ede01527f8178b3 (Figure 5).

Black Kingdom Ransomware_3

Figure 5 - 'Mega' upload functions and hardcoded failover encryption key (Lines 64 & 66)

As can be seen in the sendKey function, a hardcoded base-64 string is used to authenticate to the Mega service using an email address as both the username and password.

Given that, based on our analysis, the hardcoded Mega account used by the threat actor has been inaccessible since at least 23 March 2021, victims targeted with the ransomware since that date, if not before, may find that their data has been encrypted using the hardcoded encryption key and therefore may be recoverable through a decryption process.

Encryption Process

Preparation

In the absence of any persistency or anti-analysis capabilities, the ransomware first attempts to stop any SQL services from running, allowing any database data to be encrypted, through the use of two embedded Microsoft PowerShell commands (Figure 6).

Black Kingdom Ransomware_4

Figure 6 - Attempt to 'stop' SQL services

Whilst the first of these commands appears to be syntactically correct, its execution in the os.system (Windows command prompt) context results in the output pipe >$null being interpreted as a file location. As such, when this command is executed, a file named $null will be saved in the same directory as the ransomware executable rather than the command's output being sent to the PowerShell null variable.

The second PowerShell command is an attempt to cover their tracks and deletes the PowerShell history located in %APPDATA%\\Microsoft\\Windows\\PowerShell\\PSReadLine\\ConsoleHost_history.txt.

File Discovery

As is to be expected with any ransomware threat, the process then commences with a discovery phase in which potential target drives are identified and then directory 'walked' to identify files for encryption.

In this case, a function named get_target() is used to determine a list of targets through two possible methods (Figure 7), the first of which being the creation of a list containing potential drive letters from 'A to Z', ['A:\\\\', 'B:\\\\', 'C:\\\\', ... 'Z:\\\\], or attempting to read the contents of a threat actor supplied target list from a file named target.txt that could presumably accompany the ransomware executable.

Black Kingdom Ransomware_5

Figure 7 - Target drive/location determination

If the external target file is present, this function will return a list containing the predefined targets, if not the 'A to Z' list of drives will be passed to the encryption function.

Similar to many other ransomware threats, an exclusion list of paths (Figure 8) is provided to presumably ensure that the system remains stable after encryption to allow the ransom note to be viewed.

Black Kingdom Ransomware_6

Figure 8 - Path exclusion list

Conversely, unlike other ransomware threats, no target file extension list is provided and therefore an infected host may become unstable as potentially any file, outside of the exclusion paths, could be encrypted.

Encryption

Utilizing the standard Python library for concurrent execution, concurrent.futures, the encryption function creates a maximum of ten worker threads for parallel processing to speed up the encryption process.

With the identified target drives, and excluding folders in the exclusion list, the file system is 'walked' with each filename found being submitted to the parallel processing pool executor for encryption using the previously generated, or failover, encryption key (Figure 9).

Black Kingdom Ransomware_7

Figure 9 - encrypt_file function called

In turn, file will be opened and the content read into memory with padding added, if required, to ensure the block size is correct for use encryption using the Advanced Encryption Standard and a 256 bit key (AES-256).

As is recommended for use with AES encryption, and coincidently appearing in Python AES encryption examples that are almost identical to the code used in this threat, an initialization vector (IV) value is randomly generated for each file encryption operation and prepended to the encrypted data (Figure 10).

Black Kingdom Ransomware_8

Figure 10 - Encryption process

The resulting IV and encrypted data is subsequently written to the same file resulting in the original data being overwritten on disk and likely thwarting data recovery efforts.

Given that the IV value is randomly generated on a per file basis, there is no simple way of determining the status of a file based on, for example, a consistent file header. As such, if the encryption process were interrupted, an incident responder would presumably need to evaluate each file to determine if its content has changed or not, potentially by comparing known file types against their 'magic bytes'[3].

Disable Keyboard & Mouse

Presumably to prevent the ransomware from being terminated or investigated, the encryption process attempts to disable the keyboard and mouse should the process run for 1,200 seconds (twenty minutes) (Figure 11).

Black Kingdom Ransomware_9

Figure 11 - Disable keyboard & mouse input during encryption

Whilst many hosts may have already completed the encryption process, it is theoretically possible that this time comparison could be missed due to it requiring the time elapsed to be exactly 1,200 seconds.

Making use of the Python 'pyHook' library, the keyboard and mouse hooking code resulting in input being disabled appear to be the same as a readily available example on a common developer forums, again suggesting that much of the ransomware code may be copied and pasted from other sources.

Post-processing

Encrypted File Rename

Unlike a common ransomware tactic of using a fixed identifying file extension, those behind this threat elected to append a random file extension, on a per file basis (Figure 12), of four to seven alphanumeric characters that could hamper efforts to quickly identify which files have been encrypted.

Black Kingdom Ransomware_10

Figure 12 - Example encrypted file extensions (Note the dropped ransom note)

Additionally, rather than renaming files after they have been successfully encrypted, each encryption attempt will result in the filename and file extension being appended to a list which is processed upon the conclusion of the entire encryption process.

Furthermore, this approach could result in two undesirable situations: Files failing the encryption process could still be renamed and, should the ransomware process terminate prematurely, encrypted files would not be renamed and therefore difficult to identify.

Ransom Note Dropper

Utilizing a similar method the the file rename process, each directory encountered is added to another list that, along with the ransom note filename decrypt_file.TxT, is looped through upon conclusion of the encryption process and results in the base-64 encoded ransom note being decoded and written to file, including the victim identifier, in each directory (Figure 13).

Black Kingdom Ransomware_11

Figure 13 - Creation of ransom notes in each directory

Log Clearance

As a penultimate task, the ransomware makes another attempt to thwart incident response efforts by clearing the Windows Application, Security and System logs (Figure 14) using functions provided by the Python library 'WinSys'.

Black Kingdom Ransomware_12

Figure 14 - Windows event logs cleared

Whilst the Application log will be completely clear upon the completion of this process, Security Event ID 1102 and System Event ID 104 are logged and will allow the time of infection to be determined.

Screen Lock

Having completed the encryption process and subsequent post-processing tasks, a final function is called which effectively locks the screen, using the same keyboard and mouse hooking function as before, and prominently displays the ransom note along with a 'time out' (Figure 15).

Black Kingdom Ransomware_0

Figure 15 - Ransom note window displayed at the conclusion of the encryption process

In an attempt to convey a sense of urgency to the victim, the timer will continue to count 'up' until forty-eight hours have elapsed after which the message Time expired: THE AMOUNT DOUBLED is displayed, albeit no other action is taken by the ransomware and this 'doubled ransom' would presumably only be enforced by the threat actor based on the time that they received the key file (if at all).

Recommendations

  • Business continuity and disaster recovery planning can help an organization be prepared for a ransomware 'worst-case scenario' by providing the ability to successfully restore data and recover from an attack.
  • In case of file encryption from the 22/3, we recommend to use the Proof of Concept script embedded in the appendix to perform file decryption.
  • Organizations with vulnerable Microsoft Exchange on-premise servers should assume breach and take immediate steps to implement Incident Response, our previous bulletin[2] and the regularly updated Microsoft article[4] provide further details of security updates along with Microsoft recommended mitigations.
  • Continuous monitoring of host security events and unusual behaviors, such as excessive file operations, high CPU usage due to SYSTEM privileged process can provide an early indication of compromise or nefarious activity.
  • Application permit and deny lists can be used detect and prevent the execution of an unauthorized or unknown executable, effectively hardening a host against attack.
  • Wherever possible, organizations should seek to remediate ransomware attacks rather than making ransom payments as these serve only to perpetuate the problem and fund further threat developments.

Indicators of Compromise

File Hashes (SHA256)

  • c25a5c14269c990c94a4a20443c4eb266318200e4d7927c163e0eaec4ede780a
  • 910fbfa8ef4ad7183c1b5bdd3c9fd1380e617ca0042b428873c48f71ddc857db
  • b9dbdf11da3630f464b8daace88e11c374a642e5082850e9f10a1b09d69ff04f
  • a387c3c5776ee1b61018eeb3408fa7fa7490915146078d65b95621315e8b4287
  • c4aa94c73a50b2deca0401f97e4202337e522be3df629b3ef91e706488b64908
  • 866b1f5c5edd9f01c5ba84d02e94ae7c1f9b2196af380eed1917e8fc21acbbdc
  • 910fbfa8ef4ad7183c1b5bdd3c9fd1380e617ca0042b428873c48f71ddc857db
  • fed02796762f63978094ad4b21b1952948cea78281abb55ba58bbb7886531ea1
  • e4d74735b0fe22e977c622d8bcd6de638ebbb71aaaace38a0a924fc514131e18

Email Addresses

  • support_blackkingdom2[@]protonmail.com

Bitcoin Wallets

  • 1Lf8ZzcEhhRiXpk6YNQFpCJcUisiXb34FT - 0.173 BTC, equivalent to $9.2k transaction from 18/3/21, which might be a ransom paying victim (ransom is $10k).

Ransom Note

Saved as decrypt_file.TxT in each directory except those that appear in the exclusion list.

***************************
| We Are Back ?
***************************

We hacked your (( Network )), and now all files, documents, images,
databases and other important data are safely encrypted using the strongest algorithms ever.
You cannot access any of your files or services .
But do not worry. You can restore everthing and get back business very soon ( depends on your actions )

before I tell how you can restore your data, you have to know certain things :

We have downloaded most of your data ( especially important data ) , and if you don't contact us within 2 days, your data will be released to the public.

To see what happens to those who didn't contact us, just google : ( Blackkingdom Ransomware )

***************************
| What guarantees ?
***************************

We understand your stress and anxiety. So you have a free opportunity to test our service by instantly decrypting one or two files for free
just send the files you want to decrypt to (support_blackkingdom2@protonmail.com

***************************************************
| How to contact us and recover all of your files ?
***************************************************

The only way to recover your files and protect from data leaks, is to purchase a unique private key for you that we only posses .

[ + ] Instructions:

1- Send the decrypt_file.txt file to the following email ===> support_blackkingdom2@protonmail.com

2- send the following amount of US dollars ( 10,000 ) worth of bitcoin to this address :

[ 1Lf8ZzcEhhRiXpk6YNQFpCJcUisiXb34FT ]

3- confirm your payment by sending the transfer url to our email address

4- After you submit the payment, the data will be removed from our servers, and the decoder will be given to you,
so that you can recover all your files.

## Note ##

Dear system administrators, do not think you can handle it on your own. Notify your supervisors as soon as possible.
By hiding the truth and not communicating with us, what happened will be published on social media and yet in news websites.

Your ID ==>

<VICTIM_ID [A-Za-z0-9]{20}>

References

[1] https://blog.cyberint.com/dearcry-ransomware-microsoft-exchange-exploited

[2] https://blog.cyberint.com/hafnium-microsoft-exchange-server-vulnerability-bulletin

[3] https://en.wikipedia.org/wiki/List_of_file_signatures

[4] https://github.com/microsoft/CSS-Exchange/tree/main/Security

Appendix A - Decryption PoC

# ▄████▄▓██ ██▓ ▄▄▄▄ ▓█████ ██▀███ ██▓ ███▄ █ ▄▄▄█████▓
#▒██▀ ▀█ ▒██ ██▒▓█████▄ ▓█ ▀ ▓██ ▒ ██▒▓██▒ ██ ▀█ █ ▓ ██▒ ▓▒
#▒▓█ ▄ ▒██ ██░▒██▒ ▄██▒███ ▓██ ░▄█ ▒▒██▒▓██ ▀█ ██▒▒ ▓██░ ▒░
#▒▓▓▄ ▄██▒░ ▐██▓░▒██░█▀ ▒▓█ ▄ ▒██▀▀█▄ ░██░▓██▒ ▐▌██▒░ ▓██▓ ░
#▒ ▓███▀ ░░ ██▒▓░░▓█ ▀█▓░▒████▒░██▓ ▒██▒░██░▒██░ ▓██░ ▒██▒ ░
# ░▒ ▒ ░ ██▒▒▒ ░▒▓███▀▒░░ ▒░ ░░ ▒▓ ░▒▓░░▓ ░ ▒░ ▒CYBERINT.COM
#
title1 = "Black KingDom Ransomware Decrypter POC"
title2 = "Cyberint Research - 26 March 2021 v0.1"
title3 = "--------------------------------------"
#
# Provided as a simple proof-of-concept to allow Blue Teamers to
# test data recovery in a safe environment. Decryption will make
# use of the failover key whilst reading the IV from each encrypted
# file. Decrypted data will be written to a new file.
#
# Code to crawl a disk and attempt the recovery of all files, as well
# as removing 0x00 padding and the encrypted file extension have been
# omitted for safety... add these at your own risk! ;)
#####
# THIS SCRIPT IS PROVIDED 'AS IS' FOR PROOF-OF-CONCEPT PURPOSES ONLY
# AND SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS OR DATA LOSS MAY
# OCCUR! ATTEMPTS TO DECRYPT DATA SHOULD BE CONDUCTED AGAINST BACKUPS
# IN A SAFE 'SECONDARY' ENVIRONMENT. NO WARRANTY EXPRESSED OR IMPLIED.
####

# Import the AES crypto module
from Crypto.Cipher import AES
# Import the sys module so we can grab the command-line arguments
import sys

# Defines the default key, as used when 'Mega' cannot be contacted...
# Those with huge computational resources may want to calculate MD5
# hashes for all permetations of [A-Z0-9]{64} to brute-force??
key = b'eebf143cf615ecbe2ede01527f8178b3'

# Decrypt function, requires the key, an IV and the encrypted data
def decrypt(key, iv, data):
# Setup the AES object, as defined in the ransomware code
aes = AES.new(key, AES.MODE_CBC, iv)
# Return the decrypted data
return aes.decrypt(data)

if len(sys.argv) > 1:
# We'll assume that you've supplied a valid path/filename
encrypted_file = sys.argv[1]
# Open this file for 'r'eading as a 'b'inary...
with open(encrypted_file, 'rb') as ef:
# Read the IV from the first 16 bytes
iv = ef.read(16)
# Now read the encrypted data that follows the IV
encrypted = ef.read()
# We'll name the file "<ENCRYPTED_FILENAME>.decrypted"
decrypted_file = '{}.decrypted'.format(sys.argv[1])
# Open this file for 'w'riting as 'b'inary...
with open(decrypted_file, 'wb') as df:
# Decrypt the data
decrypted = decrypt(key, iv, encrypted)
# Write the (hopefully) decrypted data to a new file
df.write(decrypted)
# Show a preview so we can see if it worked...
print("\n{}\n{}\n{}\nExtracted File IV : {}\nEncrypted Preview : {}\nDecrypted Preview : {}\n".format(title1, title2, title3, iv, encrypted[:16], decrypted[:16]))
else:
# Someone forgot to supply a filename!
print("\n{}\n{}\n{}\nUsage: python(3) <script.py> <encrypted_filename>\n".format(title1, title2, title3))