
Détecter si un service est installé (à l'aveugle) et/ou en cours d'exécution (s'il expose des tubes nommés) sur une machine distante sans utiliser de privilèges administrateur locaux.
Détecter si un service est installé (à l'aveugle) et/ou en cours d'exécution (s'il expose des named pipes) sur une machine distante sans utiliser de privilèges d'administrateur local.
Plus précisément, l'exécution de ce script se connecte au service SMB cible (445/tcp) à distance et effectue les opérations suivantes :
Vérifie si le service spécifié est installé via l'appel RPC [MS-LSAT] LsarLookupNames(). Aucun compte privilégié n'est nécessaire, mais seule une requête « à l'aveugle » est possible (on ne peut pas lister les services, on ne peut que demander l'état d'un service spécifique).
Vérifie si le Named Pipe spécifié existe sur la cible. Les services (processus) peuvent exposer un named pipe caractéristique du service, qui peut être visible par un utilisateur non privilégié. Ainsi, vérifier les named pipes caractéristiques des services peut nous permettre de déduire si le service spécifique est en cours d'exécution ou non.
Il s'agit d'un script Python autonome utilisant Impacket, aucune installation n'est nécessaire. Testé sur Kali et Arch Linux à jour avec les dernières versions officielles d'Impacket (0.10.0 et 0.9.24) et de Python (3.9 et 3.10).
Les services, les noms de services à vérifier, et les named pipes caractéristiques du service sont spécifiés dans des fichiers de configuration JSON (ou des fichiers CSV si c'est plus confortable, ce dont je me suis rendu compte plus tard :), un convertisseur csv2json personnalisé est donc également disponible) dans le dossier conf. Pour comprendre le format, voir les exemples inclus.
Fichiers de configuration inclus :
Les cas d'utilisation peuvent être étendus avec d'autres services / named pipes, la configuration EDR est assez incomplète, n'hésitez pas à en ajouter.
Le script utilise le format de configuration JSON, mais j'ai réalisé plus tard qu'écrire du CSV est beaucoup plus confortable, j'ai donc inclus le script csv2json.py pour convertir le CSV en JSON.
L'exécution contre une seule cible pour énumérer les services AV/EDR (ou tout autre chose) est simple :
./serviceDetector.py -conf conf/edr.json evil.corp/johndoe:[email protected]
L'authentification Kerberos est également prise en charge (la variable d'environnement KRB5CCNAME pointe vers le fichier ccache) :
./serviceDetector.py -conf conf/edr.json -k -no-pass server.ecorp.local
Pour l'exécution contre plusieurs cibles, GNU parallel est extrêmement utile :
cat targets.txt | parallel -j 50 ./serviceDetector.py evil.corp/johndoe:Passw0rd1@{}
Notez qu'avant d'exécuter l'outil contre un grand nombre de cibles, testez-le sur une seule afin d'éviter le verrouillage de compte (par exemple en cas de mot de passe mal orthographié).
Note Opsec : sachez que des connexions massives et simultanées vers différentes cibles peuvent déclencher des alertes SOC.
Les deux techniques utilisées ici ne sont pas nouvelles.
L'appel RPC [MS-LSAT] LsarLookupNames() a été utilisé précédemment par Vincent Le Toux (@mysmartlogon) dans le module Antivirusscanner de l'excellent outil PingCastle.
L'idée du named pipe pour détecter les services en cours d'exécution a été inspirée par ce tweet de Lee Christensen (@tifkin_) lorsqu'il a utilisé cette technique pour la détection du service WebClient. Cette technique pour la détection AV/EDR a également été utilisée par l'outil NamedPipeTouch de la NSA (divulgué par le groupe The Shadow Brokers).