def scanLaunchItems(self, directories): #launch items launchItems = [] #results results = [] #expand directories # ->ensures '~'s are expanded to all user's directories = utils.expandPaths(directories) #get all files (plists) in launch daemon/agent directories for directory in directories: #dbg msg utils.logMessage(utils.MODE_INFO, 'scanning %s' % directory) #get launch daemon/agent launchItems.extend(glob.glob(directory + '*')) #process # ->get all auto-run launch services autoRunItems = self.autoRunBinaries(launchItems) #iterate over all auto-run items (list of the plist and the binary) # ->create file object and add to results for autoRunItem in autoRunItems: #create and append results.append(file.File(autoRunItem[0], autoRunItem[1])) return results
def scanLaunchItems(directories): #launch items launchItems = [] #results results = [] #expand directories # ->ensures '~'s are expanded to all user's directories = utils.expandPaths(directories) #get all files (plists) in launch daemon/agent directories for directory in directories: #dbg msg utils.logMessage(utils.MODE_INFO, 'scanning %s' % directory) #get launch daemon/agent launchItems.extend(glob.glob(directory + '*')) #process # ->get all auto-run launch services autoRunItems = autoRunBinaries(launchItems) #iterate over all auto-run items (list of the plist and the binary) # ->create file object and add to results for autoRunItem in autoRunItems: #create and append results.append(file.File(autoRunItem[0], autoRunItem[1])) return results
def scanLaunchItems(directories): #launch items launchItems = [] #expand directories # ->ensures '~'s are expanded to all user's directories = utils.expandPaths(directories) #get all files (plists) in launch daemon/agent directories for directory in directories: #dbg msg utils.logMessage(utils.MODE_INFO, 'scanning %s' % directory) #get launch daemon/agent plist launchItems.extend(glob.glob(directory + '*')) #check all plists for DYLD_INSERT_LIBRARIES # ->for each found, creates file object return scanPlists(launchItems, LAUNCH_ITEM_DYLD_KEY)
def findBinaryForOveride(self, bundleID): #the binary binary = None #wrap try: #expand launch daemons and agents directories directories = utils.expandPaths(LAUNCH_D_AND_A_DIRECTORIES) #attempt to find bundle ID in any of the directories for directory in directories: #init candidate plist path plistPath = directory + bundleID + '.plist' #check if there if candidate plist exists if not os.path.exists(plistPath): #skip continue #load plist plistData = utils.loadPlist(plistPath) #check if 'ProgramArguments' exists if 'ProgramArguments' in plistData: #extract program arguments programArguments = plistData['ProgramArguments'] #check if its a file if os.path.isfile(programArguments[0]): #happy, got binary for bundle id binary = programArguments[0] #bail break #check if 'Program' key contains binary # ->e.g. /System/Library/LaunchAgents/com.apple.mrt.uiagent.plist elif 'Program' in plistData: #check if its a file if os.path.isfile(plistData['Program']): #happy, got binary for bundle id binary = plistData['Program'] #bail break #ignore exceptions except: #ignore pass return binary
def scanExtensionsChrome(self): #results results = [] #get list of all chrome's preferences file # ->these contain JSON w/ info about all extensions chromePreferences = utils.expandPaths(CHROME_DIRECTORIES) #parse each for extensions for chromePreferenceFile in chromePreferences: #wrap try: #open preference file and load it with open(chromePreferenceFile, 'r') as file: #load as JSON preferences = json.loads(file.read()) if not preferences: #skip/try next continue #the list of extensions are stored in the 'settings' key extensions = preferences['extensions']['settings'] #scan all extensions # ->skip ones that are disabled, white listed, etc # TODO: skip ones that don't exist (path) for extensionKey in extensions: #dictionary for extension info extensionInfo = {} #save key extensionInfo['id'] = extensionKey #get extension dictionary currentExtension = extensions[extensionKey] #skip extensions if they are disabled # ->'state' set to 0 means disabled if 'state' in currentExtension and not currentExtension['state']: #skip continue #skip extensions that are installed by default # ->assuming these are legit/ok if 'was_installed_by_default' in currentExtension and currentExtension['was_installed_by_default']: #skip continue #extract manifest # ->contains name, description, etc if 'manifest' in currentExtension: manifest = currentExtension['manifest'] if manifest: #extract name if 'name' in manifest: #name extensionInfo['name'] = manifest['name'] #extract description if 'description' in manifest: #description extensionInfo['description'] = manifest['description'] #extract path if 'path' in currentExtension: #create full path extensionInfo['path'] = os.path.dirname(chromePreferenceFile) + '/Extensions/' + currentExtension['path'] #create and append results.append(extension.Extension(extensionInfo)) #ignore exceptions except Exception, e: print e traceback.print_exc() #skip/try next continue
def scanExtensionsChrome(self): #results results = [] #get list of all chrome's preferences file # ->these contain JSON w/ info about all extensions chromePreferences = utils.expandPaths(CHROME_DIRECTORIES) #parse each for extensions for chromePreferenceFile in chromePreferences: #wrap try: #open preference file and load it with open(chromePreferenceFile, 'r') as file: #load as JSON preferences = json.loads(file.read()) if not preferences: #skip/try next continue #the list of extensions are stored in the 'settings' key extensions = preferences['extensions']['settings'] #scan all extensions # ->skip ones that are disabled, white listed, etc for extensionKey in extensions: #dictionary for extension info extensionInfo = {} #save key extensionInfo['id'] = extensionKey #get extension dictionary currentExtension = extensions[extensionKey] #skip extensions if they are disabled # ->'state' set to 0 means disabled if 'state' in currentExtension and not currentExtension['state']: #skip continue #skip extensions that are installed by default # ->assuming these are legit/ok if 'was_installed_by_default' in currentExtension and currentExtension['was_installed_by_default']: #skip continue #extract manifest # ->contains name, description, etc if 'manifest' in currentExtension: manifest = currentExtension['manifest'] if manifest: #extract name if 'name' in manifest: #name extensionInfo['name'] = manifest['name'] #extract description if 'description' in manifest: #description extensionInfo['description'] = manifest['description'] #extract path if 'path' in currentExtension: #sometimes path is (already) full path # e.g. /Applications/Google Chrome.app/.../Google Chrome Framework.framework/Resources/<blah> if os.path.exists(currentExtension['path']): #save extensionInfo['path'] = currentExtension['path'] #generally though the full path has to be built else: #build full path extensionInfo['path'] = os.path.dirname(chromePreferenceFile) + '/Extensions/' + currentExtension['path'] #ignore path's that don't exist # ->uninstallers may not clean up things correctly if not os.path.exists(extensionInfo['path']): #skip continue #create and append results.append(extension.Extension(extensionInfo)) #ignore exceptions except Exception, e: #leave in err msg (for now) print e traceback.print_exc() #skip/try next continue
def scanExtensionsChrome(self): #results results = [] #get list of all chrome's preferences file # ->these contain JSON w/ info about all extensions chromePreferences = utils.expandPaths(CHROME_DIRECTORIES) #parse each for extensions for chromePreferenceFile in chromePreferences: #wrap try: #open preference file and load it with open(chromePreferenceFile, 'r') as file: #load as JSON preferences = json.loads(file.read()) if not preferences: #skip/try next continue # pref file just has the list of ids, # everything else we might want is in # os.path.dirname(chromePreferenceFile) + '/Extensions/' + id + version + manifest.json # manifest has name, description extensions = preferences['extensions']['install_signature'][ 'ids'] #scan all extensions # ->skip ones that are disabled, white listed, etc for extensionKey in extensions: #dictionary for extension info extensionInfo = {} #save key extensionInfo['id'] = extensionKey extensionPath = os.path.dirname( chromePreferenceFile ) + '/Extensions/' + extensionInfo['id'] extdir = os.listdir(extensionPath) for verdir in extdir: manpath = extensionPath + '/' + verdir + '/manifest.json' with open(manpath, 'r') as file: manifest = json.loads(file.read()) if not manifest: continue extensionInfo['path'] = manpath extensionInfo['name'] = manifest['name'] extensionInfo['description'] = manifest['description'] #create and append results.append(extension.Extension(extensionInfo)) #ignore exceptions except Exception, e: #leave in err msg (for now) print e traceback.print_exc() #skip/try next continue
def scan(self): #results results = [] #dbg utils.logMessage(utils.MODE_INFO, 'running scan') #init results # ->for for login hook results.append(self.initResults(LOGIN_HOOK_NAME, LOGIN_HOOK_DESCRIPTION)) #init results # ->for logout hook results.append(self.initResults(LOGOUT_HOOK_NAME, LOGOUT_HOOK_DESCRIPTION)) #expand all login/out files logInOutFiles = utils.expandPaths(LOGIN_WINDOW_FILES) #scan each file for logInOutFile in logInOutFiles: #load plist plistData = utils.loadPlist(logInOutFile) #make sure plist loaded if plistData: #grab login hook if 'LoginHook' in plistData: #check if its a file if os.path.isfile(plistData['LoginHook']): #save file results[0]['items'].append(file.File(plistData['LoginHook'])) #likely a command # ->could be file that doesn't exist, but ok to still report else: #save command results[0]['items'].append(command.Command(plistData['LoginHook'], logInOutFile)) #grab logout hook if 'LogoutHook' in plistData: #check if its a file if os.path.isfile(plistData['LogoutHook']): #save file results[1]['items'].append(file.File(plistData['LogoutHook'])) #likely a command # ->could be file that doesn't exist, but ok to still report else: #save command results[1]['items'].append(command.Command(plistData['LogoutHook'], logInOutFile)) return results