New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS preferences not checking the by-host level. #3501

Closed
groob opened this Issue Jul 27, 2017 · 8 comments

Comments

Projects
None yet
3 participants
@groob
Contributor

groob commented Jul 27, 2017

Issue

If a preference is set at the "Current Host"(as opposed to AnyHost), then osquery will miss it.

Overview

If a preference was set with CFPreferencesSetAppValue it was set for current user/any host, but if the preference was set with CFPreferencesSetValue it might be set at the current-host/by-host level. Less common than any-host but still a possibility.

In a document on preferences, apple notes that preferences could exist in any of the following domains.

cfpref_scopes

This issue is a follow up to #3083 was addressed in #3455.

Repro

Using the script below, we'll set the preference as False for kCFPreferencesCurrentHost, but True for kCFPreferencesAnyHost. Because CurrentHost has a higher order in the search list above, False is actually the effective value for that key.

#!/usr/bin/python

from Foundation import (
        kCFPreferencesAnyUser,
        kCFPreferencesCurrentUser,
        kCFPreferencesAnyHost,
        kCFPreferencesCurrentHost,
        CFPreferencesCopyKeyList,
        CFPreferencesCopyAppValue,
        CFPreferencesCopyValue,
        CFPreferencesSetValue,
        CFPreferencesAppValueIsForced,
        )


BUNDLE_ID = 'com.apple.screensaver'
key = "askForPassword"


# set current host to false
CFPreferencesSetValue(key, False, BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)

# set any host to true
CFPreferencesSetValue(key, True, BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)

Run osqueryi. The reported value is the one set for kCFPreferencesAnyHost

sudo osqueryi --line 'select * from preferences where domain="com.apple.screensaver" AND key="askForPassword" AND username="victor"'
  domain = com.apple.screensaver
     key = askForPassword
  subkey =
   value = true
  forced = 0
username = victor

Now I will use this this script by @gregneagle to read the actual value. The script reads all the possible levels and reports the effective value as well as where it is set.

python fancy_defaults_read.py com.apple.screensaver askForPassword

askForPassword: False
Type: boolean
Defined: /Users/victor/Library/Preferences/ByHost/com.apple.screensaver.xxxx.plist

@groob groob referenced this issue Jul 27, 2017

Closed

Kolide Best Practices Table #57

5 of 6 tasks complete
@groob

This comment has been minimized.

Show comment
Hide comment
@groob

groob Jul 27, 2017

Contributor

An additional note. I was just tinkering with the com.apple.bluetooth PrefKeyServicesEnabled key, by checking/unchecking the bluetooth sharing key in System Preferences.

screenshot 2017-07-27 17 38 47

CFPreferences reports that they key is set in the ByHost level when checked in the GUI.

I am not sure, but it's likely that this behavior is default for many of the system GUI panes that the user interacts with. If so, having osquery read the CurrentHost domain seems very important if we're to rely on the table for compliance.

Running ls -l ~/Library/Preferences/ByHost reveals a long list of preferences being set at that level, mostly by apple, including the .GlobalPreferences.FA01680E-98CA-5557-8F59-7716ECFEE964.plist plist.

Contributor

groob commented Jul 27, 2017

An additional note. I was just tinkering with the com.apple.bluetooth PrefKeyServicesEnabled key, by checking/unchecking the bluetooth sharing key in System Preferences.

screenshot 2017-07-27 17 38 47

CFPreferences reports that they key is set in the ByHost level when checked in the GUI.

I am not sure, but it's likely that this behavior is default for many of the system GUI panes that the user interacts with. If so, having osquery read the CurrentHost domain seems very important if we're to rely on the table for compliance.

Running ls -l ~/Library/Preferences/ByHost reveals a long list of preferences being set at that level, mostly by apple, including the .GlobalPreferences.FA01680E-98CA-5557-8F59-7716ECFEE964.plist plist.

@gregneagle

This comment has been minimized.

Show comment
Hide comment
@gregneagle

gregneagle Jul 27, 2017

Much here boils down to:

  1. Do you want to know all the preferences at every level? or
  2. Do you want to know the effective preference for a given domain/key ?

1 is more thorough, but there's potentially a lot of noise there. 2 is probably what most people want to know if they are querying prefs for compliance monitoring.

gregneagle commented Jul 27, 2017

Much here boils down to:

  1. Do you want to know all the preferences at every level? or
  2. Do you want to know the effective preference for a given domain/key ?

1 is more thorough, but there's potentially a lot of noise there. 2 is probably what most people want to know if they are querying prefs for compliance monitoring.

@groob

This comment has been minimized.

Show comment
Hide comment
@groob

groob Jul 27, 2017

Contributor

@gregneagle #2

Most of it was addressed by @theopolis in #3455, but that PR did not account for ByHost domains.
We don't need to expose what level it's set at (although would be a nice column), just the effective value.

Contributor

groob commented Jul 27, 2017

@gregneagle #2

Most of it was addressed by @theopolis in #3455, but that PR did not account for ByHost domains.
We don't need to expose what level it's set at (although would be a nice column), just the effective value.

@gregneagle

This comment has been minimized.

Show comment
Hide comment
@gregneagle

gregneagle Jul 27, 2017

So you should always be using CFPreferencesCopyAppValue and never CFPreferencesCopyValue.

gregneagle commented Jul 27, 2017

So you should always be using CFPreferencesCopyAppValue and never CFPreferencesCopyValue.

@groob

This comment has been minimized.

Show comment
Hide comment
@groob

groob Jul 27, 2017

Contributor

@gregneagle osquery runs as root though, you'd have to check the given preference as a user since CFPreferencesCopyAppValue assumes CurrentUser, no?

Contributor

groob commented Jul 27, 2017

@gregneagle osquery runs as root though, you'd have to check the given preference as a user since CFPreferencesCopyAppValue assumes CurrentUser, no?

@gregneagle

This comment has been minimized.

Show comment
Hide comment
@gregneagle

gregneagle commented Jul 27, 2017

Yup.

@gregneagle

This comment has been minimized.

Show comment
Hide comment
@gregneagle

gregneagle Jul 27, 2017

But it's the only way to be managed preferences aware.

gregneagle commented Jul 27, 2017

But it's the only way to be managed preferences aware.

@gregneagle

This comment has been minimized.

Show comment
Hide comment
@gregneagle

gregneagle Jul 27, 2017

Your table above under Overview needs a row 0 listing managed preferences.

gregneagle commented Jul 27, 2017

Your table above under Overview needs a row 0 listing managed preferences.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment