
Agente C2 multiplataforma para Mythic con carga dinámica de funciones, proxy SOCKS5, operaciones de archivos, inyección de shellcode y módulos de post-explotación para macOS/Windows.
Medusa es un agente multiplataforma compatible con Python 3.8 y Python 2.7.
Para instalar Medusa, necesitarás tener Mythic v3 instalado en una computadora remota. Puedes encontrar las instrucciones de instalación de Mythic en la página del proyecto Mythic.
Desde la raíz de instalación de Mythic, ejecuta el comando:
./mythic-cli install github https://github.com/MythicAgents/Medusa.git
Una vez instalado, reinicia Mythic para compilar un nuevo agente.
El archivo Payload_Type/medusa/rabbitmq_config.json es una plantilla y debe coincidir con tu entorno de Mythic.
rabbitmq_password con el valor de RABBITMQ_PASSWORD de tu Mythic (normalmente desde el .env de Mythic).rabbitmq_host con el nombre de tu host/contenedor RabbitMQ (a menudo mythic_rabbitmq en configuraciones docker-compose, o 127.0.0.1 para enlaces locales).mythic_server_host con el nombre de tu host/contenedor del servidor Mythic (a menudo mythic_server en configuraciones docker-compose, o 127.0.0.1 para enlaces locales).El agente base y los comandos incluidos usan librerías Python integradas, por lo que no necesitan paquetes adicionales para funcionar. Los agentes ejecutan los comandos en subprocesos, por lo que las subidas o descargas de larga duración no bloquearán al agente principal.
Ambas versiones del agente Medusa usan una implementación AES256 HMAC escrita con librerías integradas (adaptada de aquí), lo que elimina la necesidad de dependencias adicionales más allá de una instalación estándar de Python. Como tal, el agente debería funcionar en hosts Windows, Linux y macOS. Vale la pena mencionar que esta implementación criptográfica introduce cierta sobrecarga al manejar archivos grandes (capturas de pantalla, descargas, etc.), pero es manejable.
Dentro del directorio Payload_Type/Medusa/agent_code, verás archivos base_agent con sufijos py2 y py3. Del mismo modo, se pueden ver extensiones similares en los archivos de funciones individuales.
builder.py los lee para seleccionar primero la versión base correcta de Python del agente Medusa. Luego, builder.py incluirá comandos específicos de la versión de Python elegida. En el caso de que un comando solo tenga la extensión .py, se usará por defecto, asumiendo que no se necesita código alternativo entre las versiones Py2 y Py3.
Medusa usa subprocesos básicos para la ejecución de trabajos. Cuando los trabajos pueden ser de larga duración, se pueden implementar con una 'comprobación de detención' para responder a una señal de la tarea jobkill. Esto se puede implementar con un fragmento de código similar al que se muestra a continuación:
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]:
# Some job-specific tidy up
return "Job stopped."
Este manejador se puede ver implementado dentro de los comandos download, upload, watch_dir y screenshot.
Además, si se espera que el trabajo de larga duración proporcione una salida continua, la función sendTaskOutputUpdate (incluida en el agente base) se puede usar para actualizar Mythic antes de que finalice la tarea. A continuación se puede ver una función dummy que proporciona salida continua y a la que se le puede aplicar jobkill.
def dummyFunction(self, task_id):
while(True):
# Check if we've got a stop signal.
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]: return "Job stopped."
# Send output back to Mythic
self.sendTaskOutputUpdate(task_id, "We're still running")
time.sleep(10)
Medusa actualmente es compatible con dos perfiles C2: http (con y sin cifrado AES256 HMAC) y azure_blob.
El perfil HTTP se comunica con el servidor Mythic mediante el perfil básico no dinámico. Solicitudes GET para tareas, solicitudes POST con respuestas.
| Comando | Sintaxis | Descripción |
|---|
| cat | cat path/to/file | Lee y muestra el contenido de un archivo. |
| cd | cd [.. dir] | Cambia el directorio de trabajo (.. para subir un directorio). |
| cp | cp src_file_or_dir dst_file_or_dir | Copia un archivo o carpeta a un destino. |
| cwd | cwd | Muestra el directorio de trabajo. |
| download | download [path] | Descarga un archivo del sistema objetivo. |
| download_bulk | download_bulk [path1] [path2] ... | Descarga varios archivos del sistema objetivo en una sola tarea. |
| exit | exit | Sale de un callback. |
| env | env | Muestra las variables de entorno. |
| eval_code | eval_code [commands] | Ejecuta código Python y devuelve la salida. |
| jobkill | jobkill [task id] | Envía una señal de detención a una tarea de larga duración. |
| jobs | jobs | Lista las tareas de larga duración, como descargas. |
| list_modules | list_modules [module_name] | Lista los módulos en memoria o el listado completo de archivos de un módulo específico. |
| load | load command | Carga una nueva capacidad en un agente. |
| load_module | load_module | Carga un módulo Python empaquetado en ZIP en memoria (adaptado de aquí y aquí). |
| load_script | load_script | Carga y ejecuta un script de Python a través del agente. |
| ls | ls [. path] | Lista archivos y carpetas en [path] o usa . para el directorio de trabajo actual. |
| mv | mv src_file_or_dir dst_file_or_dir | Mueve un archivo o carpeta a un destino. |
| pip_freeze | pip_freeze | Lista mediante programación los paquetes instalados en el sistema. |
| pty | pty [/bin/bash] / pty self / pty fork | Abre una sesión PTY interactiva. Modos: spawn ejecuta un programa con una PTY, self abre un REPL de Python en el proceso con el estado del agente en vivo, fork bifurca el agente en un REPL de Python con el estado capturado (solo Linux/macOS). |
| rm | rm file_or_dir | Elimina un archivo o carpeta. |
| shell | shell [command] | Ejecuta un comando de shell que se lanzará mediante subprocess.Popen(). Ten en cuenta que esperará a que el comando termine, así que ten cuidado de no bloquear tu agente. |
| socks | socks start/stop [port] | Inicia/detiene el proxy SOCKS5 a través del agente Medusa. |
| sleep | sleep [seconds] [jitter percentage] | Establece el intervalo de callback del agente en segundos. |
| unload | unload command | Descarga una capacidad existente de un agente. |
| unload_module | unload_module module_name | Descarga un módulo Python previamente cargado en memoria. |
| upload | upload | Sube un archivo a una ruta remota en la máquina. |
| watch_dir | watch_dir path seconds | Vigila los cambios en el directorio objetivo, consultando cambios a una velocidad especificada. |
| Comando | Sintaxis | Descripción |
|---|
| clipboard | clipboard | Muestra el contenido del portapapeles (usa la API de Objective-C, según lo descrito por Cedric Owens aquí. Solo macOS, solo Python 2.7). |
| list_apps | list_apps | Lista las aplicaciones de macOS (solo Python 2.7, solo macOS). |
| list_tcc | list_tcc [path] | Lista las entradas de la base de datos TCC de macOS (requiere acceso total al disco y solo Big Sur por ahora). |
| screenshot | screenshot | Toma una captura de pantalla (usa la API de Objective-C, solo macOS, solo Python 2.7). |
| spawn_jxa | spawn_jxa | Lanza un proceso osascript y envía contenido JavaScript a través de una tubería. |
| vscode_list_recent | vscode_list_recent [state_db] | Lista los archivos y carpetas abiertos recientemente con VSCode. |
| vscode_open_edits | vscode_open_edits [backup_dir_path] | Lista los cambios no guardados realizados en archivos de VSCode. |
| vscode_watch_edits | vscode_watch_edits [path to remote dir] [poll_interval] | Consulta el directorio de respaldos de VSCode a un intervalo dado en busca de cambios no guardados. |
| Comando | Sintaxis | Descripción |
|---|
| shinject | shinject | Inyecta shellcode en el PID objetivo mediante CreateRemoteThread (solo Windows - adaptado de aquí). |
| load_dll | load_dll dll_path dll_export | Carga una DLL del disco y ejecuta una función exportada (NOTA: Esta DLL debe devolver un valor int al finalizar; por ejemplo, una DLL creada con msfvenom matará a tu agente al completarse). |
| list_dlls | list_dlls [pid] | Lee la memoria del proceso (PEB) local o objetivo para obtener la lista de DLL cargadas (solo Python 3). |
| ps | ps | Obtiene información limitada del proceso, p. ej., PID, nombres de proceso, arquitectura y rutas de binarios (solo Python 3). |
| ps_full | ps_full | Obtiene información completa del proceso, incluidos PPID, nivel de integridad y línea de comandos (solo Python 3). |
| kill | kill | Termina un proceso por su ID de proceso (solo Python 3). |