26/12/2024

Active DirectoryCybersécurité

Comment détecter une attaque LLMNR poisoning sur votre réseau avec un Honeypot ?

I. Présentation

Dans cet article, nous allons apprendre à mettre en place un pot de miel (honeypot) afin de piéger un attaquant sur notre réseau et détecter une attaque LLMNR poisoning.

Pour rappel, le protocole LLMNR (Local Link Multicast Name Resolution) est un protocole de résolution de nom activé par défaut sous Windows et utilisant le multicast. L'idée est que si notre résolveur local ou DNS de référence ne sait pas répondre à la question "quelle est l'adresse IP correspondant à tel nom de domaine", le client finit par demander l'information à tous ses voisins du réseau local. C’est un peu la version « bouche-à-oreille » de la résolution IP-nom.

L’attaque LLMNR poisoning consiste pour l'attaquant à abuser de l'utilisation de ce protocole en répondant systématiquement aux voisins en émettant une requête "oui je connais la correspondance" (même si ce n'est pas vrai), puis à donner son adresse IP en réponse. Ainsi, les clients viennent se connecter sur son poste via différents protocoles et l'attaquant en profite pour demander une authentification, ce qui entraîne généralement un vol de session (via SMB Relay) ou de mot de passe (en cas d'utilisation du NTLMv1 notamment).

Pour en savoir plus sur ce protocole et son exploitation dans la cadre d'une cyberattaque, je vous invite à consulter notre article à ce sujet :

Vous pouvez aussi regarder la vidéo qui résume l'article :

Il faut enfin savoir que le LLMNR poisoning (et le SMB Relay qui en découle souvent) est une technique très connue des attaquants, si bien qu'il possède son propre TTP dans le framework MITRE ATT&CK :

L'idée est maintenant de se demander comment nous pouvons détecter une tentative de l'attaquant d'exploiter le LLMNR sur notre réseau. Il faut savoir que les requêtes LLMNR et les réponses obtenues ne sont pas journalisées dans l'observateur d'évènements, on ne peut donc a priori pas compter là-dessus pour détecter une telle attaque.

II. Attaque sur LLMNR : comment piéger l'attaquant ?

Pour détecter une tentative d'exploitation du protocole LLMNR sur un réseau, nous pouvons tendre une perche à l'attaquant et lever l'alerte dès que celui-ci l'a saisie, autrement dit : le piéger.

L'idée est simple : sur un hôte qui ne possède pas de lien avec l'Active Directoy et aucun service ou compte sensible, nous allons faire tourner un script qui va émettre des requêtes LLMNR à une fréquence aléatoire sur le réseau. Il émettra des requêtes concernant des noms de domaine qui n'existent pas et pour lesquels personne ne devrait donc avoir de réponse à apporter. Ainsi, si l'on obtient une réponse à nos requêtes LLMNR, ce sera forcément le fait d'un attaquant souhaitant nous piéger, nous pourrons ainsi journaliser l'adresse IP qui nous a répondu et détecter l'attaquant (pour ensuite le bloquer par exemple).

Simple, mais efficace ! Il faut savoir que la plupart des outils d'attaque sont, par défaut, configurés pour répondre à toutes les requêtes LLMNR qu'ils voient passer en multicast sur le réseau, qu'elle soit le fruit d'une vraie requête d'un utilisateur, ou d'un honeypot.

Pour ce faire, nous allons utiliser un petit script PowerShell, facile à mettre en place, qui fera office de pot de miel (honeypot) en vue de détecter toute tentative d'exploitation. Nous allons dans un premier temps nous baser sur la CmdLet PowerShell "Resolve-DnsName", qui permet d'émettre une requête DNS. Celle-ci propose l'option "-LlmnrOnly", qui comme son nom l'indique, effectuera une requête LLMNR uniquement, sans passer par la requête DNS préalable. Exemple :

Resolve-DnsName -Name FQDN-test -Type A -LlmnrOnly

Dans le cadre de ce test, j’ai utilisé en tant qu’attaquant l’outil Responder pour empoisonner les requêtes LLMNR émises sur le réseau local. Voici ce que l'on obtient lors d'une écoute sur le réseau local lors de l'utilisation de cette requête :

 Trafic réseau observé lors de l’émission d’une requête LLMNR via PowerShell.
Trafic réseau observé lors de l’émission d’une requête LLMNR via PowerShell.

La CmdLet "Resolve-DnsName" a été utilisée pour émettre une requête LLMNR, voici ce que l'on obtient sur un Wireshark : le paquet n°1 représente la requête LLMNR, le paquet n°2 la réponse (empoisonnée) envoyée par l'attaquant.

En retour, j'obtiens bien en réponse de ma CmdLet PowerShell l'adresse IP ("IPAddress") qui m'a été indiquée par l'attaquant.

Pour rappel, le hic ici, est que je sais que le nom de domaine n'existe pas. La seule personne qui puisse me répondre est donc un attaquant qui cherche à exploiter le protocole LLMNR sur mon réseau.

Maintenant que nous avons fait ce petit essai, il est temps de passer à un script plus complet.

III. Script PowerShell de détection LLMNR

J'ai écrit pour vous un petit script basé sur la CmdLet PowerShell "Resolve-DnsName". Nous allons dans cette section étudier son comportement et voir comment l'utiliser.

Ce script est composé d'une boucle infinie ("while ($true)") qui va marquer un temps de pause aléatoire (entre 1 et 10 secondes) entre chaque boucle. À chaque itération, une requête LLMNR va être émise et, en fonction de la réponse obtenue, nous lèverons une alerte ou non. Voici la boucle en question :

# Boucle principale pour émettre des requêtes aléatoires
while ($true) {
    $randomHostname = $hostnames[$(Get-Random -Maximum $hostnames.Length)]
    Send-LLMNRQuery -hostname "$randomHostname"

    # Pause
    Start-Sleep -Seconds $random.Next($MinWaitTime, $MaxWaitTime)
}

J'utilise un tableau, l'idée est d'avoir plusieurs noms possibles (réalistes, si possible) pour nos requêtes afin que celles-ci ne mettent pas la puce à l'oreille de l'attaquant (on évitera les noms du type "LLMNR-DETECTION" par exemple :-)). Voici à titre d'exemple des noms contenant des typos (évènement possible menant à l'émission d'une requête LLMNR dans un contexte réel) :

$hostnames = @("DSN121", "Imrpimante", "ActieDirector", "DNSS-Server", "File--server")

La boucle principale va ensuite analyser sa réponse :

# Envoi de la requête LLMNR
    $LLMNRResponse = Resolve-DnsName -Name $randomHostname -Type A -LlmnrOnly -ErrorAction SilentlyContinue
    
    if ($TerminalOutput) {
        Write-Output "$(Get-Date) - LLMNR Query sent: `"$randomHostname`""
    }

    # Si une réponse est reçue, journaliser
    if ($LLMNRResponse) {
        if ($TerminalOutput) {
            Write-Output "$(Get-Date) - LLMNR response received from $($LLMNRResponse.IPAddress)"
        }
        Write-EventLogV2 -ID $eventID -hostname $randomHostname -IP $($LLMNRResponse.IPAddress) -evtLog $eventLog -evtSource $logSource
    } else {
        if ($TerminalOutput) {
            Write-Output "$(Get-Date) - No response for LLMNR Query: `"$randomHostname`""
        }
    }

En fonction de la présence ou non d'une réponse à la requête LLMNR, nous allons journaliser la réponse obtenue (et surtout l'adresse IP de l'attaquant) dans le terminal ou les logs Windows. J'utilise pour les logs Windows la commande "Write-EventLogV2" présentée dans cet article :

Le script comporte plusieurs paramètres que vous pouvez bien sûr modifier. Par défaut, seule la journalisation dans les logs Windows est réalisée, rien n'apparaît dans le terminal. Mais, si vous souhaitez voir précisément comment il fonctionne et tester le script, il est toujours intéressant de pouvoir avoir un retour en direct. Vous pouvez pour cela modifier la ligne "$TerminalOutput = $False" à :

$TerminalOutput = $True

Les autres paramètres comme l'eventID de l'évènement créé, le nom du logSource, le temps minimal ou maximal d'attente ou la liste des noms à requêter sont également modifiables.

Vous trouverez le script en entier sur notre dépôt GitHub :

IV. Visualisation dans les logs

A. Détecter l'attaque LLMNR dans l'observateur d'évènement

Une fois que ce script est présent sur une machine Windows, il suffit de l'exécuter pour commencer à émettre des requêtes LLMNR :

.\Detect-LLMNRPoisoning.ps1

Voici à quoi ressemble son utilisation lorsque la sortie terminal est activée ("$TerminalOutput= $True") :

 Détection d’un LLMNR Poisonning via notre script PS1.
Détection d’un LLMNR Poisonning via notre script PS1.

Sur la sortie du terminal, chaque requête et chaque réponse obtenue est journalisée. Cela permet de suivre en direct l'activité du script. Dans tous les cas, un évènement à l'ID 10001 est créé pour chaque réponse obtenue dans le journal "Application" de l'Observateur d'évènement Windows :

Evènement de détection d’une attaque LLMNR poisonning dans l’observateur d’évènement Windows.0

Je vous conseille de déployer ce script sur une machine qui n’a aucun lien avec l’Active Directory ni de ports ouverts ou services sensibles en cours d’exécution. Ainsi, même si l’attaquant dirige son attention vers cette machine, elle ne contiendra aucune information sensible ni accès qui pourraient être exploités. Sa compromission ne lui apporterait donc rien d'utile.

Il est également important de choisir judicieusement le réseau sur lequel déployer ce honeypot. Faut-il surveiller le réseau bureautique, celui des serveurs, ou encore la DMZ ? L'attaquant peut potentiellement lancer son attaque sur n'importe quel réseau contenant des systèmes du domaine, mais le réseau des postes utilisateurs est souvent plus vulnérable. Les utilisateurs y commettent parfois des typos lors de leurs requêtes, ce qui peut entraîner l’envoi de requêtes LLMNR. De plus, il s’agit vraisemblablement du réseau sur lequel l’attaquant aura son premier accès (compromission d’un poste utilisateur ou branchement physique), et sur lequel il démarrera ses activités de compromission de comptes utilisateur.

Attention, les fautes de frappe ne sont pas la seule cause des requêtes LLMNR. D'autres facteurs courants incluent :

  • Erreurs de configuration : une mauvaise configuration peut provoquer l'envoi de requêtes DNS et LLMNR vers des hôtes inexistants.
  • Obsolescence : des applications obsolètes peuvent encore être configurées pour pointer vers des noms DNS qui n'existent plus.
  • Comportements automatiques : certains systèmes d'exploitation ou applications, comme les navigateurs web, peuvent émettre automatiquement des requêtes (par exemple vers "wpad").

B. Visualisation de l’attaque dans un SIEM

Maintenant que nous avons un évènement qui permet de révéler la présence d'un attaquant exploitant activement le protocole LLMNR sur notre réseau, il serait dommage de passer à côté ! Il faut bien sûr penser à centraliser cet évènement dans un SIEM (Security information and event management) comme Splunk ou ELK et d'être sûr d'avoir positionné une alerte si un tel évènement est créé.

Voici, à titre d'exemple, la visualisation de l'évènement 10001 sur un SIEM ELK (ElasticSearch, LogStash, Kibana) :

 Evènement créé par notre script de détection d’attaque LLMNR Poisonning dans le SIEM ELK.
Evènement créé par notre script de détection d’attaque LLMNR Poisonning dans le SIEM ELK.

Nous avons désormais mis en place une chaîne complète de détection grâce à notre script honeypot. Pour aller encore plus loin, on peut envisager d'intégrer ce script à des solutions de blocage automatique des menaces, comme un système un IPS (Intrusion Prevention System) ou un EDR. Cela permettrait non seulement de détecter l'attaquant, mais aussi de l'isoler automatiquement du reste du réseau. Il faut bien sûr au préalable avoir éprouvé ce script dans votre environnement et déterminer si des faux positifs apparaissent.

V. Conclusion

Dans cet article, nous avons vu qu'il est possible via un script PowerShell assez simple de détecter des attaques LLMNR sur un réseau, et cela, en piégeant l'attaquant. Il est ensuite possible de créer des logs lors d'une détection, puis de les remonter au sein d'un SIEM.

Il est également théoriquement possible de détecter des attaques LLMNR via la surveillance du trafic réseau (sondes). Par exemple, en surveillant le nombre et le contenu des réponses LLMNR émises au sein d'un réseau, mais l'approche par honeypot me paraît plus simple à mettre en place, bien que moins discrète pour un attaquant avisé.

Plus globalement, il faut rappeler qu'il est recommandé par les bonnes pratiques de sécurité de désactiver ce protocole sur tous les systèmes Windows, ainsi que le protocole NBNS qui présente les mêmes faiblesses. Je vous oriente vers notre article à ce sujet pour en savoir plus :

author avatar
Mickael Dorigny Co-founder
Co-fondateur d'IT-Connect.fr. Auditeur/Pentester chez Orange Cyberdéfense.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.