Skip to content

mssql protocol crash #1065

@illmob

Description

@illmob

Describe the bug
When connecting to an MSSQL instance that does not support Windows authentication, NetExec attempts NTLM negotiation and crashes while parsing the server response as an NTLMSSP challenge. The server instead returns a valid TDS error packet stating that Windows logins are not supported.

This results in an unhandled exception during enum_host_info().

Microsoft SQL Server 2014 (12.00.924.00, Pre‑RTM)
TCP 1433 open
SQL Authentication only? (Windows auth disabled?)
Encryption required (TLS)

To Reproduce
Steps to reproduce the behavior i.e.:
Command: nxc mssql 10.179.2.11 -u testuser -p testpass
Resulted in:

[22:37:07] ERROR    Exception while calling proto_flow() on target 10.179.2.11: ("Unpacked data doesn't match constant value 'b'\\x9f\\x9e\\x00\\x00\\x01\\x14?\\x00'' should be ''NTLMSSP\\x00''", 'When unpacking field \' | "NTLMSSP\x00 | b\'\\x9f\\x9e\\x00\\x00\\x01\\x14?\\x00W\\x00i\\x00n\\x00d\\x00o\\x00w\\x00s\\x00 \\x00l\\x00o\\x00g\\x00i\\x00n\\x00s\\x00 \\x00a\\x00r\\x00e\\x00             connection.py:187
                    \\x00n\\x00o\\x00t\\x00 \\x00s\\x00u\\x00p\\x00p\\x00o\\x00r\\x00t\\x00e\\x00d\\x00 \\x00i\\x00n\\x00 \\x00t\\x00h\\x00i\\x00s\\x00 \\x00v\\x00e\\x00r\\x00s\\x00i\\x00o\\x00n\\x00 \\x00o\\x00f\\x00 \\x00S\\x00Q\\x00L\\x00
                    \\x00S\\x00e\\x00r\\x00v\\x00e\\x00r\\x00.\\x00\\x0b1\\x000\\x00.\\x001\\x007\\x009\\x00.\\x002\\x00.\\x001\\x001\\x00\\x00\\x00\\x00\\xfd\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\'[:8]\'')
                    ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/nxc/connection.py:177 in __init__                                                                                                                                                                                                                                                                         │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   174 │   │   self.logger.info(f"Socket info: host={self.host}, hostname={self.hostname},                                                                                                                                                                                                                                                                                             │
                    │       kerberos={self.kerberos}, ipv6={self.is_ipv6}, link-local                                                                                                                                                                                                                                                                                                                       │
                    │       ipv6={self.is_link_local_ipv6}")                                                                                                                                                                                                                                                                                                                                                │
                    │   175 │   │                                                                                                                                                                                                                                                                                                                                                                           │
                    │   176 │   │   try:                                                                                                                                                                                                                                                                                                                                                                    │
                    │ ❱ 177 │   │   │   self.proto_flow()                                                                                                                                                                                                                                                                                                                                                   │
                    │   178 │   │   except FileNotFoundError as e:                                                                                                                                                                                                                                                                                                                                          │
                    │   179 │   │   │   self.logger.error(f"File not found error on target {target}: {e}")                                                                                                                                                                                                                                                                                                  │
                    │   180 │   │   except Exception as e:                                                                                                                                                                                                                                                                                                                                                  │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/nxc/connection.py:244 in proto_flow                                                                                                                                                                                                                                                                       │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   241 │   │   │   self.logger.info(f"Failed to create connection object for target                                                                                                                                                                                                                                                                                                    │
                    │       {self.host}, exiting...")                                                                                                                                                                                                                                                                                                                                                       │
                    │   242 │   │   else:                                                                                                                                                                                                                                                                                                                                                                   │
                    │   243 │   │   │   self.logger.debug("Created connection object")                                                                                                                                                                                                                                                                                                                      │
                    │ ❱ 244 │   │   │   self.enum_host_info()                                                                                                                                                                                                                                                                                                                                               │
                    │   245 │   │   │                                                                                                                                                                                                                                                                                                                                                                       │
                    │   246 │   │   │   # Construct the output file template using os.path.join for OS compatibility                                                                                                                                                                                                                                                                                        │
                    │   247 │   │   │   base_log_dir = os.path.join(NXC_PATH, "logs")                                                                                                                                                                                                                                                                                                                       │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/nxc/protocols/mssql.py:77 in wrapper                                                                                                                                                                                                                                                                      │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │    74 │   │   │   with contextlib.suppress(Exception):                                                                                                                                                                                                                                                                                                                                │
                    │    75 │   │   │   │   self.conn.disconnect()                                                                                                                                                                                                                                                                                                                                          │
                    │    76 │   │   │   self.create_conn_obj()                                                                                                                                                                                                                                                                                                                                              │
                    │ ❱  77 │   │   │   return func(self, *args, **kwargs)                                                                                                                                                                                                                                                                                                                                  │
                    │    78 │   │   return wrapper                                                                                                                                                                                                                                                                                                                                                          │
                    │    79 │                                                                                                                                                                                                                                                                                                                                                                               │
                    │    80 │   def check_if_admin(self):                                                                                                                                                                                                                                                                                                                                                   │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/nxc/protocols/mssql.py:136 in enum_host_info                                                                                                                                                                                                                                                              │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   133 │   │   │   self.logger.info(f"Failed to receive NTLM challenge, reason: {e!s}")                                                                                                                                                                                                                                                                                                │
                    │   134 │   │   │   return False                                                                                                                                                                                                                                                                                                                                                        │
                    │   135 │   │   else:                                                                                                                                                                                                                                                                                                                                                                   │
                    │ ❱ 136 │   │   │   ntlm_info = parse_challenge(challenge)                                                                                                                                                                                                                                                                                                                              │
                    │   137 │   │   │   self.targetDomain = self.domain = ntlm_info["domain"]                                                                                                                                                                                                                                                                                                               │
                    │   138 │   │   │   self.hostname = ntlm_info["hostname"]                                                                                                                                                                                                                                                                                                                               │
                    │   139 │   │   │   self.server_os = ntlm_info["os_version"]                                                                                                                                                                                                                                                                                                                            │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/nxc/helpers/ntlm_parser.py:16 in parse_challenge                                                                                                                                                                                                                                                          │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   13 │   │   "domain": None,                                                                                                                                                                                                                                                                                                                                                          │
                    │   14 │   │   "os_version": None                                                                                                                                                                                                                                                                                                                                                       │
                    │   15 │   }                                                                                                                                                                                                                                                                                                                                                                            │
                    │ ❱ 16 │   challange = ntlm.NTLMAuthChallenge(challange)                                                                                                                                                                                                                                                                                                                                │
                    │   17 │   av_pairs =                                                                                                                                                                                                                                                                                                                                                                   │
                    │      ntlm.AV_PAIRS(challange["TargetInfoFields"][:challange["TargetInfoFields_len"]])                                                                                                                                                                                                                                                                                                 │
                    │   18 │   if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None:                                                                                                                                                                                                                                                                                                                           │
                    │   19 │   │   with contextlib.suppress(Exception):                                                                                                                                                                                                                                                                                                                                     │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/impacket/structure.py:104 in __init__                                                                                                                                                                                                                                                                     │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   101 │   │   self.b = lambda x: six.ensure_binary(x, encoding=self.ENCODING)                                                                                                                                                                                                                                                                                                         │
                    │   102 │   │                                                                                                                                                                                                                                                                                                                                                                           │
                    │   103 │   │   if data is not None:                                                                                                                                                                                                                                                                                                                                                    │
                    │ ❱ 104 │   │   │   self.fromString(data)                                                                                                                                                                                                                                                                                                                                               │
                    │   105 │   │   else:                                                                                                                                                                                                                                                                                                                                                                   │
                    │   106 │   │   │   self.data = None                                                                                                                                                                                                                                                                                                                                                    │
                    │   107                                                                                                                                                                                                                                                                                                                                                                                 │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/impacket/ntlm.py:390 in fromString                                                                                                                                                                                                                                                                        │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │    387 │   │   return Structure.getData(self)                                                                                                                                                                                                                                                                                                                                         │
                    │    388 │                                                                                                                                                                                                                                                                                                                                                                              │
                    │    389 │   def fromString(self,data):                                                                                                                                                                                                                                                                                                                                                 │
                    │ ❱  390 │   │   Structure.fromString(self,data)                                                                                                                                                                                                                                                                                                                                        │
                    │    391 │   │   self['domain_name'] = data[self['domain_offset']:][:self['domain_len']]                                                                                                                                                                                                                                                                                                │
                    │    392 │   │   self['TargetInfoFields'] =                                                                                                                                                                                                                                                                                                                                             │
                    │        data[self['TargetInfoFields_offset']:][:self['TargetInfoFields_len']]                                                                                                                                                                                                                                                                                                          │
                    │    393 │   │   return self                                                                                                                                                                                                                                                                                                                                                            │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/impacket/structure.py:169 in fromString                                                                                                                                                                                                                                                                   │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   166 │   │   │   if len(field) > 2:                                                                                                                                                                                                                                                                                                                                                  │
                    │   167 │   │   │   │   dataClassOrCode = field[2]                                                                                                                                                                                                                                                                                                                                      │
                    │   168 │   │   │   try:                                                                                                                                                                                                                                                                                                                                                                │
                    │ ❱ 169 │   │   │   │   self[field[0]] = self.unpack(field[1], data[:size], dataClassOrCode =                                                                                                                                                                                                                                                                                           │
                    │       dataClassOrCode, field = field[0])                                                                                                                                                                                                                                                                                                                                              │
                    │   170 │   │   │   except Exception as e:                                                                                                                                                                                                                                                                                                                                              │
                    │   171 │   │   │   │   e.args += ("When unpacking field '%s | %s | %r[:%d]'" % (field[0],                                                                                                                                                                                                                                                                                              │
                    │       field[1], data, size),)                                                                                                                                                                                                                                                                                                                                                         │
                    │   172 │   │   │   │   raise                                                                                                                                                                                                                                                                                                                                                           │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │ /home/pciaudit/.local/share/pipx/venvs/netexec/lib/python3.13/site-packages/impacket/structure.py:332 in unpack                                                                                                                                                                                                                                                                       │
                    │                                                                                                                                                                                                                                                                                                                                                                                       │
                    │   329 │   │   if format[:1] == "'" or format[:1] == '"':                                                                                                                                                                                                                                                                                                                              │
                    │   330 │   │   │   answer = format[1:]                                                                                                                                                                                                                                                                                                                                                 │
                    │   331 │   │   │   if self.b(answer) != data:                                                                                                                                                                                                                                                                                                                                          │
                    │ ❱ 332 │   │   │   │   raise Exception("Unpacked data doesn't match constant value '%r' should                                                                                                                                                                                                                                                                                         │
                    │       be '%r'" % (data, answer))                                                                                                                                                                                                                                                                                                                                                      │
                    │   333 │   │   │   return answer                                                                                                                                                                                                                                                                                                                                                       │
                    │   334 │   │                                                                                                                                                                                                                                                                                                                                                                           │
                    │   335 │   │   # address specifier                                                                                                                                                                                                                                                                                                                                                     │
                    ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
                    Exception: ("Unpacked data doesn't match constant value 'b'\\x9f\\x9e\\x00\\x00\\x01\\x14?\\x00'' should be ''NTLMSSP\\x00''", 'When unpacking field \' | "NTLMSSP\x00 | b\'\\x9f\\x9e\\x00\\x00\\x01\\x14?\\x00W\\x00i\\x00n\\x00d\\x00o\\x00w\\x00s\\x00 \\x00l\\x00o\\x00g\\x00i\\x00n\\x00s\\x00 \\x00a\\x00r\\x00e\\x00 \\x00n\\x00o\\x00t\\x00
                    \\x00s\\x00u\\x00p\\x00p\\x00o\\x00r\\x00t\\x00e\\x00d\\x00 \\x00i\\x00n\\x00 \\x00t\\x00h\\x00i\\x00s\\x00 \\x00v\\x00e\\x00r\\x00s\\x00i\\x00o\\x00n\\x00 \\x00o\\x00f\\x00 \\x00S\\x00Q\\x00L\\x00
                    \\x00S\\x00e\\x00r\\x00v\\x00e\\x00r\\x00.\\x00\\x0b1\\x000\\x00.\\x001\\x007\\x009\\x00.\\x002\\x00.\\x001\\x001\\x00\\x00\\x00\\x00\\xfd\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\'[:8]\'')

...

Expected behavior
Connection established
Server returns TDS error message:
"Windows logins are not supported in this version of SQL Server."
NetExec attempts to parse response as NTLMSSP

Crash with:
Unpacked data doesn't match constant value 'NTLMSSP\x00'
Expected behavior:
Graceful handling of SQL Server error response
Clean failure indicating Windows authentication is not supported
No NTLM parsing attempt when server returns TDS error packet

Screenshots
If applicable, add screenshots to help explain your problem.

NetExec info

  • OS: Kali Cloud
  • Version of nxc: .5.0 - Yippie-Ki-Yay - b1e9d63 - 37
  • Installed from: pipx

Additional context
impacket-mssqlclient handles this scenario correctly (fails login without crashing)
This appears to be a protocol state mismatch rather than a connectivity issue
Likely requires checking for TDS Error tokens before NTLM parsing

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions