Skip to content
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

tables: implement password_policy table for macOS #7594

Merged
merged 8 commits into from
Jun 30, 2022

Conversation

sharvilshah
Copy link
Member

Uses OpenDirectory and output is similar to apple's built-in pwpolicy command.

osquery> select * from password_policy;
+-------------------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------+
| policy_identifier                                                       | policy_attribute                                               | policy_description                                        |
+-------------------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------+
| ProfilePayload:9c546b0a-53f7-4f33-8bc6-84ec075817f5:minLength           | policyAttributePassword matches '.{10,}'                       | Contain at least 10 characters.                           |
| com.apple.defaultpasswordpolicy.fde                                     | policyAttributePassword matches '.{4,}+'                       | Enter a password that is four characters or more.         |
| ProfilePayload:9c546b0a-53f7-4f33-8bc6-84ec075817f5:requireAlphanumeric | policyAttributePassword matches '^(?=.*[0-9])(?=.*[a-zA-Z]).+' | Contain at least one number and one alphabetic character. |
+-------------------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------+

This covers default policy (com.apple.defaultpasswordpolicy.fde in the example above) as well as ones pushed by MDM profiles.

@@ -0,0 +1,11 @@
table_name("password_policy")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least on my mac, this is documented both as having global policies, as well as per-user policies. Any thoughts about how to handle that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the reason I used ODNodeCopyAccountPolicies API call is to get both global and per-user policies. I am not sure on other platform, but windows has NetUserModalsGet in it's win32 API, from their description:

The NetUserModalsGet function retrieves global information for all users and global groups in the security database, which is the security accounts manager (SAM) database or, in the case of domain controllers, the Active Directory.

From: https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netusermodalsget?redirectedfrom=MSDN

I am guessing that should cover it? I am not sure on Linux

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My windows internals knowledge is lacking, but based on above it seems we can continue with password_policy as the table name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is both global, and per-user policy, how is that reflected in this schema? Can users have different polices? How is that represented.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On macOS, the concept of user policies and global policies has been deprecated for a while now. From the man page:

Account Policies
Account policies are the replacement for the deprecated legacy global and user policies. Account policies are specified as a dictionary containing three keys, one key for each policy category. Note that the dictionary is
not required to contain all of the policy categories

The policy_identifier is something that a user can set (either manually or via MDM). Apple supplied policy has identifiers that start with com.apple., and currently Apple only supplies one policy by default -- where if filevault gets enabled, the password has to be 4 characters or more.

For other platforms, if there is a clear user/global distinction, I guess one can use the extended schema for the table.

osquery/tables/system/darwin/password_policy.cpp Outdated Show resolved Hide resolved
osquery/tables/system/darwin/password_policy.cpp Outdated Show resolved Hide resolved
osquery/tables/system/darwin/password_policy.cpp Outdated Show resolved Hide resolved
osquery/tables/system/darwin/password_policy.cpp Outdated Show resolved Hide resolved
osquery/tables/system/darwin/password_policy.cpp Outdated Show resolved Hide resolved
@sharvilshah
Copy link
Member Author

Added one more column to make it easy to show the relevant data:

osquery> select * from password_policy;
+-------------------------------------------------------------------------+---------------------+----------------------------------------------------------------+-----------------------------------------------------------+
| policy_identifier                                                       | policy_attribute    | policy_content                                                 | policy_description                                        |
+-------------------------------------------------------------------------+---------------------+----------------------------------------------------------------+-----------------------------------------------------------+
| ProfilePayload:9c546b0a-53f7-4f33-8bc6-84ec075817f5:minLength           | minLength           | policyAttributePassword matches '.{10,}'                       | Contain at least 10 characters.                           |
| com.apple.defaultpasswordpolicy.fde                                     |                     | policyAttributePassword matches '.{4,}+'                       | Enter a password that is four characters or more.         |
| ProfilePayload:9c546b0a-53f7-4f33-8bc6-84ec075817f5:requireAlphanumeric | requireAlphanumeric | policyAttributePassword matches '^(?=.*[0-9])(?=.*[a-zA-Z]).+' | Contain at least one number and one alphabetic character. |
+-------------------------------------------------------------------------+---------------------+----------------------------------------------------------------+-----------------------------------------------------------+

Final review @directionless?

@sharvilshah sharvilshah requested a review from zwass June 22, 2022 23:09
@sharvilshah
Copy link
Member Author

Hey @directionless,

Did a little bit more digging and testing, there is another obscure-ish API to grab account policies for the user, in case there is a per-user policy. I have implemented that too, and I added a uid column when that's the case.

squery> select * from password_policy;
+-----+-------------------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------+
| uid | policy_identifier                                                       | policy_content                                                 | policy_description                                        |
+-----+-------------------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------+
|     | ProfilePayload:9c546b0a-53f7-4f33-8bc6-84ec075817f5:minLength           | policyAttributePassword matches '.{10,}'                       | Contain at least 10 characters.                           |
|     | com.apple.defaultpasswordpolicy.fde                                     | policyAttributePassword matches '.{4,}+'                       | Enter a password that is four characters or more.         |
|     | ProfilePayload:9c546b0a-53f7-4f33-8bc6-84ec075817f5:requireAlphanumeric | policyAttributePassword matches '^(?=.*[0-9])(?=.*[a-zA-Z]).+' | Contain at least one number and one alphabetic character. |
| 502 | com.apple.policy.legacy.minChars                                        | policyAttributePassword matches '.{12,}?'                      | Must be a minimum of 12 characters in length              |
+-----+-------------------------------------------------------------------------+----------------------------------------------------------------+-----------------------------------------------------------+

In this example above, I created a new user, and set that user's account policy to have minimum length of the password to be 12 characters.

zwass
zwass previously approved these changes Jun 30, 2022
Copy link
Member

@zwass zwass left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM unless those objects do need to be released.

Copy link
Member

@zwass zwass left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet!

@sharvilshah
Copy link
Member Author

Screen Shot 2022-06-30 at 11 41 18 AM

Hooked it up to the profiler, and no leaky objects are detected for password_policy queries!

@sharvilshah sharvilshah merged commit be644ec into osquery:master Jun 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants