def queryPathInformation(self, connId, smbServer, recvPacket, parameters, data, maxDataCount=0): # The trick we play here is that Windows clients first ask for the file # and then it asks for the directory containing the file. # It is important to answer the right questions for the attack to work connData = smbServer.getConnectionData(connId) respSetup = '' respParameters = '' respData = '' errorCode = 0 queryPathInfoParameters = smb.SMBQueryPathInformation_Parameters( flags=recvPacket['Flags2'], data=parameters) if len(data) > 0: queryPathInfoData = smb.SMBQueryPathInformation_Data(data) if connData['ConnectedShares'].has_key(recvPacket['Tid']): path = '' try: origPathName = decodeSMBString( recvPacket['Flags2'], queryPathInfoParameters['FileName']) origPathName = os.path.normpath(origPathName.replace( '\\', '/')) if connData.has_key('MS15011') is False: connData['MS15011'] = {} smbServer.log( "Client is asking for QueryPathInformation for: %s" % origPathName, logging.INFO) if connData['MS15011'].has_key( origPathName) or origPathName == '.': # We already processed this entry, now it's asking for a directory infoRecord, errorCode = queryPathInformation( path, '/', queryPathInfoParameters['InformationLevel']) else: # First time asked, asking for the file infoRecord, errorCode = queryPathInformation( path, self.defaultFile, queryPathInfoParameters['InformationLevel']) connData['MS15011'][os.path.dirname( origPathName)] = infoRecord except Exception, e: #import traceback #traceback.print_exc() smbServer.log("queryPathInformation: %s" % e, logging.ERROR) if infoRecord is not None: respParameters = smb.SMBQueryPathInformationResponse_Parameters( ) respData = infoRecord
def queryPathInformation(self, connId, smbServer, recvPacket, parameters, data, maxDataCount = 0): # The trick we play here is that Windows clients first ask for the file # and then it asks for the directory containing the file. # It is important to answer the right questions for the attack to work connData = smbServer.getConnectionData(connId) respSetup = b'' respParameters = b'' respData = b'' errorCode = 0 queryPathInfoParameters = smb.SMBQueryPathInformation_Parameters(flags = recvPacket['Flags2'], data = parameters) if recvPacket['Tid'] in connData['ConnectedShares']: path = '' try: origPathName = decodeSMBString(recvPacket['Flags2'], queryPathInfoParameters['FileName']) origPathName = os.path.normpath(origPathName.replace('\\','/')) if ('MS15011' in connData) is False: connData['MS15011'] = {} smbServer.log("Client is asking for QueryPathInformation for: %s" % origPathName,logging.INFO) if origPathName in connData['MS15011'] or origPathName == '.': # We already processed this entry, now it's asking for a directory infoRecord, errorCode = queryPathInformation(path, '/', queryPathInfoParameters['InformationLevel']) else: # First time asked, asking for the file infoRecord, errorCode = queryPathInformation(path, self.defaultFile, queryPathInfoParameters['InformationLevel']) connData['MS15011'][os.path.dirname(origPathName)] = infoRecord except Exception as e: #import traceback #traceback.print_exc() smbServer.log("queryPathInformation: %s" % e,logging.ERROR) if infoRecord is not None: respParameters = smb.SMBQueryPathInformationResponse_Parameters() respData = infoRecord else: errorCode = STATUS_SMB_BAD_TID smbServer.setConnectionData(connId, connData) return respSetup, respParameters, respData, errorCode
def create_and_x(self, conn_id, smb_server, smb_command, recv_packet): """ Our version of smbComNtCreateAndX looks for special test files and fools the rest of the framework into opening them as if they were normal files. """ conn_data = smb_server.getConnectionData(conn_id) # Wrap processing in a try block which allows us to throw SmbException # to control the flow. try: ncax_parms = imp_smb.SMBNtCreateAndX_Parameters( smb_command["Parameters"]) path = self.get_share_path(conn_data, ncax_parms["RootFid"], recv_packet["Tid"]) log.info("[SMB] Requested share path: %s", path) disposition = ncax_parms["Disposition"] log.debug("[SMB] Requested disposition: %s", disposition) # Currently we only support reading files. if disposition != imp_smb.FILE_OPEN: raise SmbException(STATUS_ACCESS_DENIED, "Only support reading files") # Check to see if the path we were given is actually a # magic path which needs generating on the fly. if path not in [SERVER_MAGIC, TESTS_MAGIC]: # Pass the command onto the original handler. return imp_smbserver.SMBCommands.smbComNtCreateAndX( conn_id, smb_server, smb_command, recv_packet) flags2 = recv_packet["Flags2"] ncax_data = imp_smb.SMBNtCreateAndX_Data(flags=flags2, data=smb_command["Data"]) requested_file = imp_smbserver.decodeSMBString( flags2, ncax_data["FileName"]) log.debug("[SMB] User requested file '%s'", requested_file) if path == SERVER_MAGIC: fid, full_path = self.get_server_path(requested_file) else: assert (path == TESTS_MAGIC) fid, full_path = self.get_test_path(requested_file) resp_parms = imp_smb.SMBNtCreateAndXResponse_Parameters() resp_data = "" # Simple way to generate a fid if len(conn_data["OpenedFiles"]) == 0: fakefid = 1 else: fakefid = conn_data["OpenedFiles"].keys()[-1] + 1 resp_parms["Fid"] = fakefid resp_parms["CreateAction"] = disposition if os.path.isdir(path): resp_parms[ "FileAttributes"] = imp_smb.SMB_FILE_ATTRIBUTE_DIRECTORY resp_parms["IsDirectory"] = 1 else: resp_parms["IsDirectory"] = 0 resp_parms["FileAttributes"] = ncax_parms["FileAttributes"] # Get this file's information resp_info, error_code = imp_smbserver.queryPathInformation( "", full_path, level=imp_smb.SMB_QUERY_FILE_ALL_INFO) if error_code != STATUS_SUCCESS: raise SmbException(error_code, "Failed to query path info") resp_parms["CreateTime"] = resp_info["CreationTime"] resp_parms["LastAccessTime"] = resp_info["LastAccessTime"] resp_parms["LastWriteTime"] = resp_info["LastWriteTime"] resp_parms["LastChangeTime"] = resp_info["LastChangeTime"] resp_parms["FileAttributes"] = resp_info["ExtFileAttributes"] resp_parms["AllocationSize"] = resp_info["AllocationSize"] resp_parms["EndOfFile"] = resp_info["EndOfFile"] # Let's store the fid for the connection # smbServer.log("Create file %s, mode:0x%x" % (pathName, mode)) conn_data["OpenedFiles"][fakefid] = {} conn_data["OpenedFiles"][fakefid]["FileHandle"] = fid conn_data["OpenedFiles"][fakefid]["FileName"] = path conn_data["OpenedFiles"][fakefid]["DeleteOnClose"] = False except SmbException as s: log.debug("[SMB] SmbException hit: %s", s) error_code = s.error_code resp_parms = "" resp_data = "" resp_cmd = imp_smb.SMBCommand(imp_smb.SMB.SMB_COM_NT_CREATE_ANDX) resp_cmd["Parameters"] = resp_parms resp_cmd["Data"] = resp_data smb_server.setConnectionData(conn_id, conn_data) return [resp_cmd], None, error_code
def create_and_x(self, conn_id, smb_server, smb_command, recv_packet): """ Our version of smbComNtCreateAndX looks for special test files and fools the rest of the framework into opening them as if they were normal files. """ conn_data = smb_server.getConnectionData(conn_id) # Wrap processing in a try block which allows us to throw SmbException # to control the flow. try: ncax_parms = imp_smb.SMBNtCreateAndX_Parameters( smb_command["Parameters"]) path = self.get_share_path(conn_data, ncax_parms["RootFid"], recv_packet["Tid"]) log.info("[SMB] Requested share path: %s", path) disposition = ncax_parms["Disposition"] log.debug("[SMB] Requested disposition: %s", disposition) # Currently we only support reading files. if disposition != imp_smb.FILE_OPEN: raise SmbException(STATUS_ACCESS_DENIED, "Only support reading files") # Check to see if the path we were given is actually a # magic path which needs generating on the fly. if path not in [SERVER_MAGIC, TESTS_MAGIC]: # Pass the command onto the original handler. return imp_smbserver.SMBCommands.smbComNtCreateAndX(conn_id, smb_server, smb_command, recv_packet) flags2 = recv_packet["Flags2"] ncax_data = imp_smb.SMBNtCreateAndX_Data(flags=flags2, data=smb_command[ "Data"]) requested_file = imp_smbserver.decodeSMBString( flags2, ncax_data["FileName"]) log.debug("[SMB] User requested file '%s'", requested_file) if path == SERVER_MAGIC: fid, full_path = self.get_server_path(requested_file) else: assert (path == TESTS_MAGIC) fid, full_path = self.get_test_path(requested_file) resp_parms = imp_smb.SMBNtCreateAndXResponse_Parameters() resp_data = "" # Simple way to generate a fid if len(conn_data["OpenedFiles"]) == 0: fakefid = 1 else: fakefid = conn_data["OpenedFiles"].keys()[-1] + 1 resp_parms["Fid"] = fakefid resp_parms["CreateAction"] = disposition if os.path.isdir(path): resp_parms[ "FileAttributes"] = imp_smb.SMB_FILE_ATTRIBUTE_DIRECTORY resp_parms["IsDirectory"] = 1 else: resp_parms["IsDirectory"] = 0 resp_parms["FileAttributes"] = ncax_parms["FileAttributes"] # Get this file's information resp_info, error_code = imp_smbserver.queryPathInformation( "", full_path, level=imp_smb.SMB_QUERY_FILE_ALL_INFO) if error_code != STATUS_SUCCESS: raise SmbException(error_code, "Failed to query path info") resp_parms["CreateTime"] = resp_info["CreationTime"] resp_parms["LastAccessTime"] = resp_info[ "LastAccessTime"] resp_parms["LastWriteTime"] = resp_info["LastWriteTime"] resp_parms["LastChangeTime"] = resp_info[ "LastChangeTime"] resp_parms["FileAttributes"] = resp_info[ "ExtFileAttributes"] resp_parms["AllocationSize"] = resp_info[ "AllocationSize"] resp_parms["EndOfFile"] = resp_info["EndOfFile"] # Let's store the fid for the connection # smbServer.log("Create file %s, mode:0x%x" % (pathName, mode)) conn_data["OpenedFiles"][fakefid] = {} conn_data["OpenedFiles"][fakefid]["FileHandle"] = fid conn_data["OpenedFiles"][fakefid]["FileName"] = path conn_data["OpenedFiles"][fakefid]["DeleteOnClose"] = False except SmbException as s: log.debug("[SMB] SmbException hit: %s", s) error_code = s.error_code resp_parms = "" resp_data = "" resp_cmd = imp_smb.SMBCommand(imp_smb.SMB.SMB_COM_NT_CREATE_ANDX) resp_cmd["Parameters"] = resp_parms resp_cmd["Data"] = resp_data smb_server.setConnectionData(conn_id, conn_data) return [resp_cmd], None, error_code