def __init__(self, remoteName='', remoteHost='', myName = None, sess_port = 445, timeout=60, preferredDialect = None, existingConnection = None): self._SMBConnection = 0 self._dialect = '' self._nmbSession = 0 hostType = nmb.TYPE_SERVER if existingConnection is not None: # Existing Connection must be a smb or smb3 instance assert ( isinstance(existingConnection,smb.SMB) or isinstance(existingConnection, smb3.SMB3)) self._SMBConnection = existingConnection return ##preferredDialect = smb.SMB_DIALECT if preferredDialect is None: # If no preferredDialect sent, we try the highest available one. packet = self._negotiateSession(myName, remoteName, remoteHost, sess_port, timeout) if packet[0] == '\xfe': # Answer is SMB2 packet self._SMBConnection = smb3.SMB3(remoteName, remoteHost, myName, hostType, sess_port, timeout, session = self._nmbSession ) else: # Answer is SMB packet, sticking to SMBv1 self._SMBConnection = smb.SMB(remoteName, remoteHost, myName, hostType, sess_port, timeout, session = self._nmbSession, negPacket = packet) else: if preferredDialect == smb.SMB_DIALECT: self._SMBConnection = smb.SMB(remoteName, remoteHost, myName, hostType, sess_port, timeout) elif preferredDialect in [SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30]: self._SMBConnection = smb3.SMB3(remoteName, remoteHost, myName, hostType, sess_port, timeout, preferredDialect = preferredDialect) else: print "Unknown dialect ", preferredDialect raise
def request_SMBv23(host, port=445): # start client smb_client = smb3.SMB3(host, host, sess_port=port) # start: modified from login() # https://github.com/SecureAuthCorp/impacket/blob/master/impacket/smb3.py session_setup = smb3.SMB2SessionSetup() if smb_client.RequireMessageSigning is True: session_setup["SecurityMode"] = smb3.SMB2_NEGOTIATE_SIGNING_REQUIRED else: session_setup["SecurityMode"] = smb3.SMB2_NEGOTIATE_SIGNING_ENABLED session_setup["Flags"] = 0 # NTLMSSP blob = smb3.SPNEGO_NegTokenInit() blob["MechTypes"] = [ smb3.TypesMech["NTLMSSP - Microsoft NTLM Security Support Provider"] ] auth = ntlm.getNTLMSSPType1( smb_client._Connection["ClientName"], "", smb_client._Connection["RequireSigning"], ) blob["MechToken"] = auth.getData() session_setup["SecurityBufferLength"] = len(blob) session_setup["Buffer"] = blob.getData() packet = smb_client.SMB_PACKET() packet["Command"] = smb3.SMB2_SESSION_SETUP packet["Data"] = session_setup packet_id = smb_client.sendSMB(packet) smb_response = smb_client.recvSMB(packet_id) if smb_client._Connection["Dialect"] == smb3.SMB2_DIALECT_311: smb_client.__UpdatePreAuthHash(smb_response.rawData) # NTLM challenge if smb_response.isValidAnswer(smb3.STATUS_MORE_PROCESSING_REQUIRED): session_setup_response = smb3.SMB2SessionSetup_Response( smb_response["Data"]) resp_token = smb3.SPNEGO_NegTokenResp(session_setup_response["Buffer"]) return resp_token["ResponseToken"] else: return None
def negotiateSession( self, preferredDialect=None, flags1=smb.SMB.FLAGS1_PATHCASELESS | smb.SMB.FLAGS1_CANONICALIZED_PATHS, flags2=smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_LONG_NAMES, negoData='\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'): """ Perform protocol negotiation :param string preferredDialect: the dialect desired to talk with the target server. If None is specified the highest one available will be used :param string flags1: the SMB FLAGS capabilities :param string flags2: the SMB FLAGS2 capabilities :param string negoData: data to be sent as part of the nego handshake :return: True, raises a Session Error if error. """ hostType = nmb.TYPE_SERVER if preferredDialect is None: # If no preferredDialect sent, we try the highest available one. packet = self._negotiateSession(self._myName, self._remoteName, self._remoteHost, self._sess_port, self._timeout, True, flags1=flags1, flags2=flags2, data=negoData) if packet[0] == '\xfe': # Answer is SMB2 packet self._SMBConnection = smb3.SMB3(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout, session=self._nmbSession) else: # Answer is SMB packet, sticking to SMBv1 self._SMBConnection = smb.SMB(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout, session=self._nmbSession, negPacket=packet) else: if preferredDialect == smb.SMB_DIALECT: self._SMBConnection = smb.SMB(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout) elif preferredDialect in [ SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30 ]: self._SMBConnection = smb3.SMB3( self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout, preferredDialect=preferredDialect) else: LOG.critical("Unknown dialect ", preferredDialect) raise # propagate flags to the smb sub-object # does not affect smb3 objects if isinstance(self._SMBConnection, smb.SMB): self._SMBConnection.set_flags(flags1=flags1, flags2=flags2) return True
def negotiateSession(self, preferredDialect=None, flags1=smb.SMB.FLAGS1_PATHCASELESS | smb.SMB.FLAGS1_CANONICALIZED_PATHS, flags2=smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_LONG_NAMES, negoData='\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'): """ Perform protocol negotiation :param string preferredDialect: the dialect desired to talk with the target server. If None is specified the highest one available will be used :param string flags1: the SMB FLAGS capabilities :param string flags2: the SMB FLAGS2 capabilities :param string negoData: data to be sent as part of the nego handshake :return: True, raises a Session Error if error. """ # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP. This is to help some old # applications still believing # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better know about i # *SMBSERVER's limitations if self._sess_port == nmb.SMB_SESSION_PORT and self._remoteName == '*SMBSERVER': self._remoteName = self._remoteHost elif self._sess_port == nmb.NETBIOS_SESSION_PORT and self._remoteName == '*SMBSERVER': # If remote name is *SMBSERVER let's try to query its name.. if can't be guessed, continue and hope for the best nb = nmb.NetBIOS() try: res = nb.getnetbiosname(self._remoteHost) except: pass else: self._remoteName = res hostType = nmb.TYPE_SERVER if preferredDialect is None: # If no preferredDialect sent, we try the highest available one. packet = self.negotiateSessionWildcard(self._myName, self._remoteName, self._remoteHost, self._sess_port, self._timeout, True, flags1=flags1, flags2=flags2, data=negoData) if packet[0:1] == b'\xfe': # Answer is SMB2 packet self._SMBConnection = smb3.SMB3(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout, session=self._nmbSession, negSessionResponse=SMB2Packet(packet)) else: # Answer is SMB packet, sticking to SMBv1 self._SMBConnection = smb.SMB(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout, session=self._nmbSession, negPacket=packet) else: if preferredDialect == smb.SMB_DIALECT: self._SMBConnection = smb.SMB(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout) elif preferredDialect in [SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30]: self._SMBConnection = smb3.SMB3(self._remoteName, self._remoteHost, self._myName, hostType, self._sess_port, self._timeout, preferredDialect=preferredDialect) else: raise Exception("Unknown dialect %s") # propagate flags to the smb sub-object, except for Unicode (if server supports) # does not affect smb3 objects if isinstance(self._SMBConnection, smb.SMB): if self._SMBConnection.get_flags()[1] & smb.SMB.FLAGS2_UNICODE: flags2 |= smb.SMB.FLAGS2_UNICODE self._SMBConnection.set_flags(flags1=flags1, flags2=flags2) return True