Кроссплатформенный C2-агент для Mythic с динамической загрузкой функций, SOCKS5-прокси, файловыми операциями, внедрением шеллкода и модулями постэксплуатации для macOS/Windows.
Medusa — это кроссплатформенный агент, совместимый как с Python 3.8, так и с Python 2.7.
Для установки Medusa вам понадобится Mythic v3, установленный на удалённом компьютере. Инструкции по установке Mythic вы можете найти на странице проекта Mythic.
Из корневого каталога установки Mythic выполните команду:
./mythic-cli install github https://github.com/MythicAgents/Medusa.git
После установки перезапустите Mythic, чтобы собрать нового агента.
Файл Payload_Type/medusa/rabbitmq_config.json является шаблоном и должен соответствовать вашему окружению Mythic.
rabbitmq_password в значение вашего Mythic RABBITMQ_PASSWORD (обычно из .env файла Mythic).rabbitmq_host в имя хоста/контейнера RabbitMQ (часто mythic_rabbitmq в docker-compose конфигурациях или 127.0.0.1 для локальных привязок).mythic_server_host в имя хоста/контейнера сервера Mythic (часто mythic_server в docker-compose конфигурациях или 127.0.0.1 для локальных привязок).Базовый агент и все включённые команды используют встроенные библиотеки Python, поэтому для их работы не требуются дополнительные пакеты. Агенты выполняют команды в потоках, поэтому длительные загрузки или скачивания не блокируют основной агент.
| Команда | Синтаксис | Описание |
|---|---|---|
| cat | cat path/to/file | Прочитать и вывести содержимое файла. |
| cd | cd [.. dir] | Сменить рабочую директорию (.. — переход на одну директорию вверх). |
| cp | cp src_file_or_dir dst_file_or_dir | Скопировать файл или папку в указанное место. |
| cwd | cwd | Вывести рабочую директорию. |
| download | download [path] | Скачать файл с целевой системы. |
| download_bulk | download_bulk [path1] [path2] ... | Скачать несколько файлов с целевой системы одной задачей. |
| exit | exit | Завершить callback. |
| env | env | Вывести переменные окружения. |
| eval_code | eval_code [commands] | Выполнить Python-код и вернуть результат. |
| jobkill | jobkill [task id] | Отправить сигнал остановки длительной задаче. |
| jobs | jobs | Список длительных задач, например, скачиваний. |
| list_modules | list_modules [module_name] | Список модулей в памяти или полный список файлов для конкретного модуля. |
| load | load command | Загрузить новую возможность в агента. |
| load_module | load_module | Загрузить заархивированный Python-модуль в память (адаптировано из этого и этого). |
| load_script | load_script | Загрузить и выполнить Python-скрипт через агента. |
| ls | ls [. path] | Список файлов и папок в [path] или используйте . для текущей рабочей директории. |
| Команда | Синтаксис | Описание |
|---|---|---|
| clipboard | clipboard | Вывести содержимое буфера обмена (использует Objective-C API, как описано Cedric Owens здесь. Только macOS, только Python 2.7). |
| list_apps | list_apps | Список приложений macOS (только Python 2.7, только macOS). |
| list_tcc | list_tcc [path] | Список записей в базе данных TCC macOS (требуется полный доступ к диску, пока только Big Sur). |
| screenshot | screenshot | Сделать скриншот (использует Objective-C API, только macOS, только Python 2.7). |
| spawn_jxa | spawn_jxa | Запустить процесс osascript и передать в него Javascript-содержимое. |
| vscode_list_recent | vscode_list_recent [state_db] | Список файлов и папок, недавно открытых в VSCode. |
| vscode_open_edits | vscode_open_edits [backup_dir_path] | Список несохранённых изменений в файлах VSCode. |
| vscode_watch_edits | vscode_watch_edits [path to remote dir] [poll_interval] | Опрашивать директорию резервных копий VSCode с заданным интервалом для поиска несохранённых изменений. |
| Команда | Синтаксис | Описание |
|---|---|---|
| shinject | shinject | Внедрить шеллкод в целевой PID с помощью CreateRemoteThread (только Windows — адаптировано из этого). |
| load_dll | load_dll dll_path dll_export | Загрузить DLL с диска и выполнить экспортируемую функцию (ВНИМАНИЕ: эта DLL должна возвращать целочисленное значение по завершении; например, DLL, созданная через msfvenom, убьёт вашего агента по завершении). |
| list_dlls | list_dlls [pid] | Прочитать память процесса (PEB) локального или целевого процесса, чтобы получить список загруженных DLL (только Python 3). |
| ps | ps | Получить ограниченную информацию о процессах, например, PID, имена процессов, архитектуру и пути к бинарным файлам (только Python 3). |
| ps_full | ps_full | Получить полную информацию о процессах, включая PPID, уровень целостности и командную строку (только Python 3). |
| kill | kill | Завершить процесс по идентификатору процесса (только Python 3). |
Обе версии агента Medusa используют реализацию AES256 HMAC, написанную на встроенных библиотеках (адаптировано из этого), что устраняет необходимость в каких-либо дополнительных зависимостях помимо стандартной установки Python. Таким образом, агент должен работать на хостах Windows, Linux и macOS. Стоит отметить, что эта криптографическая реализация добавляет некоторые накладные расходы при работе с большими файлами (скриншоты, скачивания и т.д.), но это приемлемо.
В директории Payload_Type/Medusa/agent_code вы увидите файлы base_agent с суффиксами py2 и py3. Аналогичные расширения файлов можно увидеть и для отдельных файлов функций.
Скрипт builder.py считывает их, чтобы сначала выбрать правильную базовую версию Python для агента Medusa. Затем builder.py включит команды, специфичные для выбранной версии Python. Если команда имеет только расширение .py, она будет использоваться по умолчанию, исходя из предположения, что для версий Py2 и Py3 не нужен альтернативный код.
Medusa использует базовую многопоточность для выполнения задач. Если задачи потенциально длительные, их можно реализовать с «проверкой остановки» для реагирования на сигнал от задачи jobkill. Это можно реализовать с помощью фрагмента кода, похожего на показанный ниже:
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]:
# Некоторое специфичное для задачи завершение
return "Job stopped."
Этот обработчик можно увидеть реализованным в командах download, upload, watch_dir и screenshot.
Кроме того, если длительная задача должна выдавать непрерывный вывод, функция sendTaskOutputUpdate, включённая в базовый агент, может использоваться для обновления Mythic до завершения задачи. Ниже показана фиктивная функция, которая выдаёт непрерывный вывод и может быть остановлена через jobkill.
def dummyFunction(self, task_id):
while(True):
# Проверяем, не получили ли сигнал остановки.
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]: return "Job stopped."
# Отправляем вывод обратно в Mythic
self.sendTaskOutputUpdate(task_id, "We're still running")
time.sleep(10)
Medusa в настоящее время поддерживает два C2-профиля: http (как с шифрованием AES256 HMAC, так и без него) и azure_blob.
HTTP-профиль выполняет callback на сервер Mythic через базовый, нединамический профиль. GET-запросы для получения задач, POST-запросы с ответами.
| mv | mv src_file_or_dir dst_file_or_dir | Переместить файл или папку в указанное место. |
| pip_freeze | pip_freeze | Программно вывести список установленных пакетов в системе. |
| pty | pty [/bin/bash] / pty self / pty fork | Открыть интерактивную PTY-сессию. Режимы: spawn запускает программу с PTY, self открывает внутрипроцессный Python REPL с живым состоянием агента, fork форкает агента в Python REPL со снимком состояния (только Linux/macOS). |
| rm | rm file_or_dir | Удалить файл или папку. |
| shell | shell [command] | Выполнить команду оболочки, которая будет запущена с помощью subprocess.Popen(). Обратите внимание, что команда будет ждать завершения, так что будьте осторожны и не блокируйте агента. |
| socks | socks start/stop [port] | Запустить/остановить SOCKS5 прокси через агента Medusa. |
| sleep | sleep [seconds] [jitter percentage] | Установить интервал callback агента в секундах. |
| unload | unload command | Выгрузить существующую возможность из агента. |
| unload_module | unload_module module_name | Выгрузить Python-модуль, ранее загруженный в память. |
| upload | upload | Загрузить файл в удалённый путь на машине. |
| watch_dir | watch_dir path seconds | Отслеживать изменения в целевой директории с заданной периодичностью опроса. |