def sendNegotiate(self,negotiateMessage): #Also partly copied from tds.py login = TDS_LOGIN() login['HostName'] = (''.join([random.choice(string.ascii_letters) for _ in range(8)])).encode('utf-16le') login['AppName'] = (''.join([random.choice(string.ascii_letters) for _ in range(8)])).encode('utf-16le') login['ServerName'] = self.server.encode('utf-16le') login['CltIntName'] = login['AppName'] login['ClientPID'] = random.randint(0,1024) login['PacketSize'] = self.packetSize login['OptionFlags2'] = TDS_INIT_LANG_FATAL | TDS_ODBC_ON | TDS_INTEGRATED_SECURITY_ON # NTLMSSP Negotiate login['SSPI'] = negotiateMessage login['Length'] = len(login.getData()) # Send the NTLMSSP Negotiate self.sendTDS(TDS_LOGIN7, login.getData()) # According to the specs, if encryption is not required, we must encrypt just # the first Login packet :-o if self.resp['Encryption'] == TDS_ENCRYPT_OFF: self.tlsSocket = None tds = self.recvTDS() self.sessionData['NTLM_CHALLENGE'] = tds challenge = NTLMAuthChallenge() challenge.fromString(tds['Data'][3:]) #challenge.dump() return challenge
def sendNegotiate(self, negotiateMessage): self.init_connection() #Also partly copied from tds.py login = TDS_LOGIN() login['HostName'] = (''.join([ random.choice(string.letters) for _ in range(8) ])).encode('utf-16le') login['AppName'] = (''.join([ random.choice(string.letters) for _ in range(8) ])).encode('utf-16le') login['ServerName'] = self.server.encode('utf-16le') login['CltIntName'] = login['AppName'] login['ClientPID'] = random.randint(0, 1024) login['PacketSize'] = self.packetSize login['OptionFlags2'] = TDS_INIT_LANG_FATAL | TDS_ODBC_ON login['OptionFlags2'] |= TDS_INTEGRATED_SECURITY_ON # NTLMSSP Negotiate auth = negotiateMessage login['SSPI'] = str(auth) login['Length'] = len(str(login)) # Send the NTLMSSP Negotiate self.sendTDS(TDS_LOGIN7, str(login)) # According to the spects, if encryption is not required, we must encrypt just # the first Login packet :-o if self.resp['Encryption'] == TDS_ENCRYPT_OFF: self.tlsSocket = None tds = self.recvTDS() return tds['Data'][3:]
def skipAuthentication(self): # 1. First packet should be a TDS_PRELOGIN() tds = self.recvTDS() if tds['Type'] != TDS_PRE_LOGIN: # Unexpected packet LOG.debug('Unexpected packet type %d instead of TDS_PRE_LOGIN' % tds['Type']) return False prelogin = TDS_PRELOGIN() prelogin['Version'] = "\x08\x00\x01\x55\x00\x00" prelogin['Encryption'] = TDS_ENCRYPT_NOT_SUP prelogin['ThreadID'] = struct.pack('<L', random.randint(0, 65535)) prelogin['Instance'] = '\x00' # Answering who we are self.sendTDS(TDS_TABULAR, str(prelogin), 0) # 2. Packet should be a TDS_LOGIN tds = self.recvTDS() if tds['Type'] != TDS_LOGIN7: # Unexpected packet LOG.debug('Unexpected packet type %d instead of TDS_LOGIN' % tds['Type']) return False login = TDS_LOGIN() login.fromString(tds['Data']) if login['OptionFlags2'] & TDS_INTEGRATED_SECURITY_ON: # Windows Authentication enabled # Send the resp we've got from the original relay TDSResponse = self.sessionData['NTLM_CHALLENGE'] self.sendTDS(TDSResponse['Type'], TDSResponse['Data'], 0) # Here we should get the NTLM_AUTHENTICATE tds = self.recvTDS() authenticateMessage = NTLMAuthChallengeResponse() authenticateMessage.fromString(tds['Data']) self.username = authenticateMessage['user_name'] try: self.username = ( '%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le')) ).upper() except UnicodeDecodeError: # Not Unicode encoded? self.username = ('%s/%s' % (authenticateMessage['domain_name'], authenticateMessage['user_name'])).upper() else: if login['UserName'].find('/') >= 0: try: self.username = login['UserName'].upper().decode( 'utf-16le') except UnicodeDecodeError: # Not Unicode encoded? self.username = login['UserName'].upper() else: try: self.username = ( '/%s' % login['UserName'].decode('utf-16le')).upper() except UnicodeDecodeError: # Not Unicode encoded? self.username = ('/%s' % login['UserName']).upper() # Check if we have a connection for the user if self.activeRelays.has_key(self.username): # Check the connection is not inUse if self.activeRelays[self.username]['inUse'] is True: LOG.error( 'MSSQL: Connection for %s@%s(%s) is being used at the moment!' % (self.username, self.targetHost, self.targetPort)) return False else: LOG.info('MSSQL: Proxying client session for %s@%s(%s)' % (self.username, self.targetHost, self.targetPort)) self.session = self.activeRelays[ self.username]['protocolClient'].session else: LOG.error('MSSQL: No session for %s@%s(%s) available' % (self.username, self.targetHost, self.targetPort)) return False # We have a session relayed, let's answer back with the data if login['OptionFlags2'] & TDS_INTEGRATED_SECURITY_ON: TDSResponse = self.sessionData['AUTH_ANSWER'] self.sendTDS(TDSResponse['Type'], TDSResponse['Data'], 0) else: TDSResponse = self.sessionData['AUTH_ANSWER'] self.sendTDS(TDSResponse['Type'], TDSResponse['Data'], 0) return True
def skipAuthentication(self): # 1. First packet should be a TDS_PRELOGIN() tds = self.recvTDS() if tds['Type'] != TDS_PRE_LOGIN: # Unexpected packet LOG.debug('Unexpected packet type %d instead of TDS_PRE_LOGIN' % tds['Type']) return False prelogin = TDS_PRELOGIN() prelogin['Version'] = "\x08\x00\x01\x55\x00\x00" prelogin['Encryption'] = TDS_ENCRYPT_NOT_SUP prelogin['ThreadID'] = struct.pack('<L',random.randint(0,65535)) prelogin['Instance'] = '\x00' # Answering who we are self.sendTDS(TDS_TABULAR, str(prelogin), 0) # 2. Packet should be a TDS_LOGIN tds = self.recvTDS() if tds['Type'] != TDS_LOGIN7: # Unexpected packet LOG.debug('Unexpected packet type %d instead of TDS_LOGIN' % tds['Type']) return False login = TDS_LOGIN() login.fromString(tds['Data']) if login['OptionFlags2'] & TDS_INTEGRATED_SECURITY_ON: # Windows Authentication enabled # Send the resp we've got from the original relay TDSResponse = self.sessionData['NTLM_CHALLENGE'] self.sendTDS(TDSResponse['Type'], TDSResponse['Data'], 0) # Here we should get the NTLM_AUTHENTICATE tds = self.recvTDS() authenticateMessage = NTLMAuthChallengeResponse() authenticateMessage.fromString(tds['Data']) self.username = authenticateMessage['user_name'] try: self.username = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'), authenticateMessage['user_name'].decode('utf-16le'))).upper() except UnicodeDecodeError: # Not Unicode encoded? self.username = ('%s/%s' % (authenticateMessage['domain_name'], authenticateMessage['user_name'])).upper() else: if login['UserName'].find('/') >=0: try: self.username = login['UserName'].upper().decode('utf-16le') except UnicodeDecodeError: # Not Unicode encoded? self.username = login['UserName'].upper() else: try: self.username = ('/%s' % login['UserName'].decode('utf-16le')).upper() except UnicodeDecodeError: # Not Unicode encoded? self.username = ('/%s' % login['UserName']).upper() # Check if we have a connection for the user if self.activeRelays.has_key(self.username): # Check the connection is not inUse if self.activeRelays[self.username]['inUse'] is True: LOG.error('MSSQL: Connection for %s@%s(%s) is being used at the moment!' % ( self.username, self.targetHost, self.targetPort)) return False else: LOG.info('MSSQL: Proxying client session for %s@%s(%s)' % ( self.username, self.targetHost, self.targetPort)) self.session = self.activeRelays[self.username]['protocolClient'].session else: LOG.error('MSSQL: No session for %s@%s(%s) available' % ( self.username, self.targetHost, self.targetPort)) return False # We have a session relayed, let's answer back with the data if login['OptionFlags2'] & TDS_INTEGRATED_SECURITY_ON: TDSResponse = self.sessionData['AUTH_ANSWER'] self.sendTDS(TDSResponse['Type'], TDSResponse['Data'], 0) else: TDSResponse = self.sessionData['AUTH_ANSWER'] self.sendTDS(TDSResponse['Type'], TDSResponse['Data'], 0) return True