Подписка на блог

Customize in /user/extras/subscribe-sheet.tmpl.php.

Sample text.

Twitter, Facebook, VK icon VK, Telegram, LinkedIn, Odnoklassniki, Pinterest, РСС JSON Feed

Sample text.

Расцвет вредоносного ПО на Python

Вышла расчудесная статья про Python и вредоносное ПО от Austin Jackson. Особенно радуют ссылки! Побежал читать!

Далее приводится краткое содержание...

Подавляющее большинство серьезных вредоносных программ за последние 30 лет было написано на ассемблере или компилируемых языках, таких как C, C++ и Delphi. Об этом см. в статье A Look into 30 Years of Malware Development from a Software Metrics Perspective.

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

см. статью про рост популярности Python

см. статью Malware Against the C Monoculture

По сравнению со стандартным компилируемым языком, таким как C, написание вредоносных программ на Python сопряжено с целым рядом трудностей. Во-первых, Python должен быть установлен в ОС, чтобы интерпретировать и выполнять код. Скомпилированный пример вредоносного ПО, написанный на C, может составлять 200 КБ, тогда как сопоставимый пример вредоносного кода, написанный на Python, может весить 20 МБ после преобразования в исполняемый файл. Использование ЦП и ОЗУ также будет значительно выше при использовании интерпретируемого языка. Однако сейчас 2020 год, и цифровой ландшафт уже не тот, каким был когда-то. Интернет работает быстрее, чем когда-либо, наши компьютеры имеют больше памяти, чем когда-либо, а процессоры становятся быстрее с каждым годом. Python также более распространен, чем когда-либо, и по умолчанию поставляется в MacOS и большинстве дистрибутивов Linux.

Существует много способов «скомпилировать Python» в исполняемый файл.

PyInstaller способен создавать приложения на Python в виде автономных исполняемых файлов для Windows, Linux, MacOS и пр.

Давайте создадим простое «Привет, мир!» с помощью PyInstaller:

$ cat hello.py
print('Hello, world!')

$ pyinstaller --onefile hello.py
...

$ ./dist/hello 
Hello, world!

$ file dist/hello 
dist/hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=294d1f19a085a730da19a6c55788ec08c2187039, stripped

$ du -sh dist/hello 
7.0M    dist/hello

Создали автономный Linux ELF. Теперь создадим и скомпилируем на C для сравнения:

$ cat hello.c
#include <stdio.h>
int main() {
    printf("Hello, world!");
}

$ gcc hello.c -o hello

$ ./hello 
Hello, world!

$ file hello
hello: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=480c7c75e09c169ab25d1b81bd28f66fde08da7c, for GNU/Linux 3.2.0, not stripped

$ du -sh hello
20K hello

Обратите внимание, насколько больше размер файла: 7 МБ (Python) против 20 КБ (C)! Исполняемый файл Python намного больше из-за того, что для запуска он должен включать интерпретатор (как объектный файл в Linux) внутри самого исполняемого файла.

py2exe — еще один популярный метод для преобразования кода Python в формат EXE, который можно запускать изначально.

Nuitka — более продвинутый метод компиляции кода Python в исполняемый файл. Он переводит код Python в программу на C, которая затем связывается с libpython для выполнения кода, аналогичного CPython. Nuitka может использовать различные компиляторы C, включая gcc, clang, MinGW64, Visual Studio 2019+ и clang-cl, чтобы преобразовать код Python в C.

Создадим «Привет, мир!» с помощью Nuitka:

$ cat hello.py
print('Hello, world!')

$ nuitka3 hello.py
...

$ ./hello.bin
Hello, world!

$ file hello.bin 
hello.bin: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=eb6a504e8922f8983b23ce6e82c45a907c6ebadf, for GNU/Linux 3.2.0, stripped

$ du -sh hello.bin
432K    hello.bin

Nuitka создала переносимый двоичный файл (432 КБ).
Давайте посмотрим на папку сборки:

$ cloc hello.build/
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               11           2263            709           8109
C/C++ Header                     1              1              0              7
-------------------------------------------------------------------------------
SUM:                            12           2264            709           8116
-------------------------------------------------------------------------------

Nuitka создала более 8000 строк кода на C из однострочной Python-программы! 0_o

Уже существует несколько инструментов для простого анализа двоичных файлов, созданных PyInstaller и py2exe для восстановления исходного кода Python. Благодаря переводу кода Python на C Nuitka гораздо сложнее выполнить RE.

Рассмотрим три простых, но мощных примера инструментов упрощающих написание malware на Python:
— Обфускация кода
— Создание скриншотов
— Выполнение веб-запросов

1) Обфускация кода: pyminifier и pyarmor.

Вот небольшой пример того, как с помощью pyarmor можно запутать код на Python:

$ cat hello.py 
print('Hello, world!')

$ pyarmor obfuscate hello.py
...

$ cat dist/hello.py
from pytransform import pyarmor_runtime
pyarmor_runtime()
__pyarmor__(__name__, __file__, b'\x50\x59\x41\x52\x4d\x4f\x52\x00\x00\x03\x08\x00\x55\x0d\x0d\x0a\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x40\x00\x00\x00\xd5\x00\x00\x00\x00\x00\x00\x18\xf4\x63\x79\xf6\xaa\xd7\xbd\xc8\x85\x25\x4e\x4f\xa6\x80\x72\x9f\x00\x00\x00\x00\x00\x00\x00\x00\xec\x50\x8c\x64\x26\x42\xd6\x01\x10\x54\xca\x9c\xb6\x30\x82\x05\xb8\x63\x3f\xb0\x96\xb1\x97\x0b\xc1\x49\xc9\x47\x86\x55\x61\x93\x75\xa2\xc2\x8c\xb7\x13\x87\xff\x31\x46\xa5\x29\x41\x9d\xdf\x32\xed\x7a\xb9\xa0\xe1\x9a\x50\x4a\x65\x25\xdb\xbe\x1b\xb6\xcd\xd4\xe7\xc2\x97\x35\xd3\x3e\xd3\xd0\x74\xb8\xd5\xab\x48\xd3\x05\x29\x5e\x31\xcf\x3f\xd3\x51\x78\x13\xbc\xb3\x3e\x63\x62\xca\x05\xfb\xac\xed\xfa\xc1\xe3\xb8\xa2\xaa\xfb\xaa\xbb\xb5\x92\x19\x73\xf0\x78\xe4\x9f\xb0\x1c\x7a\x1c\x0c\x6a\xa7\x8b\x19\x38\x37\x7f\x16\xe8\x61\x41\x68\xef\x6a\x96\x3f\x68\x2b\xb7\xec\x60\x39\x51\xa3\xfc\xbd\x65\xdb\xb8\xff\x39\xfe\xc0\x3d\x16\x51\x7f\xc9\x7f\x8b\xbd\x88\x80\x92\xfe\xe1\x23\x61\xd0\xf1\xd3\xf8\xfa\xce\x86\x92\x6d\x4d\xd7\x69\x50\x8b\xf1\x09\x31\xcc\x19\x15\xef\x37\x12\xd4\xbd\x3d\x0d\x6e\xbb\x28\x3e\xac\xbb\xc4\xdb\x98\xb5\x85\xa6\x19\x11\x74\xe9\xab\xdf', 1)

$ python dist/hello.py
Hello, world!

2) Создание скриншотов: pyscreenshot и python-mss.

Скриншот можно легко сделать в python-mss следующим образом:

from mss import mss

with mss() as sct:
    sct.shot()

3) Выполнение веб-запросов: requests и httpx.

Вредоносное ПО часто выполняет веб-запросы для веб-управления и контроля (command & control, C2), получения внешнего IP-адреса, загрузки полезной нагрузки и пр.

Внешний IP-адрес скомпрометированной конечной точки можно получить с помощью следующего запроса:

import requests
external_ip = requests.get('http://whatismyip.akamai.com/').text

Про eval

eval — встроенная в Python функция, считается очень опасной, поскольку представляет серьезную угрозу безопасности при использовании в продакшене.

eval() может использоваться для выполнения Python кода внутри самой Python программы. Это способность позволяет запускать высокоуровневые скрипты или «плагины» на лету. Это похоже на случай, когда вредоносная программа на C включает в себя механизм сценариев Lua, чтобы дать вредоносной программе возможность выполнять Lua сценарии (см. описание Flame. Вредоносное ПО на Python может быть эффективно размещено на атакуемой машине, а «возможности» могут выполняться по мере необходимости, чтобы оставаться скрытыми.

Примеры вредоносных программ на Python

SeaDuke

SeaDuke — наиболее известное вредоносное ПО, где используется Python. В течение 2015 и 2016 гг. Национальный комитет Демократической партии США был атакован двумя группами APT 28 & 29.

Анализ SeaDuke был проведен Отделом 42 Пало-Альто (Palo Alto’s Unit 42). Декомпилированный исходный код можно найти здесь.

F-Secure опубликовала технический документ о вредоносных программах Duke, который охватывает SeaDuke и связанное ПО.

SeaDuke — это троян на Python, завернутый в EXE с помощью PyInstaller, упакован в UPX. Исходный код Python был обфуцирован. Вредоносная программа имела множество возможностей, в том числе несколько способов сокрытия в Windows, кроссплатформенность и выполнение веб-запросов для управления и контроля.

PWOBot

PWOBot — это вредоносное ПО на Python, похожее на SeaDuke, скомпилирована с помощью PyInstaller в исполняемый файл Windows. Распространен в течение 2013-2015 годов и затронул несколько европейских организаций, в основном в Польше. Вредоносная программа была полнофункциональной и включала в себя возможность регистрировать нажатия клавиш, скрываться в Windows, загружать и выполнять файлы, выполнять код Python, выполнять веб-запросы и анализировать криптовалюту. Анализ PWOBot был проведен Отделом 42 Пало-Альто.

PyLocky

PyLocky — это вымогатель на основе Python, скомпилированный с PyInstaller в исполняемый файл Windows. Он был нацелен на несколько разных стран, включая США, Францию, Италию и Корею. Он включал возможности защиты от песочницы, командование и управление, а также шифрование файлов с использованием 3DES (Triple DES).

Trend Micro провел анализ PyLocky. Аналитики Talos Intelligence смогли создать расшифровщик.

PoetRAT

PoetRAT — это троян на основе Python, предназначенный для правительства и энергетического сектора Азербайджана в начале 2020 года. Троян определяет системы и похищает информацию, связанную с ICS / SCADA, управляющими ветровыми турбинами.

Вредоносное ПО попадало с помощью зараженных документов MS Word. RAT имел множество возможностей для кражи информации, включая извлечение файлов по FTP, съемку изображений с веб-камер, загрузку дополнительных инструментов, ведение журнала ключей, определение браузера и кражу учетных данных. Talos Intelligence сообщила об этой деятельности и произвела подробный разбор.

Открытое ПО

Доступно несколько открытых RAT троянов, таких как pupy и Stitch. Эти трояны показывают, насколько сложным и многофункциональным может быть вредоносное ПО на Python!

Инструменты анализа вредоносного ПО

uncompyle6

uncompyle6 является кросс-версией декомпилятора кода на Python. Его можно использовать для перевода байт-кода Python обратно в исходный код.

Например, программа «Привет, мир!» представлена в виде .pyc (байт-код).
Мы можем восстановить исходный код скрипта, используя uncompyle:

$ xxd hello.cpython-38.pyc 
00000000: 550d 0d0a 0000 0000 16f3 075f 1700 0000  U.........._....
00000010: e300 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0002 0000 0040 0000 0073 0c00 0000 6500  .....@...s....e.
00000030: 6400 8301 0100 6401 5300 2902 7a0d 4865  d.....d.S.).z.He
00000040: 6c6c 6f2c 2077 6f72 6c64 214e 2901 da05  llo, world!N)...
00000050: 7072 696e 74a9 0072 0200 0000 7202 0000  print..r....r...
00000060: 00fa 2d2f 686f 6d65 2f75 7365 722f 746d  ..-/home/user/tm
00000070: 702f 7079 7468 6f6e 5f61 7274 6963 6c65  p/python_article
00000080: 2f6e 2f74 6573 742f 6865 6c6c 6f2e 7079  /n/test/hello.py
00000090: da08 3c6d 6f64 756c 653e 0100 0000 f300  ..<module>......
000000a0: 0000 00

$ uncompyle6 hello.cpython-38.pyc | grep -v '#'
print('Hello, world!')

pyinstxtractor.py (PyInstaller Extractor)

PyInstaller Extractor может извлекать данные из скомпилированных с помощью PyInstaller исполняемых файлов:

> python pyinstxtractor.py hello.exe
...

Появится .pyc, которые затем можно восстановить в uncompyle6.

python-exe-unpacker

Сценарий unpack.py можно использовать для распаковки и декомпиляции исполняемых файлов, созданных с помощью py2exe:

> python python_exe_unpack.py -i hello.exe
...

Как обнаружить скомпилированный Python код?

PyInstaller и py2exe при компиляции в Windows помещают уникальные строки в двоичный исполняемый файл. Это означает, что их можно обнаружить с помощью YARA правил.

PyInstaller записывает строку «pyi-windows-manifest-filename» в конце исполняемого файла, вы можете увидеть ее здесь в шестнадцатеричном редакторе (HxD):

YARA правило для обнаружения скомпилированных исполняемых файлов PyInstaller (исходный код):

import "pe"

rule PE_File_pyinstaller
{
    meta:
        author = "Didier Stevens (https://DidierStevens.com)"
        description = "Detect PE file produced by pyinstaller"
    strings:
        $a = "pyi-windows-manifest-filename"
    condition:
        pe.number_of_resources > 0 and $a
}

Второе YARA правило для обнаружения скомпилированных исполняемых файлов py2exe (исходный код):

import "pe"

rule py2exe
{
  meta:
        author = "Didier Stevens (https://www.nviso.be)"
        description = "Detect PE file produced by py2exe"
  condition:
        for any i in (0 .. pe.number_of_resources - 1):
          (pe.resources[i].type_string == "P\x00Y\x00T\x00H\x00O\x00N\x00S\x00C\x00R\x00I\x00P\x00T\x00")
}

Вот такие дела.

Дополнительные материалы:

  1. GrrCON 2019
  2. Destroy Everything. Tom Somerville
  3. Обсуждение статьи
  4. Подкаст
  5. The Backdoor Factory
  6. Malware writing — Python malware, part 1
Подписаться на блог
Поделиться
Отправить
Запинить
 42   20 дн   Infosec   malware   Python   Security
Популярное