Agent C2 multiplateforme pour Mythic avec chargement dynamique de fonctions, proxy SOCKS5, opérations sur fichiers, injection de shellcode et modules de post-exploitation macOS/Windows.
Medusa est un agent multiplateforme compatible avec Python 3.8 et Python 2.7.
Pour installer Medusa, vous devez avoir Mythic v3 installé sur une machine distante. Vous trouverez les instructions d'installation de Mythic sur la page du projet Mythic.
Depuis la racine d'installation de Mythic, exécutez la commande :
./mythic-cli install github https://github.com/MythicAgents/Medusa.git
Une fois installé, redémarrez Mythic pour construire un nouvel agent.
Le fichier Payload_Type/medusa/rabbitmq_config.json est un modèle et doit correspondre à votre environnement Mythic.
rabbitmq_password sur la valeur de votre RABBITMQ_PASSWORD Mythic (généralement dans le fichier de Mythic)..envrabbitmq_host sur le nom de votre hôte/conteneur RabbitMQ (souvent mythic_rabbitmq dans les configurations docker-compose, ou 127.0.0.1 pour les liaisons locales).mythic_server_host sur le nom de votre hôte/conteneur du serveur Mythic (souvent mythic_server dans les configurations docker-compose, ou 127.0.0.1 pour les liaisons locales).L'agent de base et les commandes incluses utilisent toutes des bibliothèques Python intégrées, donc aucun paquet supplémentaire n'est nécessaire pour fonctionner. Les agents exécutent les commandes dans des threads, donc les téléversements ou téléchargements de longue durée ne bloquent pas l'agent principal.
| Commande | Syntaxe | Description |
|---|---|---|
| cat | cat chemin/vers/fichier | Lire et afficher le contenu d'un fichier. |
| cd | cd [.. répertoire] | Changer de répertoire de travail (.. pour remonter d'un répertoire). |
| cp | cp fichier_ou_dossier_src fichier_ou_dossier_dst | Copier un fichier ou un dossier vers la destination. |
| cwd | cwd | Afficher le répertoire de travail. |
| download | download [chemin] | Télécharger un fichier depuis le système cible. |
| download_bulk | download_bulk [chemin1] [chemin2] ... | Télécharger plusieurs fichiers depuis le système cible en une seule tâche. |
| exit | exit | Quitter un callback. |
| env | env | Afficher les variables d'environnement. |
| eval_code | eval_code [commandes] | Exécuter du code Python et retourner le résultat. |
| jobkill | jobkill [id de tâche] | Envoyer un signal d'arrêt à une tâche longue. |
| jobs | jobs | Lister les tâches longues, comme les téléchargements. |
| list_modules | list_modules [nom_module] | Lister les modules en mémoire ou la liste complète des fichiers d'un module spécifique. |
| load | load commande | Charger une nouvelle capacité dans un agent. |
| load_module | load_module | Charger un module Python compressé en mémoire (adapté de ici et ici). |
| load_script | load_script | Charger et exécuter un script Python via l'agent. |
| ls | ls [. chemin] |
| Commande | Syntaxe | Description |
|---|---|---|
| clipboard | clipboard | Afficher le contenu du presse-papiers (utilise l'API Objective-C, comme décrit par Cedric Owens ici. macOS uniquement, Python 2.7 uniquement). |
| list_apps | list_apps | Lister les applications macOS (Python 2.7 uniquement, macOS uniquement). |
| list_tcc | list_tcc [chemin] | Lister les entrées de la base de données TCC macOS (nécessite un accès complet au disque et Big Sur uniquement pour l'instant). |
| screenshot | screenshot | Prendre une capture d'écran (utilise l'API Objective-C, macOS uniquement, Python 2.7 uniquement). |
| spawn_jxa | spawn_jxa | Lancer un processus osascript et lui envoyer du contenu JavaScript. |
| vscode_list_recent | vscode_list_recent [state_db] | Lister les fichiers et dossiers récemment ouverts avec VSCode. |
| vscode_open_edits | vscode_open_edits [chemin_backup_dir] | Lister les modifications non enregistrées apportées aux fichiers dans VSCode. |
| vscode_watch_edits | vscode_watch_edits [chemin vers répertoire distant] [intervalle_de_polling] | Interroger le répertoire de sauvegarde VSCode à un intervalle donné pour les modifications non enregistrées. |
| Commande | Syntaxe | Description |
|---|---|---|
| shinject | shinject | Injecter du shellcode dans un PID cible en utilisant CreateRemoteThread (Windows uniquement - adapté de ici). |
| load_dll | load_dll chemin_dll export_dll | Charger une DLL sur disque et exécuter une fonction exportée (NOTE : Cette DLL doit retourner une valeur int à la fin, une DLL créée avec msfvenom, par exemple, tuera votre agent à la fin). |
| list_dlls | list_dlls [pid] | Lire la mémoire du processus (PEB) du processus local ou cible pour obtenir la liste des DLL chargées (Python 3 uniquement). |
| ps | ps | Obtenir des informations limitées sur les processus : PID, noms de processus, architecture et chemins binaires (Python 3 uniquement). |
| ps_full | ps_full | Obtenir des informations complètes sur les processus : PPID, niveau d'intégrité et ligne de commande (Python 3 uniquement). |
| kill | kill | Terminer un processus par son ID (Python 3 uniquement). |
Les deux versions de l'agent Medusa utilisent une implémentation AES256 HMAC écrite avec des bibliothèques intégrées (adaptée de ici), éliminant le besoin de dépendances supplémentaires au-delà d'une installation Python standard. Ainsi, l'agent devrait fonctionner sur les hôtes Windows, Linux et macOS. Il est à noter que cette implémentation cryptographique introduit un certain surcoût lors du traitement de gros fichiers (captures d'écran, téléchargements, etc.) mais reste fonctionnelle.
Dans le répertoire Payload_Type/Medusa/agent_code, vous verrez des fichiers base_agent avec les suffixes py2 et py3. De même, des extensions de fichier similaires peuvent être vues pour les fichiers de fonctions individuelles.
Ceux-ci sont lus par le script builder.py pour d'abord sélectionner la bonne version Python de base de l'agent Medusa. builder.py inclura ensuite les commandes spécifiques à la version Python choisie. Dans le cas où une commande a seulement une extension .py, elle sera utilisée par défaut, en supposant qu'aucun code alternatif n'est nécessaire entre les versions Py2 et Py3.
Medusa utilise un threading de base pour l'exécution des tâches. Lorsque les tâches sont potentiellement longues, elles peuvent être implémentées avec une « vérification d'arrêt » pour répondre à un signal de la tâche jobkill. Cela peut être implémenté avec un extrait de code similaire à celui ci-dessous :
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]:
# Nettoyage spécifique à la tâche
return "Tâche arrêtée."
Ce gestionnaire peut être vu implémenté dans les commandes download, upload, watch_dir et screenshot.
De plus, si la tâche longue est censée fournir une sortie continue, la fonction sendTaskOutputUpdate — incluse dans l'agent de base — peut être utilisée pour mettre à jour Mythic avant la fin de la tâche. Une fonction factice qui fournit une sortie continue et peut être arrêtée par jobkill est visible ci-dessous.
def dummyFunction(self, task_id):
while(True):
# Vérifier si nous avons un signal d'arrêt.
if [task for task in self.taskings if task["task_id"] == task_id][0]["stopped"]: return "Tâche arrêtée."
# Envoyer la sortie vers Mythic
self.sendTaskOutputUpdate(task_id, "Nous tournons toujours")
time.sleep(10)
Medusa supporte actuellement deux profils C2 : http (avec et sans chiffrement AES256 HMAC) et azure_blob.
Le profil HTTP rappelle le serveur Mythic via le profil de base non dynamique. Requêtes GET pour les tâches, requêtes POST avec les réponses.
Lister les fichiers et dossiers dans [chemin] ou utilisez . pour le répertoire de travail courant. |
| mv | mv fichier_ou_dossier_src fichier_ou_dossier_dst | Déplacer un fichier ou un dossier vers la destination. |
| pip_freeze | pip_freeze | Lister les paquets installés sur le système par programmation. |
| pty | pty [/bin/bash] / pty self / pty fork | Ouvrir une session PTY interactive. Modes : spawn exécute un programme avec un PTY, self ouvre un REPL Python in-process avec l'état actif de l'agent, fork duplique l'agent dans un REPL Python avec un état figé (Linux/macOS uniquement). |
| rm | rm fichier_ou_dossier | Supprimer un fichier ou un dossier. |
| shell | shell [commande] | Exécuter une commande shell qui sera lancée via subprocess.Popen(). Notez que cela attendra la fin de la commande, alors faites attention à ne pas bloquer votre agent. |
| socks | socks start/stop [port] | Démarrer/arrêter le proxy SOCKS5 via l'agent Medusa. |
| sleep | sleep [secondes] [pourcentage de gigue] | Définir l'intervalle de callback de l'agent en secondes. |
| unload | unload commande | Décharger une capacité existante d'un agent. |
| unload_module | unload_module nom_module | Décharger un module Python précédemment chargé en mémoire. |
| upload | upload | Téléverser un fichier vers un chemin distant sur la machine. |
| watch_dir | watch_dir chemin secondes | Surveiller les modifications dans un répertoire cible, en interrogeant les changements à une fréquence définie. |