Backdoor Python VIPERTUNNEL : Une Analyse Approfondie
Detection stack
- AIDR
- Alert
- ETL
- Query
Résumé
Le rapport détaille l’analyse de VIPERTUNNEL, une porte dérobée basée sur Python qui atteint la persistance via une tâche planifiée et exploite un sitecustomize.py malveillant pour charger une DLL obfusquée. La DLL déchiffre et exécute une charge utile à plusieurs étapes qui établit un proxy SOCKS5 vers un serveur C2 codé en dur sur le port 443. L’infrastructure est liée à UNC2165 et EvilCorp et partage des techniques d’obfuscation avec le voleur d’identifiants ShadowCoil.
Enquête
Les chercheurs ont examiné la sortie d’Autoruns, identifié la tâche planifiée 523135538, et retracé l’exécution vers C:ProgramDatacp49spythonw.exe et son module sitecustomize.py. L’ingénierie inverse de b5yogiiy3c.dll a révélé des obfuscations en couches, des routines de déchiffrement, et une étape finale qui crée un tunnel SOCKS5 utilisant des identifiants codés en dur. L’analyse de l’infrastructure a lié plusieurs domaines et IPs à la campagne et a mis en évidence l’utilisation du cadre Pyramid C2.
Atténuation
Déployez la détection des points de terminaison qui surveille l’exécution de pythonw.exe sans arguments, la création de tâches planifiées avec des noms numériques, et la présence de sitecustomize.py à des emplacements inattendus. Bloquez le trafic sortant vers les domaines C2 connus et les ports 443/8000 avec des réponses HTTP 401 anormales. Mettez en œuvre un contrôle strict des applications pour empêcher le chargement de modules Python non autorisés.
Réponse
Alertez sur la création de la tâche planifiée suspecte et l’exécution de pythonw.exe sans script. Mettez en quarantaine les hôtes affectés, collectez les dumps de mémoire et recherchez les noms de classes caractéristiques et les identifiants codés en dur. Invalidez les identifiants compromis et perturbez l’infrastructure C2 identifiée dans le rapport.
graph TB %% Class definitions classDef technique fill:#ffcc99 classDef process fill:#c2f0c2 classDef tool fill:#ffeb99 classDef file fill:#d9d9d9 classDef component fill:#cce5ff classDef c2 fill:#f4b084 classDef credential fill:#ffe6e6 %% Technique nodes tech_persistence[« <b>Technique</b> – T1053.005 Tâche planifiée : Persistance<br/><b>Description</b>: Crée ou modifie une tâche planifiée pour exécuter du code malveillant à un moment programmé. »] class tech_persistence technique tech_obfuscation[« <b>Technique</b> – T1027 Fichiers ou informations obfusqués<br/><b>Description</b>: Utilise encodage, compression et cryptographie pour masquer du code malveillant. »] class tech_obfuscation technique tech_deobfuscate[« <b>Technique</b> – T1140 Déobfuscation / décodage<br/><b>Description</b>: Décode Base85 et autres transformations pour récupérer le code suivant. »] class tech_deobfuscate technique tech_compile[« <b>Technique</b> – T1027.004 Compilation après livraison<br/><b>Description</b>: Compile le code récupéré en mémoire via compile() et exec(). »] class tech_compile technique tech_reflect[« <b>Technique</b> – T1620 Chargement réflexif de code<br/><b>Description</b>: Exécute du code directement en mémoire sans écriture disque. »] class tech_reflect technique tech_proxy_ext[« <b>Technique</b> – T1090.002 Proxy externe<br/><b>Description</b>: Utilisation d’un proxy SOCKS5 externe pour rediriger le trafic. »] class tech_proxy_ext technique tech_proxy_int[« <b>Technique</b> – T1090.001 Proxy interne<br/><b>Description</b>: Utilisation de composants proxy internes. »] class tech_proxy_int technique tech_tunnel[« <b>Technique</b> – T1572 Tunneling de protocole<br/><b>Description</b>: Encapsulation du trafic dans un tunnel SOCKS5. »] class tech_tunnel technique tech_encrypted[« <b>Technique</b> – T1573 Canal chiffré<br/><b>Description</b>: Communication C2 chiffrée (ChaCha20/XOR). »] class tech_encrypted technique tech_webc2[« <b>Technique</b> – T1102 Service Web<br/><b>Description</b>: Communication avec C2 via HTTPS. »] class tech_webc2 technique tech_nonstd[« <b>Technique</b> – T1571 Port non standard<br/><b>Description</b>: Utilisation du port 443 pour masquer le trafic. »] class tech_nonstd technique %% Process and tool nodes process_task[« <b>Processus</b> – Tâche planifiée 523135538<br/><b>Commande</b>: C:\\ProgramData\\cp49s\\pythonw.exe »] class process_task process tool_pythonw[« <b>Outil</b> – pythonw.exe<br/><b>Rôle</b>: Exécute Python sans fenêtre console. »] class tool_pythonw tool %% File nodes file_sitecustomize[« <b>Fichier</b> – sitecustomize.py<br/><b>But</b>: Auto-import et exécution DLL. »] class file_sitecustomize file file_dll[« <b>Fichier</b> – b5yogiiy3c.dll<br/><b>Type</b>: Charge utile Python obfusquée. »] class file_dll file %% Component nodes component_wire[« <b>Composant</b> – Classe Wire<br/><b>Fonction</b>: Client SOCKS5. »] class component_wire component component_relay[« <b>Composant</b> – Classe Relay<br/><b>Fonction</b>: Transfert de trafic. »] class component_relay component component_commander[« <b>Composant</b> – Classe Commander<br/><b>Fonction</b>: Gestion des commandes C2. »] class component_commander component %% C2 and credential nodes c2_server[« <b>Serveur C2</b> – Service Pyramid<br/><b>Réponse</b>: HTTP 401 Basic realm=Proxy »] class c2_server c2 credentials[« <b>Identifiants</b> – AnyUser / AnyPassword<br/><b>Usage</b>: Authentification proxy »] class credentials credential %% CONNECTIONS (UNCHANGED – IMPORTANT) tech_persistence –>|creates| process_task process_task –>|launches| tool_pythonw tool_pythonw –>|imports| file_sitecustomize file_sitecustomize –>|loads| file_dll file_dll –>|uses| tech_obfuscation file_dll –>|triggers| tech_deobfuscate tech_deobfuscate –>|leads to| tech_compile tech_compile –>|leads to| tech_reflect tech_reflect –>|executes| component_wire component_wire –>|works with| component_relay component_relay –>|controls| component_commander component_commander –>|contacts| c2_server c2_server –>|uses| tech_proxy_ext c2_server –>|uses| tech_proxy_int c2_server –>|tunnels via| tech_tunnel c2_server –>|encrypts channel| tech_encrypted c2_server –>|communicates over| tech_webc2 c2_server –>|uses port| tech_nonstd component_commander –>|auth with| credentials
Flux du’Attaque
Détections
Exécution de Python depuis des Dossiers Suspects (via cmdline)
Voir
Tâche Planifiée Suspecte (via audit)
Voir
IOCs (SourceIP) à détecter : Glisser à Travers le Bruit – Plongée Profonde dans la Porte Dérobée Python VIPERTUNNEL Partie 2
Voir
IOCs (SourceIP) à détecter : Glisser à Travers le Bruit – Plongée Profonde dans la Porte Dérobée Python VIPERTUNNEL Partie 1
Voir
IOCs (DestinationIP) à détecter : Glisser à Travers le Bruit – Plongée Profonde dans la Porte Dérobée Python VIPERTUNNEL Partie 2
Voir
IOCs (DestinationIP) à détecter : Glisser à Travers le Bruit – Plongée Profonde dans la Porte Dérobée Python VIPERTUNNEL Partie 1
Voir
Exécution Suspecte de Python pour la Persistance via sitecustomize.py [Création de Processus Windows]
Voir
Exécution de Simulation
Prérequis : Le Contrôle Préliminaire de Télémétrie & Baseline doit avoir réussi.
Raisonnement : Cette section détaille l’exécution précise de la technique d’adversaire (TTP) conçue pour déclencher la règle de détection. Les commandes et le narratif DOIVENT refléter directement les TTP identifiés et viser à générer la télémétrie exacte attendue par la logique de détection.
-
Narrative & Commandes d’Attaque :
L’adversaire dépose d’abord un sitecustomize.py malveillant
sitecustomize.pydans le même répertoire quepythonw.exe. Python importe automatiquementsitecustomize.pyau démarrage de l’interpréteur, permettant à l’attaquant d’exécuter du code arbitraire sans passer de chemin de script sur la ligne de commande. En lançantpythonw.exesans aucun argument, l’événement de création de processus contient uneCommandLinevide, satisfaisant les conditions de la règle Sigma. La charge utile établit une tâche planifiée pour la persistance, assurant que l’interpréteur s’exécute au démarrage du système, maintenant ainsi un point d’ancrage à long terme. -
Script de Test de Régression :
# ------------------------------------------------- # Configurer sitecustomize.py malveillant # ------------------------------------------------- $payloadPath = 'C:ProgramDatacp49ssitecustomize.py' $exePath = 'C:ProgramDatacp49spythonw.exe' # Garantir l'existence du dossier cible New-Item -ItemType Directory -Path (Split-Path $exePath) -Force | Out-Null # Déployer une copie bénigne de pythonw.exe pour le test (si non déjà présent) # Dans un vrai scénario de red-team, ce serait l'interpréteur légitime if (-Not (Test-Path $exePath)) { # Copier depuis l'installation système de Python (ajuster le chemin si nécessaire) Copy-Item 'C:Python39pythonw.exe' $exePath } # Créer un sitecustomize.py malveillant (crée une tâche planifiée comme preuve de concept) @" import subprocess, sys # Créer une tâche planifiée qui exécute pythonw.exe chaque minute (persistance) subprocess.run(['schtasks', '/Create', '/SC', 'MINUTE', '/MO', '1', '/TN', 'UpdateTask', '/TR', sys.executable]) "@ | Set-Content -Path $payloadPath -Encoding UTF8 # ------------------------------------------------- # Déclencher la détection (exécution malveillante) # ------------------------------------------------- Write-Host '[+] Lancement de pythonw.exe avec une ligne de commande vide...' Start-Process -FilePath $exePath -ArgumentList '' -WindowStyle Hidden # Attendre un court moment pour que la tâche planifiée soit créée (facultatif) Start-Sleep -Seconds 5 Write-Host '[+] Charge utile exécutée. Vérifiez votre SIEM pour l'alerte.' # ------------------------------------------------- # Fin du script # ------------------------------------------------- -
Commandes de Nettoyage :
# Supprimer le sitecustomize.py malveillant Remove-Item -Path 'C:ProgramDatacp49ssitecustomize.py' -Force -ErrorAction SilentlyContinue # Supprimer la tâche planifiée créée par la charge utile schtasks /Delete /TN UpdateTask /F # Éventuellement, supprimer la copie de pythonw.exe (si c'était une copie de test) # Remove-Item -Path 'C:ProgramDatacp49spythonw.exe' -Force Write-Host '[+] Nettoyage complet.'