PythonRat IOCs

remote access Trojan

CERT-AgID, действуя на основании отчета команды Malware Hunter Team (MHT), которая недавно опубликовала твит о полезной нагрузке, отслеженной на итальянском сайте (также подхваченной итальянским исследователем JamesWT), проанализировала содержимое вредоносного кода.

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

Согласно информации, также предоставленной MHT, кампания использует ZIP-файл с CHM-файлом внутри для запуска обратной оболочки в powershell.

PythonRat

Файл, загруженный с итальянского домена, zohoservice.exe, является PE. Быстрый анализ с помощью команды strings показывает, что перед нами исполняемый файл, разработанный с помощью Python:

Строка _PYI_ONEDIR_MODE типична для PyInstaller. После определения типа исполняемого файла остается только извлечь файлы с байткодом Python.

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

Этот файл может быть декомпилирован с помощью decompyle3.

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

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

Первый уровень обфускации довольно прост: он включает декодирование из base64. Полученный код, однако, более сложен.

Отметим, что определена лямбда-функция с именем _, которая принимает на вход строку (и число). Строка делится на слова, каждое слово преобразуется в число, делится на случайное число (_______ - это имя, используемое для импорта случайного числа) и результат преобразуется в символ. Затем все символы объединяются в строку.

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

Давайте начнем с анализа следующего блока кода:

Сразу видно, что ''.join(chr(i) for i in [101,120,101,99]) - это строка 'exec'. eval('exec') просто преобразовывается в exec, поэтому приведенный выше код не делает ничего, кроме выполнения закодированной строки. Их можно декодировать с помощью Cyberchef, чтобы получить код в виде обычного текста:

Этот код не делает ничего, кроме присвоения нечитаемых псевдонимов функциям print, exec и eval.

Затем следует строка чисел, которая, вероятно, содержит следующий этап и будет расшифрована лямбдой с именем _.

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

Мы можем сразу же декодировать строки. Помня, что ____ - это псевдоним для eval, мы можем удалить некоторые вложенные eval/exec, чтобы получить результат:

Мы видим, что сначала декодируется base64, затем распаковывается с помощью ZLIB, к нему применяется декодирование ROT13, а затем окончательное декодирование из base64. Cyberchef снова помогает нам быстро выполнить эти операции, чтобы получить следующий код:

Обратите внимание на важный вызов random.seed (_______ - это псевдоним random). Задавая определенный seed, последовательность генерируемых значений всегда будет одинаковой. Это позволит лямбда-функции, рассмотренной выше, декодировать следующий этап.

Семя декодируется точно так же, как и последний блок кода, и имеет значение 187753564038212036. Выражение why+you+are+reading+this+huh+thing сводится к строке, которая вызывает и выполняет _(__), то есть следующий этап.

Затем мы можем написать простой сценарий для его декодирования.

Полученный код является настоящим RAT. Исходный код приведен ниже.

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

Код RAT немедленно начинает соединение с C2, но на порту 8879, и ждет команды start. Пока он ее не получит, он будет посылать на C2 строку gg (good game?).

После запуска RAT снова свяжется с C2, но уже по настроенному порту и будет ждать команды. Код находится внутри функции управления и очень прост для чтения, поэтому ниже мы перечислим только поддерживаемые команды и их функциональность.

  • exit Завершает соединение с C2, но не завершает RAT. Атакующий может возобновить соединение, повторно отправив команду start, показанную ранее.
  • shell Эмулирует командный интерпретатор (а не оболочку). Позволяет просматривать каталоги и вызывать произвольные программы/команды.
  • keylogger Запускает кейлоггер. Данные сохраняются в %APPDATA%\Roaming\keylogs.txt. Использует клавиатурный модуль Python.
  • keyblock_start Запускает кейлоггер.
  • keyblock_stop Приостанавливает работу кейлоггера.
  • reboot Перезагружает машину
  • shutdown Выключает машину
  • screenshot Отправляет снимок экрана на C2.
  • persistence Сбрасывает ключ запуска для persistence
  • screenshare Запускает прямую трансляцию экрана на C2.
  • sysinfo Отправляет общее описание машины на C2. Содержит: Публичный IP, имя машины, имя ОС, процессор
  • download Отправляет C2 произвольный файл, выбранный злоумышленниками

Существует множество проектов RAT, написанных на Python и доступных на платформе Github, но наиболее близким к коду, использованному в этой кампании, является Python-RAT.

Все 12 команд, упомянутых выше, присутствуют в проекте Python-RAT, который на самом деле содержит более 40 из них, функции и структура кода похожи, несмотря на то, что некоторые переменные были переименованы (например, command в cmd).

Indicators of Compromise

IPv4

  • 45.82.69.203

URLs

  • http://45.82.69.203/st.ps1
  • https://lucaagostini.it/regallo/
  • https://lucaagostini.it/regallo/zohoservice.exe

MD5

  • 8a419e45e6ece666f5529299d8497bb8
  • 952d6923f15c2fc764d4e577d42f0512
  • c1a31c3594d1f94983b79784dfc9d9aa

SHA1

  • 4ef8daa7c7afe763f05e45997cc55b6eab21dfa2
  • 5d444d42ef461af0e26ff9d4c2345ff8d70c3065
  • cfb2f7d68c49c4faa387fd57552c752c8961dc77

SHA256

  • 3035ab2a9c83b4fb5159981c8ccd159b300a28b91e45e7b38793407d243dc9d3
  • 3a8191685b0dbd44b12051ab53a21c6f1f4969bba7d759b3d3497cc05ce7bfad
  • 7f482c7d24e7191746061169e8bb9d329026638be072bf4526a2509b34ccf32c
Комментарии: 0