예제 #1
0
 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)
예제 #2
0
    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)
예제 #3
0
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
예제 #4
0
    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)