TDS / MQTT / Exchange
This page covers SQL Server’s TDS, MQTT for message delivery, and Exchange NSPI. It shows how each connection starts and how Impacket reads the responses. The corresponding CLIs are listed in the MSSQL / Exchange / MQTT Command Index.
TDS (MSSQL)
Section titled “TDS (MSSQL)”Implementation: MSSQL in impacket/tds.py.
Interactive operation is in impacket/examples/mssqlshell.py.
The normal transport is TCP. mssqlclient.py -named-pipe opens a named pipe
over SMB and sends the same TDS messages. -auth-smb / -hashes-smb
allow separate SMB and SQL credentials. With Windows authentication, the SMB
identity is used for SQL login. TDS 8.0 strict encryption is not supported
over named pipes.
sequenceDiagram
participant C as MSSQL client
participant S as SQL Server :1433
C->>S: PRELOGIN
opt encryption
C->>S: TLS handshake
end
C->>S: LOGIN7 (SQL auth or SSPI)
S-->>C: LOGINACK / ERROR / FEATUREEXTACK
C->>S: SQL Batch
S-->>C: COLMETADATA / ROW / DONE / INFO / ERROR
Discovery
Section titled “Discovery”MSSQL.getInstances() sends SQLR_CLNT_UCAST_EX to UDP 1434
(SQLR_PORT). This is the same Browser protocol used by mssqlinstance.
Responses repeat name;value; pairs and contain the instance name,
port, named pipe, and version. This helps determine the Kerberos SPN
(MSSQLSvc/host:port or MSSQLSvc/host:INSTANCE).
PRELOGIN and LOGIN7
Section titled “PRELOGIN and LOGIN7”TDS_PRELOGIN exchanges the version, encryption setting, instance, and thread ID.
If encryption is required, the connection switches to TLS and sends LOGIN7 over it.
There is also a TDS 8 path (tds8).
Authentication in TDS_LOGIN (LOGIN7):
| Path | CLI | Wire Format |
|---|---|---|
| SQL authentication | Default | User and obfuscated password in LOGIN7 |
| Windows NTLM | -windows-auth | Type1/Type2/Type3 in the SSPI field |
| Kerberos | -k | SPNEGO + AP-REQ in SSPI; kerberosLogin() |
Writing DOMAIN\user as the username alone does not enable Windows authentication.
-windows-auth changes the login mechanism.
The SQL password is obfuscated in LOGIN7 by nibble swaps and XOR
(encryptPassword()); without TLS, this does not protect it.
Channel binding applies over TLS. The client uses
generate_cbt_from_tls_unique() to create tls-unique.
checkMSSQLStatus
checks the login response for CBT enforcement. The TDS 8 (tds8) path
establishes TLS before PRELOGIN.
Token stream
Section titled “Token stream”A query uses a SQL Batch packet. The server returns a token stream.
| Token | Meaning |
|---|---|
| COLMETADATA | Column names and types |
| ROW / NBCROW | Rows |
| DONE / DONEPROC / DONEINPROC | End of a batch; status includes whether there was an error |
| ERROR / INFO | Messages; DONE can follow ERROR |
| ENVCHANGE | Changes such as database switching; retained in the session |
| LOGINACK / FEATUREEXTACK / RETURNSTATUS | Login and features |
TDS_INFO_ERROR and TDS_DONE have layouts for versions 7.1 and earlier
and 7.2 and later (login7_uses_72_plus_token_layout). Packet boundaries
are separate from token boundaries. Do not mistake multiple result sets or NULL for ordinary rows.
MSSQLShell helpers such as xp_cmdshell call server-side procedures
in the same session. The database context and transaction
remain in effect.
Related CLI: mssqlclient
Implementation: impacket/mqtt.py.
mqtt_check sends CONNECT and checks
whether anonymous connections work and what CONNACK returns. It is independent of the Windows authentication stack.
The wire format starts with a fixed header and a variable-length integer for remaining length.
Exchange NSPI
Section titled “Exchange NSPI”exchanger uses
nspi.py and
oxabref.py to
enumerate and dump the address book. The transport is often
RPC over HTTP (ncacn_http).
NSPI is an RPC interface for MAPI address books. Its main tasks are GUID / DNT lookups and restricted table enumeration. It is not an EWS/MAPI client for the mailbox itself.
Checks When Making Changes
Section titled “Checks When Making Changes”- Change TDS versions and token layouts together
- Keep Windows and SQL authentication fields in LOGIN7 separate
- Make CBT / TLS switching consistent with the PRELOGIN encryption flag
- Check CONNECT flags for the MQTT protocol version (3.1 / 3.1.1)

