def __init__(self, name, fileList, processIDs): """give a file list and a name construct a swirl into memory """ self._pathCache = {} self._detectedPackageManager() self.swirl = Swirl(name, datetime.now()) # # let's see if we have proecss ID we might need to scan for dynamic dependecies # with the help of the /proc FS # # synamicDependencies = { 'binarypath' : [list of file it depends to], # '/bin/bash' : ['/lib/x86_64-linux-gnu/libnss_files-2.15.so', # '/lib/x86_64-linux-gnu/libnss_nis-2.15.so']} dynamicDependecies = {} if processIDs : if not fileList : fileList = [] for proc in processIDs.split(','): proc = proc.strip() # add the binary binaryFile = os.readlink('/proc/' + proc + '/exe') fileList.append( binaryFile ) dynamicDependecies[binaryFile] = [] f=open('/proc/' + proc + '/maps') maps = f.read() f.close() for i in maps.split('\n'): tokens = i.split() if len(tokens) > 5 and 'x' in tokens[1] and os.path.isfile(tokens[5]): # memory mapped area is executable and point to a files dynamicDependecies[binaryFile].append( tokens[5] ) for i in fileList: if os.path.islink(i): swirlFile = SwirlFile( i ) swirlFile.type = 'link' self.swirl.addFile(swirlFile) elif os.path.isfile(i): if i in dynamicDependecies: swirlFile = PluginManager.getSwirl(i) else: swirlFile = PluginManager.getSwirl(i) #self._hashDependencies(swirlFile) self.swirl.addFile(swirlFile) elif os.path.isdir(i): pass else: raise IOError("The file %s cannot be opened." % i) # # we might need to add the dynamic dependencies to the swirl # if they did not get detected already for fileName in dynamicDependecies.keys(): swirlFile = self.swirl.getSwirlFile(fileName) listDepFile = swirlFile.getListDependenciesFiles() for dynamicDepFile in dynamicDependecies[fileName]: if dynamicDepFile not in listDepFile: newDeps = PluginManager.getDependeciesFromPath(dynamicDepFile) for i in newDeps: swirlFile.addDependency( i ) # now that I have all the dependencies in place (both static and dynamic) # I can do the hashing for i in self.swirl.swirlFiles: self._hashDependencies(i)
def __init__(self, name, fileList, processIDs, execCmd): """give a file list and a name construct a swirl into memory """ self._detectedPackageManager() self.swirl = Swirl(name, datetime.now()) if execCmd: self.swirl.cmdLine = execCmd # # dependencies discovered with dinamic methods # dynamicDependencies = { 'binarypath' : [list of file it depends to], # '/bin/bash' : ['/lib/x86_64-linux-gnu/libnss_files-2.15.so', # '/lib/x86_64-linux-gnu/libnss_nis-2.15.so']} if execCmd: self._straceCmd(execCmd) # let's see if we have proecss ID we might need to scan for dynamic dependecies # with the help of the /proc FS elif processIDs: for proc in processIDs.split(','): pid = proc.strip() # add the binary tcb = FingerPrint.syscalltracer.TracerControlBlock(pid) tcb.updateSharedLibraries() dynamicDependecies = FingerPrint.syscalltracer.TracerControlBlock.dependencies # set up the fileList for the static dependency detection if not fileList: fileList = [] # it does not work on python 2.5 aka RHEL 5.X # fileList = [f if f[0] == '/' else os.path.normpath(os.getcwd() + '/' + f) for f in fileList] def norm_path(path): if path[0] == '/': return os.path.normpath(path) else: return os.path.normpath(os.getcwd() + '/' + path) fileList = [norm_path(f) for f in fileList] fileList = fileList + dynamicDependecies.keys() # add all the fileList to the swirl and figure out all their static libraries for binPath in fileList: if os.path.isfile(binPath): cmd = binPath if binPath in FingerPrint.syscalltracer.TracerControlBlock.cmdline: # the user cmdline could be a symlink so we want to keep track cmd = FingerPrint.syscalltracer.TracerControlBlock.cmdline[ binPath][0] cmd = utils.which(cmd) if not cmd: cmd = binPath if cmd and cmd[0] != '/': # hmm we have a relative path pwd = FingerPrint.syscalltracer.TracerControlBlock.get_env_variable( binPath, "PWD") pwd = pwd + '/' + cmd if os.path.isfile(pwd) and os.access(pwd, os.X_OK): cmd = pwd else: # TODO this way to resolving relative path is not 100% correct # it should be done in the syscalltracer cmd = binPath # load the env tmpenv = [] if binPath in FingerPrint.syscalltracer.TracerControlBlock.env: for var in FingerPrint.syscalltracer.TracerControlBlock.env[ binPath]: if '=' in var and '=()' not in var: tmpenv.append(var) swirlFile = PluginManager.getSwirl(cmd, self.swirl, tmpenv) self.swirl.execedFiles.append(swirlFile) elif os.path.isdir(binPath): pass else: raise IOError("The file %s cannot be opened." % binPath) # # we might need to add the dynamic dependencies to the swirl # if they did not get detected already for fileName in dynamicDependecies.keys(): swirlFile = PluginManager.getSwirl(fileName, self.swirl) #let's add it to the execed file list if swirlFile not in self.swirl.execedFiles: # TODO remove me... this should never be called self.swirl.execedFiles.append(swirlFile) for dynamicDepFile in dynamicDependecies[fileName]: newSwirlFileDependency = PluginManager.getSwirl( dynamicDepFile, self.swirl, swirlFile.env) #I need to verify it if is static dep or dynamic dep #TODO need to optimize this swirlDependencies = self.swirl.getListSwirlFilesDependentStatic( swirlFile) if newSwirlFileDependency.path not in [ x.path for x in swirlDependencies ]: swirlFile.dynamicDependencies.append( newSwirlFileDependency) # let's see if it used some Data files # files is a double dictionary see TraceContrlBlock for its structure files = FingerPrint.syscalltracer.TracerControlBlock.files # excludeFileName: file whcih should be ingored and not added to the swirl excludeFileName = ['/etc/ld.so.cache'] for lib_swFile in files: swirlFile = PluginManager.getSwirl(lib_swFile, self.swirl) if swirlFile.isLoader(): continue all_dependencies_files = [] #TODO take this for loop out of the for lib_swFile loop for deps in self.swirl.getListSwirlFilesDependentStaticAndDynamic( swirlFile): all_dependencies_files += deps.getPaths() for execFile in files[lib_swFile]: for openedFile in files[lib_swFile][execFile]: # we need to remove some useless files from the opened list # if not depenedencies will be listed as opned files if openedFile not in excludeFileName and not os.path.isdir( openedFile): swirlOpenedFile = PluginManager.getSwirl( openedFile, self.swirl) if swirlOpenedFile.path not in all_dependencies_files: if execFile not in swirlFile.openedFiles: swirlFile.openedFiles[execFile] = [] swirlFile.openedFiles[execFile].append( swirlOpenedFile) self.swirl.ldconf_paths = self._get_ldconf_paths() # get hash and package name for each swirlFile for swf in self.swirl.swirlFiles: #let's skip relative path if swf.path[0] != '$' and os.path.exists(swf.path): swf.md5sum = sergeant.getHash(swf.path, swf.type) #TODO make this code nicer if sergeant.is_special_folder(swf.path): swf.package = None else: swf.package = self._getPackage(swf.path)
class Blotter: def __init__(self, name, fileList, processIDs): """give a file list and a name construct a swirl into memory """ self._pathCache = {} self._detectedPackageManager() self.swirl = Swirl(name, datetime.now()) # # let's see if we have proecss ID we might need to scan for dynamic dependecies # with the help of the /proc FS # # synamicDependencies = { 'binarypath' : [list of file it depends to], # '/bin/bash' : ['/lib/x86_64-linux-gnu/libnss_files-2.15.so', # '/lib/x86_64-linux-gnu/libnss_nis-2.15.so']} dynamicDependecies = {} if processIDs : if not fileList : fileList = [] for proc in processIDs.split(','): proc = proc.strip() # add the binary binaryFile = os.readlink('/proc/' + proc + '/exe') fileList.append( binaryFile ) dynamicDependecies[binaryFile] = [] f=open('/proc/' + proc + '/maps') maps = f.read() f.close() for i in maps.split('\n'): tokens = i.split() if len(tokens) > 5 and 'x' in tokens[1] and os.path.isfile(tokens[5]): # memory mapped area is executable and point to a files dynamicDependecies[binaryFile].append( tokens[5] ) for i in fileList: if os.path.islink(i): swirlFile = SwirlFile( i ) swirlFile.type = 'link' self.swirl.addFile(swirlFile) elif os.path.isfile(i): if i in dynamicDependecies: swirlFile = PluginManager.getSwirl(i) else: swirlFile = PluginManager.getSwirl(i) #self._hashDependencies(swirlFile) self.swirl.addFile(swirlFile) elif os.path.isdir(i): pass else: raise IOError("The file %s cannot be opened." % i) # # we might need to add the dynamic dependencies to the swirl # if they did not get detected already for fileName in dynamicDependecies.keys(): swirlFile = self.swirl.getSwirlFile(fileName) listDepFile = swirlFile.getListDependenciesFiles() for dynamicDepFile in dynamicDependecies[fileName]: if dynamicDepFile not in listDepFile: newDeps = PluginManager.getDependeciesFromPath(dynamicDepFile) for i in newDeps: swirlFile.addDependency( i ) # now that I have all the dependencies in place (both static and dynamic) # I can do the hashing for i in self.swirl.swirlFiles: self._hashDependencies(i) def getSwirl(self): """return the current swirl """ return self.swirl def _hashDependencies(self, swirlFile): """after the swirlFile is created it add md5sum for each dependency """ for newDep in swirlFile.dependencies: if len(newDep.pathList) > 0: # let's check in the cache if newDep.pathList[0] in self._pathCache : newDep.pathList, newDep.hashList, newDep.packageList = self._pathCache[newDep.pathList[0]] else: #new file we have to do it p = newDep.pathList[0] #add all the simbolik links till we hit the real file while os.path.islink(newDep.pathList[-1]) : p = os.readlink(newDep.pathList[-1]) if not os.path.isabs(p): p = os.path.join( os.path.dirname(newDep.pathList[-1]), p) newDep.packageList.append( None ) newDep.hashList.append( None ) newDep.pathList.append( p ) #md5 fileToHash = p newDep.hashList.append(sergeant.getHash(fileToHash, newDep.pluginName)) #package Name package = self._getPackage( fileToHash ) newDep.packageList.append( package ) #update the cache self._pathCache[newDep.pathList[0]] = (newDep.pathList, newDep.hashList, newDep.packageList) def _detectedPackageManager(self): """ set the proper _getPackage*(self, path) function to handle rpm or dpkg based on /etc/issue content""" #rpm based OSes rpmOSs = ["red hat", "fedora", "suse", "centos", "scientific linux"] #dpkg based OSes dpkgOSs = ["debian", "ubuntu"] f=open('/etc/issue') issues=f.read() f.close() if any(os in issues.lower() for os in rpmOSs): self._getPackage = self._getPackageRpm if any(os in issues.lower() for os in dpkgOSs): self._getPackage = self._getPackageDpkg if not '_getPackage' in dir(self): #we could not detect the pakcage manager self._getPackage = lambda p : None def _getPackageDpkg(self, path): """given a path it return the package which provide that path if if finds one only debian system""" cmd1 = ['dpkg', '-S'] cmd2 = ['dpkg-query', '--show', "-f='${Package} ${Version} ${Architecture}'", ] try: (package, returncode) = getOutputAsList(cmd1 + [path]) except subprocess.CalledProcessError: #package not found return None except OSError: #cmd not found return None if returncode != 0 or len(package[0]) == 0: #the file is not tracked return None packageName = package[0].split(':')[0] try: (package, returncode) = getOutputAsList(cmd2 + [packageName]) if returncode != 0: return None return package[0] except subprocess.CalledProcessError: #package not found return None except OSError: #cmd not found return None def _getPackageRpm(self, path): """given a path it return the package which provide that path if if finds one only rpm based system""" cmd = ['rpm', '-qf'] try: (package, returncode) = getOutputAsList(cmd + [path]) if returncode != 0: return None return package[0] except subprocess.CalledProcessError: #package not found return None except OSError: #cmd not found return None
def __init__(self, name, fileList, processIDs, execCmd): """give a file list and a name construct a swirl into memory """ self._detectedPackageManager() self.swirl = Swirl(name, datetime.now()) if execCmd : self.swirl.cmdLine = execCmd # # dependencies discovered with dinamic methods # dynamicDependencies = { 'binarypath' : [list of file it depends to], # '/bin/bash' : ['/lib/x86_64-linux-gnu/libnss_files-2.15.so', # '/lib/x86_64-linux-gnu/libnss_nis-2.15.so']} if execCmd : self._straceCmd(execCmd) # let's see if we have proecss ID we might need to scan for dynamic dependecies # with the help of the /proc FS elif processIDs : for proc in processIDs.split(','): pid = proc.strip() # add the binary tcb = FingerPrint.syscalltracer.TracerControlBlock(pid) tcb.updateSharedLibraries() dynamicDependecies = FingerPrint.syscalltracer.TracerControlBlock.dependencies # set up the fileList for the static dependency detection if not fileList : fileList = [] # it does not work on python 2.5 aka RHEL 5.X # fileList = [f if f[0] == '/' else os.path.normpath(os.getcwd() + '/' + f) for f in fileList] def norm_path(path): if path[0] == '/': return os.path.normpath(path) else: return os.path.normpath(os.getcwd() + '/' + path) fileList = [ norm_path(f) for f in fileList ] fileList = fileList + dynamicDependecies.keys() # add all the fileList to the swirl and figure out all their static libraries for binPath in fileList: if os.path.isfile(binPath): cmd = binPath if binPath in FingerPrint.syscalltracer.TracerControlBlock.cmdline: # the user cmdline could be a symlink so we want to keep track cmd = FingerPrint.syscalltracer.TracerControlBlock.cmdline[binPath][0] cmd = utils.which(cmd) if not cmd : cmd = binPath if cmd and cmd[0] != '/': # hmm we have a relative path pwd = FingerPrint.syscalltracer.TracerControlBlock.get_env_variable(binPath, "PWD") pwd = pwd + '/' + cmd if os.path.isfile(pwd) and os.access(pwd, os.X_OK): cmd = pwd else: # TODO this way to resolving relative path is not 100% correct # it should be done in the syscalltracer cmd = binPath # load the env tmpenv = [] if binPath in FingerPrint.syscalltracer.TracerControlBlock.env: for var in FingerPrint.syscalltracer.TracerControlBlock.env[binPath]: if '=' in var and '=()' not in var: tmpenv.append(var) swirlFile = PluginManager.getSwirl(cmd, self.swirl, tmpenv) self.swirl.execedFiles.append(swirlFile) elif os.path.isdir(binPath): pass else: raise IOError("The file %s cannot be opened." % binPath) # # we might need to add the dynamic dependencies to the swirl # if they did not get detected already for fileName in dynamicDependecies.keys(): swirlFile = PluginManager.getSwirl(fileName, self.swirl) #let's add it to the execed file list if swirlFile not in self.swirl.execedFiles: # TODO remove me... this should never be called self.swirl.execedFiles.append(swirlFile) for dynamicDepFile in dynamicDependecies[fileName]: newSwirlFileDependency = PluginManager.getSwirl(dynamicDepFile, self.swirl, swirlFile.env) #I need to verify it if is static dep or dynamic dep #TODO need to optimize this swirlDependencies = self.swirl.getListSwirlFilesDependentStatic( swirlFile ) if newSwirlFileDependency.path not in [x.path for x in swirlDependencies]: swirlFile.dynamicDependencies.append(newSwirlFileDependency) # let's see if it used some Data files # files is a double dictionary see TraceContrlBlock for its structure files = FingerPrint.syscalltracer.TracerControlBlock.files # excludeFileName: file whcih should be ingored and not added to the swirl excludeFileName = ['/etc/ld.so.cache'] for lib_swFile in files: swirlFile = PluginManager.getSwirl(lib_swFile, self.swirl) if swirlFile.isLoader() : continue all_dependencies_files=[] #TODO take this for loop out of the for lib_swFile loop for deps in self.swirl.getListSwirlFilesDependentStaticAndDynamic(swirlFile): all_dependencies_files += deps.getPaths() for execFile in files[lib_swFile]: for openedFile in files[lib_swFile][execFile]: # we need to remove some useless files from the opened list # if not depenedencies will be listed as opned files if openedFile not in excludeFileName and not os.path.isdir(openedFile): swirlOpenedFile = PluginManager.getSwirl(openedFile, self.swirl) if swirlOpenedFile.path not in all_dependencies_files: if execFile not in swirlFile.openedFiles: swirlFile.openedFiles[execFile] = [] swirlFile.openedFiles[execFile].append(swirlOpenedFile) self.swirl.ldconf_paths = self._get_ldconf_paths() # get hash and package name for each swirlFile for swf in self.swirl.swirlFiles: #let's skip relative path if swf.path[0] != '$' and os.path.exists(swf.path): swf.md5sum = sergeant.getHash(swf.path, swf.type) #TODO make this code nicer if sergeant.is_special_folder( swf.path ) : swf.package = None else: swf.package = self._getPackage(swf.path)