跨平台 C2 代理,适用于 Mythic,支持动态函数加载、SOCKS5 代理、文件操作、shellcode 注入以及 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 值(通常来自 Mythic 的 .env 文件)。rabbitmq_host 设置为你的 RabbitMQ 主机/容器名称(在 docker-compose 设置中通常是 ,本地绑定则为 )。mythic_rabbitmq127.0.0.1mythic_server_host 设置为你的 Mythic 服务器主机/容器名称(在 docker-compose 设置中通常是 mythic_server,本地绑定则为 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 | 退出一个回调。 |
| 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] 中的文件和文件夹,或者使用 . 表示当前工作目录。 |
| mv | mv src_file_or_dir dst_file_or_dir | 将文件或文件夹移动到目标位置。 |
| pip_freeze | pip_freeze | 以编程方式列出系统上已安装的包。 |
| pty | pty [/bin/bash] / pty self / |
| 命令 | 语法 | 描述 |
|---|---|---|
| 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] | 列出 macOS TCC 数据库中的条目(需要完全磁盘访问,且目前仅限 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 | 使用 CreateRemoteThread 将 Shellcode 注入目标 PID(仅 Windows - 改编自此处)。 |
| load_dll | load_dll dll_path dll_export | 加载磁盘上的 DLL 并执行一个导出函数(注意:该 DLL 必须在完成时返回一个 int 值,例如 msfvenom 创建的 DLL 会在完成时杀死你的代理)。 |
| list_dlls | list_dlls [pid] | 读取本地或目标进程的进程内存(PEB)以获取加载的 DLL 列表(仅 Python 3)。 |
| ps | ps | 获取有限的进程信息,例如 PID、进程名称、架构和二进制路径(仅 Python 3)。 |
| ps_full | ps_full | 获取完整的进程信息,包括 PPID、完整性级别和命令行(仅 Python 3)。 |
| kill | kill | 按进程 ID 终止进程(仅 Python 3)。 |
Medusa 代理的两个版本都使用内置库实现的 AES256 HMAC 加密(改编自此处),从而消除了标准 Python 安装之外的任何额外依赖。因此,该代理应能在 Windows、Linux 和 macOS 主机上运行。值得一提的是,这种加密实现在处理大文件(截图、下载等)时会带来一些开销,但仍在可接受范围内。
在 Payload_Type/Medusa/agent_code 目录中,你会看到带有 py2 和 py3 后缀的 base_agent 文件。同样,单个功能文件也有类似的扩展名。
这些文件由 builder.py 脚本读取,首先选择 Medusa 代理的正确基础 Python 版本。然后 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 配置文件通过基本的非动态配置文件回连到 Mythic 服务器。GET 请求用于获取任务,POST 请求用于返回响应。
pty fork打开一个交互式 PTY 会话。模式:spawn 使用 PTY 运行程序,self 打开进程内 Python REPL 并保持代理状态,fork 将代理分叉成带有快照状态的 Python REPL(仅限 Linux/macOS)。 |
| rm | rm file_or_dir | 删除文件或文件夹。 |
| shell | shell [command] | 运行一个 shell 命令,该命令将使用 subprocess.Popen() 产生。注意,这将等待命令完成,因此请注意不要阻塞你的代理。 |
| socks | socks start/stop [port] | 通过 Medusa 代理启动/停止 SOCKS5 代理。 |
| sleep | sleep [seconds] [jitter percentage] | 设置代理的回调间隔(以秒为单位)。 |
| unload | unload command | 从代理中卸载现有能力。 |
| unload_module | unload_module module_name | 卸载先前加载到内存中的 Python 模块。 |
| upload | upload | 将文件上传到机器的远程路径。 |
| watch_dir | watch_dir path seconds | 监视目标目录中的更改,按指定速率轮询更改。 |