Exploiter les runners GitLab CI comme un cadre de Command-and-Control
Detection stack
- AIDR
- Alert
- ETL
- Query
Résumé
L’article décrit une preuve de concept nommée GitRunner C2 qui transforme des binaires GitLab CI runner légitimes et signés numériquement en un cadre de commande et contrôle. En installant les runners comme services Windows, un attaquant peut exécuter des commandes PowerShell arbitraires et exfiltrer des données via l’infrastructure intégrée de GitLab. Comme le trafic utilise HTTPS sortant vers gitlab.com, l’activité peut se fondre dans les communications normales des développeurs.
Enquête
Le chercheur a démontré la chaîne d’attaque complète, commençant par l’enrôlement via une ligne de commande PowerShell élevée et se terminant par l’exécution de commandes interactives. L’enquête s’est appuyée sur les journaux Sysmon et PowerShell Operational pour enregistrer la création de processus, les modifications de registre et les commandes exécutées via le Script Block Logging. L’étude a montré que le comportement légitime du runner peut aider à échapper à la détection traditionnelle des EDR et sur le réseau.
Atténuation
Les défenseurs doivent surveiller les nouveaux services Windows installés avec des noms inhabituels ou des services lancés depuis des chemins de fichiers non standards. Activer le Script Block Logging de PowerShell est essentiel pour la visibilité des commandes exécutées via le runner. Les organisations devraient également limiter qui peut installer des services et surveiller les trafics HTTPS sortants suspects vers GitLab depuis des points d’accès qui ne sont pas utilisés pour le travail de développement.
Réponse
Si cette activité est détectée, isolez immédiatement le point d’accès affecté pour arrêter toute communication de commande et de contrôle. Révoquez tous les tokens d’accès personnel GitLab et les tokens d’enregistrement runner liés à l’environnement compromis. Les enquêteurs doivent ensuite examiner les journaux PowerShell et les journaux d’événements Windows pour déterminer l’étendue des commandes exécutées et toute exfiltration de données qui en résulte.
"flowchart TD step_ingress["T1105 u2013 Transfert d’outil d’ingress : Téléchargement de gitlab-runner-windows-amd64.exe légitime via PowerShell depuis S3"] step_persistence["T1543.003 u2013 Créer ou modifier un processus système : Service Windows : Installer le runner GitLab comme service Windows natif pour la persistance"] rules_for_persistence("<b>Nom de la règle</b>: Chemin de binaire de service suspect (via system)<br/><b>ID de la règle</b>: 780e6396-d9f4-42b2-8d73-89918e2dab16") step_trust_subversion["T1553.002 u2013 Subvertir les contrôles de confiance : Signature de code : Utilisation du binaire GitLab signé numériquement pour échapper à la détection"] step_execution["T1059.003 u2013 Interpréteur de commande et de script : Windows Command Shell : Exécution de charges utiles de commande via des variables CI utilisant l’exécuteur de shell"] step_c2["T1071 u2013 Protocole de couche application : Utilisation de HTTPS (port 443) vers l’infrastructure GitLab comme relais C2"] step_exfiltration["T1567.001 u2013 Exfiltration via un service web : Exfiltration vers un dépôt de code : Déplacement de fichiers via les artefacts GitLab et le registre de paquetages génériques"] step_ingress –>|mène à| step_persistence step_persistence –>|active| step_trust_subversion step_persistence -.->|détecté par| rules_for_persistence step_trust_subversion –>|puis| step_execution step_execution –>|utilise| step_c2 step_c2 –>|mène à| step_exfiltration "
Flux d’attaque
Détections
La possibilité d’exécution via des lignes de commande PowerShell cachées (via cmdline)
Voir
Exécution possible de GitRunner C2 (via PowerShell)
Voir
Création possible de tâche planifiée (via PowerShell)
Voir
Création possible de tâche planifiée utilisant PowerShell (via PowerShell)
Voir
Opérations sur les images de service par un processus rare (via registry_event)
Voir
Chemin de binaire de service suspect (via system)
Voir
Script Block Logging de PowerShell indiquant un potentiel abus du Runner GitLab [Windows PowerShell]
Voir
Évasion du service Runner GitLab PowerShell [Windows Sysmon]
Voir
Exécution de simulation
Prérequis : La vérification préliminaire de la télémétrie et de la ligne de base doit avoir été passée.
Justification : Cette section détaille l’exécution précise de la technique de l’adversaire (TTP) conçue pour déclencher la règle de détection. Les commandes et le récit DOIVENT refléter directement les TTP identifiés et viser à générer exactement la télémétrie attendue par la logique de détection. Des exemples abstraits ou non liés entraîneront des erreurs de diagnostic.
-
Narratif de l’attaque et commandes : Un adversaire a obtenu un accès initial et a l’intention d’établir un canal de commande et de contrôle (C2) persistant. Au lieu d’utiliser un malware connu, ils téléchargent le
gitlab-runner-windows-amd64.exelégitime pour se fondre dans l’activité DevOps. Ils utilisent PowerShell pour déposer le fichier dans un répertoire temporaire puis l’enregistrent comme service Windows nommé « gitlab-runner ». Cette méthode vise à exploiter la nature de confiance des outils CI/CD pour contourner les contrôles de sécurité traditionnels. -
Script de test de régression :
# Simulation de l'installation du GitLab Runner pour la validation de détection $ErrorActionPreference = "Stop" # 1. Définissez les chemins et les noms pour correspondre exactement à la logique de détection $TargetDir = "C:WindowsTemp" $BinaryName = "gitlab-runner-windows-amd64.exe" $BinaryPath = Join-Path $TargetDir $BinaryName $ServiceName = "gitlab-runner" Write-Host "[+] Démarrage de la simulation : Installation de $BinaryName" # 2. Simulez la création de fichier (ID événement Sysmon 11) # Dans une attaque réelle, il s'agirait d'un téléchargement web. Ici, nous créons un fichier factice avec le nom spécifié. New-Item -Path $BinaryPath -ItemType File -Force | Out-Null Write-Host "[+] Fichier créé : $BinaryPath (Déclenche l'ID événement 11)" # 3. Simulez l'installation de service de registre (ID événement Sysmon 13) # Création du chemin du service dans le registre pour déclencher la détection ImagePath. $RegPath = "HKLM:SYSTEMCurrentControlSetServices$ServiceName" New-Item -Path $RegPath -Force | Out-Null Set-ItemProperty -Path $RegPath -Name "ImagePath" -Value $BinaryPath Write-Host "[+] Clé de registre et ImagePath créés : $RegPath (Déclenche l'ID événement 13)" Write-Host "[+] Simulation complète. Vérifiez SIEM pour les alertes." -
Commandes de nettoyage :
# Nettoyer les artefacts de simulation $TargetDir = "C:WindowsTemp" $BinaryName = "gitlab-runner-windows-amd64.exe" $BinaryPath = Join-Path $TargetDir $BinaryName $ServiceName = "gitlab-runner" Remove-Item -Path $BinaryPath -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:SYSTEMCurrentControlSetServices$ServiceName" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "[+] Nettoyage complet."