def get_vulnapps(): """ Get a list of apps with old Sparkle frameworks, and check SUFeedURL for http:// If Sparkle framework version not found, adds to vulnerable list. """ # Get all apps mdfind knows about apps = subprocess.check_output(['/usr/bin/mdfind', 'kind:app']) sparkle_info = '/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Info.plist' app_info = '/Contents/Info.plist' vulnerableapp_list = [] for app in apps.splitlines(): # If the app has a sparkle framework if os.path.exists(app + sparkle_info): # Try to get a version out of Sparkle's framework, returns None without exception if missing sparkle_version = CFPreferencesCopyAppValue('CFBundleShortVersionString', app + sparkle_info) if not sparkle_version: sparkle_version = CFPreferencesCopyAppValue('CFBundleVersion', app + sparkle_info) # Check for a SUFeedURL sparkle_feed_url = CFPreferencesCopyAppValue('SUFeedURL', app + app_info) bundle_id = CFPreferencesCopyAppValue('CFBundleIdentifier', app + app_info) # If we have a SUFeedURL if sparkle_feed_url and not sparkle_feed_url.startswith('https://'): # If Sparkle version is less than 1.13.1 & SUFeedURL is http if not sparkle_version: vulnerableapp_list.append(app + ' - ' + bundle_id) elif LooseVersion(sparkle_version) < LooseVersion('1.13.1'): vulnerableapp_list.append(app + ' - ' + bundle_id) return vulnerableapp_list
def fact(): '''Returns the icloud drive status''' result = 'None' console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] plist = '/Users/%s/Library/Preferences/MobileMeAccounts.plist' % console_user if os.path.exists(plist): d = CFPreferencesCopyAppValue('Accounts', plist)[0]['Services'][2] if d: result = d.get('Enabled', False) return {factoid: result}
def fact(): """Returns the icloud drive status""" result = "None" console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] plist = "/Users/%s/Library/Preferences/MobileMeAccounts.plist" % console_user if os.path.exists(plist): d = CFPreferencesCopyAppValue("Accounts", plist)[0]["Services"][2] if d: result = d.get("Enabled", False) return {factoid: result}
def _get_macos_pref(self, key): """Get a specific macOS preference key.""" value = CFPreferencesCopyAppValue(key, BUNDLE_ID) if isinstance(value, NSNumber): value = int(value) elif isinstance(value, NSArray): value = list(value) elif isinstance(value, NSDictionary): value = dict(value) # RECIPE_REPOS is a dict of dicts for k, v in value.items(): if isinstance(v, NSDictionary): value[k] = dict(v) return value
def fact(): """Returns the gatekeeper version""" plist = "/private/var/db/gkopaque.bundle/Contents/version.plist" if os.path.exists(plist): result = CFPreferencesCopyAppValue("CFBundleShortVersionString", plist) return {factoid: result}
def pref(pref_name, bundle_id=BUNDLE_ID): """ Return a preference and whether exists or not. Since this uses CFPreferencesCopyAppValue, Preferences can be defined several places. Precedence is: - MCX/configuration profile - /var/root/Library/Preferences/ByHost/ManagedInstalls.XXXXXX.plist - /var/root/Library/Preferences/ManagedInstalls.plist - /Library/Preferences/ManagedInstalls.plist - .GlobalPreferences defined at various levels (ByHost, user, system) - default_prefs defined here. """ pref_value = CFPreferencesCopyAppValue(pref_name, bundle_id) if pref_value is None: pref_value = DEFAULT_PREFS.get(pref_name) # we're using a default value. We'll write it out to # /Library/Preferences/<BUNDLE_ID>.plist for admin # discoverability if pref_value is not None: set_pref(pref_name, pref_value) if isinstance(pref_value, NSDate): # convert NSDate/CFDates to strings pref_value = str(pref_value) return pref_value
def fact(): '''Returns the gatekeeper version''' plist = '/private/var/db/gkopaque.bundle/Contents/version.plist' if os.path.exists(plist): result = CFPreferencesCopyAppValue('CFBundleShortVersionString', plist) return {factoid: result}
def fact(): """Returns the software update server""" sus = "None" sus = CFPreferencesCopyAppValue( "CatalogURL", "/Library/Preferences/com.apple.SoftwareUpdate.plist") return {factoid: str(sus)}
def fact(): '''Returns the sentinel version''' version = 'None' plist = '/Library/Sentinel/sentinel-agent.bundle/Contents/Info.plist' if os.path.exists(plist): version = CFPreferencesCopyAppValue('CFBundleShortVersionString', plist) return {factoid: version}
def fact(): '''Returns the software update server''' sus = 'None' sus = CFPreferencesCopyAppValue( 'CatalogURL', '/Library/Preferences/com.apple.SoftwareUpdate.plist') return {factoid: str(sus)}
def fact(): """Returns the status of automatic installation of config data""" status = "disabled" pref = CFPreferencesCopyAppValue( "ConfigDataInstall", "/Library/Preferences/com.apple.SoftwareUpdate") if pref: status = "enabled" return {factoid: status}
def main(): # pylint: disable=too-many-locals '''Run all our fact plugins and collect their data''' module_dir = os.path.join(os.path.dirname(__file__), 'facts') facts = {} # find all the .py files in the 'facts' dir fact_files = [ os.path.splitext(name)[0] for name in os.listdir(module_dir) if name.endswith('.py') and not name == '__init__.py'] for name in fact_files: # load each file and call its fact() function file_path = os.path.join(module_dir, name + '.py') try: # Python 3.4 and higher only spec = importlib.util.spec_from_file_location(name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) facts.update(module.fact()) # pylint: disable=broad-except except BaseException as err: print(u'Error %s in file %s' % (err, file_path), file=sys.stderr) # pylint: enable=broad-except if facts: # Handle cases when facts return None - convert them to empty # strings. for key, value in facts.items(): if value is None: facts[key] = '' # Read the location of the ManagedInstallDir from ManagedInstall.plist bundle_id = 'ManagedInstalls' pref_name = 'ManagedInstallDir' managedinstalldir = CFPreferencesCopyAppValue(pref_name, bundle_id) conditionalitemspath = os.path.join( managedinstalldir, 'ConditionalItems.plist') conditional_items = {} # read the current conditional items if os.path.exists(conditionalitemspath): try: with open(conditionalitemspath, "rb") as file: conditional_items = plistlib.load(file) except (IOError, OSError, ExpatError) as err: pass # update the conditional items conditional_items.update(facts) # and write them out try: with open(conditionalitemspath, "wb") as file: plistlib.dump(conditional_items, file) except (IOError, OSError) as err: print('Couldn\'t save conditional items: %s' % err, file=sys.stderr)
def fact(): '''Returns the status of automatic installation of config data''' status = "disabled" pref = CFPreferencesCopyAppValue('ConfigDataInstall', '/Library/Preferences/com.apple.SoftwareUpdate') if pref: status = "enabled" return {factoid: status}
def fact(): """Returns the java plugin version""" result = "None" plist = "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Info.plist" if os.path.exists(plist): result = CFPreferencesCopyAppValue("CFBundleVersion", plist) return {factoid: result}
def fact(): '''Returns the java plugin version''' result = 'None' plist = '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Info.plist' if os.path.exists(plist): result = CFPreferencesCopyAppValue('CFBundleVersion', plist) return {factoid: result}
def data(): '''Returns the number of updates available''' result = 'None' plist = '/Library/Preferences/com.apple.SoftwareUpdate.plist' if os.path.exists(plist): result = CFPreferencesCopyAppValue('LastUpdatesAvailable', plist) return {number: result}
def fact(): '''Gets the ADSite from the nomad plist''' result = '' username = SCDynamicStoreCopyConsoleUser(None, None, None)[0] if username: result = CFPreferencesCopyAppValue('ADSite', '/Users/%s/Library/Preferences/com.trusourcelabs.NoMAD.plist' % username) return {factoid: result}
def fact(): """Returns the dsbindtimeout setting""" result = "None" plist = "/Library/Preferences/com.apple.loginwindow.plist" if plist and os.path.exists(plist): result = CFPreferencesCopyAppValue("DSBindTimeout", plist) return {factoid: str(result)}
def check_detectx_version(): """Returns boolean whether or not the installed version of DetectX meets or exceeds the specified MINIMUM_VERSION""" result = False plist = os.path.join(DX, 'Contents/Info.plist') if os.path.exists(plist): installed_version = CFPreferencesCopyAppValue('CFBundleVersion', plist) if LooseVersion(installed_version) >= LooseVersion(MINIMUM_VERSION): result = True return result
def pref(pref_name): """Returns a preference from com.apple.SoftwareUpdate. Uses CoreFoundation. Args: pref_name: str preference name to get. """ return CFPreferencesCopyAppValue(pref_name, APPLE_SOFTWARE_UPDATE_PREFS_DOMAIN)
def fact(): """Returns the status of automatic downloading of software updates""" status = "disabled" pref = CFPreferencesCopyAppValue( "AutomaticDownload", "/Library/Preferences/com.apple.SoftwareUpdate" ) if pref: status = "enabled" return {factoid: status}
def fact(): '''Returns the icloud status''' result = 'None' console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] plist = '/Users/%s/Library/Preferences/MobileMeAccounts.plist' % console_user if os.path.exists(plist): d = CFPreferencesCopyAppValue('Accounts', plist) result = d[0]['LoggedIn'] if d else False return {factoid: result}
def _get_macos_pref(self, key): """Get a specific macOS preference key.""" value = CFPreferencesCopyAppValue(key, BUNDLE_ID) # Casting NSArrays and NSDictionaries to native Python types. # This a workaround for 10.6, where PyObjC doesn't seem to # support as many common operations such as list concatenation # between Python and ObjC objects. if isinstance(value, NSArray) or isinstance(value, NSDictionary): value = Conversion.pythonCollectionFromPropertyList(value) return value
def fact(): """Returns the icloud status""" result = "None" console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] plist = "/Users/%s/Library/Preferences/MobileMeAccounts.plist" % console_user if os.path.exists(plist): d = CFPreferencesCopyAppValue("Accounts", plist) result = d[0]["LoggedIn"] if d else False return {factoid: result}
def fact(): """Returns the java vendor (apple or oracle)""" result = "None" plist = "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Info.plist" if os.path.exists(plist): result = CFPreferencesCopyAppValue("CFBundleIdentifier", plist).split(".")[1] return {factoid: result}
def fact(): '''Returns the dsbindtimeout setting''' result = 'None' plist = '/Library/Preferences/com.apple.loginwindow.plist' if plist and os.path.exists(plist): result = CFPreferencesCopyAppValue('DSBindTimeout', plist) return {factoid: str(result)}
def fact(): '''Returns the java vendor (apple or oracle)''' result = 'None' plist = '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Info.plist' if os.path.exists(plist): result = CFPreferencesCopyAppValue('CFBundleIdentifier', plist).split('.')[1] return {factoid: result}
def fact(): '''Returns the channel name for Office updates''' result = 'None' console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] plist = '/Users/%s/Library/Preferences/com.microsoft.autoupdate2.plist' % console_user if os.path.exists(plist): result = CFPreferencesCopyAppValue('ChannelName', plist) return {factoid: result}
def fact(): '''Returns the icloud desktop sync status''' result = False console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] plist = '/Users/%s/Library/Preferences/MobileMeAccounts.plist' % console_user if os.path.exists(plist): d = CFPreferencesCopyAppValue('Accounts', plist)[0]['Services'][2] sync_active = d.get('Enabled', False) files = glob.glob( '/Users/%s/Library/Mobile Documents/com~apple~CloudDocs/*' % console_user) if sync_active and files: for f in files: if os.path.islink(f): result = True break return {factoid: result}
def get_user_config(): # Get the MAU's config as seen from the current or last person logged in # Because some settings are user specific try: mau_config = FoundationPlist.readPlist( get_user_path() + "/Library/Preferences/com.microsoft.autoupdate2.plist") mau_config_items = {} for item in mau_config: if item == 'UpdateCache': mau_config_items['updatecache'] = mau_config[item] elif item == 'ManifestServer': mau_config_items['manifestserver'] = mau_config[item] elif item == 'AutoUpdateVersion': mau_config_items['autoupdateversion'] = mau_config[item] elif item == 'ChannelName': mau_config_items['channelname'] = mau_config[item] elif item == 'HowToCheck': mau_config_items['howtocheck'] = mau_config[item] elif item == 'LastCheckForUpdates' or item == 'LastUpdate': if mau_config[item] != "Dec 29, 1 at 7:03:58 PM": pattern = '%Y-%m-%d %H:%M:%S +0000' mau_config_items['lastcheckforupdates'] = int( time.mktime( time.strptime( str(mau_config[item]).replace(" at ", ", "), pattern))) elif item == 'StartDaemonOnAppLaunch': mau_config_items['startdaemononapplaunch'] = to_bool( mau_config[item]) elif item == 'Applications': mau_config_items[ 'registeredapplications'] = process_registered_apps( mau_config) # Add in update information if enabled msupdate_check_enabled = to_bool( CFPreferencesCopyAppValue('msupdate_check_enabled', 'org.munkireport.ms_office')) if os.path.exists( '/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate' ) and msupdate_check_enabled == 1: mau_config_items = get_msupdate_update_check(mau_config_items) mau_config_items['msupdate_check_enabled'] = 1 else: mau_config_items['msupdate_check_enabled'] = 0 return (mau_config_items) except Exception: return {}
def get_pref(key, domain=BUNDLE_ID): """Return a single pref value (or None) for a domain.""" value = CFPreferencesCopyAppValue(key, domain) # Casting NSArrays and NSDictionaries to native Python types. # This a workaround for 10.6, where PyObjC doesn't seem to # support as many common operations such as list concatenation # between Python and ObjC objects. if isinstance(value, NSArray): value = list(value) elif isinstance(value, NSDictionary): value = dict(value) return value