- Table of contents
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).
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).
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).
Figure 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).
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).
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.
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.
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).
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).
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).
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.
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).
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’.
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).
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))