def splitSMBChainedMessages(self, data): try: smbMessages = [] # SMB v1 if (data[4:8] == '\xff\x53\x4d\x42'): z = 4 nx = data.find('\xff\x53\x4d\x42', z + 1) while nx > -1: smbMessages.append(NewSMBPacket(data=data[z:nx])) z = nx nx = data.find('\xff\x53\x4d\x42', z + 1) # Required after the last iteration to get the remaining data smbMessages.append(NewSMBPacket(data=copy.deepcopy(data[z:]))) return smbMessages # SMB v2 elif (data[4:8] == '\xfe\x53\x4d\x42'): z = 4 nx = data.find('\xfe\x53\x4d\x42', z + 1) while nx > -1: smbMessages.append( SMB2Packet(data=copy.deepcopy(data[z:nx]))) z = nx nx = data.find('\xfe\x53\x4d\x42', z + 1) # Required after the last iteration to get the remaining data smbMessages.append(SMB2Packet(data=copy.deepcopy(data[z:]))) return smbMessages except Exception, e: logging.error("[SMB_Core::splitSMBChainedMessages] " + str(traceback.format_exc())) return data
def create_smb( smb_client, treeId, fileName, desiredAccess, shareMode, creationOptions, creationDisposition, fileAttributes, impersonationLevel=SMB2_IL_IMPERSONATION, oplockLevel=SMB2_OPLOCK_LEVEL_NONE, createContexts=None, ): packet = smb_client.getSMBServer().SMB_PACKET() packet["Command"] = SMB2_CREATE packet["TreeID"] = treeId if smb_client._SMBConnection._Session["TreeConnectTable"][treeId][ "IsDfsShare"] is True: packet["Flags"] = SMB2_FLAGS_DFS_OPERATIONS smb2Create = SMB2Create() smb2Create["SecurityFlags"] = 0 smb2Create["RequestedOplockLevel"] = oplockLevel smb2Create["ImpersonationLevel"] = impersonationLevel smb2Create["DesiredAccess"] = desiredAccess smb2Create["FileAttributes"] = fileAttributes smb2Create["ShareAccess"] = shareMode smb2Create["CreateDisposition"] = creationDisposition smb2Create["CreateOptions"] = creationOptions smb2Create["NameLength"] = len(fileName) * 2 if fileName != "": smb2Create["Buffer"] = fileName.encode("utf-16le") else: smb2Create["Buffer"] = b"\x00" if createContexts is not None: smb2Create["Buffer"] += createContexts smb2Create["CreateContextsOffset"] = (len(SMB2Packet()) + SMB2Create.SIZE + smb2Create["NameLength"]) smb2Create["CreateContextsLength"] = len(createContexts) else: smb2Create["CreateContextsOffset"] = 0 smb2Create["CreateContextsLength"] = 0 packet["Data"] = smb2Create packetID = smb_client.getSMBServer().sendSMB(packet) ans = smb_client.getSMBServer().recvSMB(packetID) if ans.isValidAnswer(STATUS_SUCCESS): createResponse = SMB2Create_Response(ans["Data"]) # The client MUST generate a handle for the Open, and it MUST # return success and the generated handle to the calling application. # In our case, str(FileID) return str(createResponse["FileID"])
def create(self, treeId, fileName, desiredAccess, shareMode, creationOptions, creationDisposition, fileAttributes, impersonationLevel=SMB2_IL_IMPERSONATION, securityFlags=0, oplockLevel=SMB2_OPLOCK_LEVEL_NONE, createContexts=None): packet = self.__smbClient.getSMBServer().SMB_PACKET() packet['Command'] = SMB2_CREATE packet['TreeID'] = treeId if self.__smbClient._SMBConnection._Session['TreeConnectTable'][ treeId]['IsDfsShare'] is True: packet['Flags'] = SMB2_FLAGS_DFS_OPERATIONS smb2Create = SMB2Create() smb2Create['SecurityFlags'] = 0 smb2Create['RequestedOplockLevel'] = oplockLevel smb2Create['ImpersonationLevel'] = impersonationLevel smb2Create['DesiredAccess'] = desiredAccess smb2Create['FileAttributes'] = fileAttributes smb2Create['ShareAccess'] = shareMode smb2Create['CreateDisposition'] = creationDisposition smb2Create['CreateOptions'] = creationOptions smb2Create['NameLength'] = len(fileName) * 2 if fileName != '': smb2Create['Buffer'] = fileName.encode('utf-16le') else: smb2Create['Buffer'] = b'\x00' if createContexts is not None: smb2Create['Buffer'] += createContexts smb2Create['CreateContextsOffset'] = len( SMB2Packet()) + SMB2Create.SIZE + smb2Create['NameLength'] smb2Create['CreateContextsLength'] = len(createContexts) else: smb2Create['CreateContextsOffset'] = 0 smb2Create['CreateContextsLength'] = 0 packet['Data'] = smb2Create packetID = self.__smbClient.getSMBServer().sendSMB(packet) ans = self.__smbClient.getSMBServer().recvSMB(packetID) if ans.isValidAnswer(STATUS_SUCCESS): createResponse = SMB2Create_Response(ans['Data']) # The client MUST generate a handle for the Open, and it MUST # return success and the generated handle to the calling application. # In our case, str(FileID) return str(createResponse['FileID'])
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
client.sendall(rpkt) response = client.recv(999999) client.close() del (client) except Exception, e: # It's not supported, bummer dialects.remove(SMB_DIALECT) else: # SMB1 is supported, cool pass # Check SMB 2.0.2 try: # Generic smb2 packet smbHeader = SMB2Packet( unhexlify( "fe534d42400001000000000000001f0000000000000000000000000000000000fffe000000000000000000000000000000000000000000000000000000000000" )) # Here's a generic negotiate protocol request # - just modify the client GUID to prevent # AV/IDS fingerprinting negProto = SMB2Negotiate( unhexlify( "24000500010000007f000000cb78cd146438e7119168000c291232a370000000020000000202100200030203110300000100260000000000010020000100c8c31f28d43563c829b9070423e96a98701ac3ec788a3ac01573ee03d07d942600000200060000000000020002000100" )) negProto['Dialects'] = [SMB2_DIALECT_002, 0, 0, 0, 0, 0] negProto['ClientGuid'] = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(8)) rawData = str(smbHeader) + str(negProto)