diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..a8dad46d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,46 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + + + +### Summary + +(Summarize the bug encountered concisely) + +### Steps to reproduce + +(How one can reproduce the issue - this is very important) + +### Operating System version + +(macOS Version and build) + +### What is the current *bug* behavior? + +(What actually happens) + +### What is the expected *correct* behavior? + +(What you should see instead) + +### Relevant logs and/or screenshots + +(Paste any relevant logs - please use code blocks (```) to format console output, logs, and code as it's tough to read otherwise.) + +### Output of checks + +(Paste any output that occurs with the bug) + +### Possible fixes + +(If you can, link to the line of code that might be responsible for the problem) diff --git a/.github/ISSUE_TEMPLATE/feature-proposal.md b/.github/ISSUE_TEMPLATE/feature-proposal.md new file mode 100644 index 00000000..cbf0922e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-proposal.md @@ -0,0 +1,40 @@ +--- +name: Feature Proposal +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +### Problem to solve + + + +### Intended users + + + +### Further details + + + +### Proposal + + + +### Documentation + + + +### Testing + + + +### What does success look like, and how can we measure that? + + + +### Links / references + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5ca0973f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store + diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc new file mode 100644 index 00000000..cbf6f3fb --- /dev/null +++ b/CHANGELOG.adoc @@ -0,0 +1,12 @@ += Changelog + +This document provides a high-level view of the changes to the macOS Security Compliance Project. + +== [0.9.0] - 2020-06-11 + +Initial Public release (PRE-RELEASE) + + + + + diff --git a/README.adoc b/README.adoc new file mode 100644 index 00000000..7b810c5a --- /dev/null +++ b/README.adoc @@ -0,0 +1,57 @@ += macOS Security Compliance Project +// settings: +:idprefix: +:idseparator: - +ifndef::env-github[:icons: font] +ifdef::env-github[] +:status: +//:outfilesuffix: .adoc +:caution-caption: :fire: +:important-caption: :exclamation: +:note-caption: :paperclip: +:tip-caption: :bulb: +:warning-caption: :warning: +endif::[] +:uri-org: https://github.com/usnistgov +:uri-repo: {uri-org}/macos_security + + +ifdef::status[] +image:https://badgen.net/badge/icon/apple?icon=apple&label, link=[https://www.apple.com/] +image:https://badgen.net/badge/icon/10.15?icon=apple&label, link=[https://www.apple.com/macos] +endif::[] + +The macOS security compliance project is an link:LICENSE.md[open source] effort that can be used to create customized security baselines of technical security controls, which are mapped to various compliance frameworks such as: NIST 800-53, DISA STIG, FINRA, and HIPAA requirements. This is a joint project of federal operational IT Security staff from the National Institute of Standards (NIST), National Aeronautics and Space Administration (NASA), Defense Information Systems Agency (DISA), and Los Alamos National Laboratory (LANL). + +To learn more about the project, please see the {uri-repo}/wiki[wiki]. + +== Usage + +Civilian agencies are to use the National Checklist Program as required by https://csrc.nist.gov/publications/detail/sp/800-70/rev-4/final[NIST 800-70]. + +[NOTE] +==== +Part 39 of the Federal Acquisition Regulations, section 39.101 paragraph (c) states, “In acquiring information technology, agencies shall include the appropriate information technology security policies and requirements, including use of common security configurations available from the National Institute of Standards and Technology’s website at https://checklists.nist.gov. Agency contracting officers should consult with the requiring official to ensure the appropriate standards are incorporated.” +==== + +== Authors + +[width="100%",cols="1,1"] +|=== +|Bob Gendler|National Institute of Standards and Technology +|Allen Golbig|National Aeronautics and Space Administration +|Dan Brodjieski|Defense Information Systems Agency +|Jason Blake|National Institute of Standards and Technology +|Blair Heiserman|National Institute of Standards and Technology +|Joshua Glemza|National Aeronautics and Space Administration +|Elyse Anderson|National Aeronautics and Space Administration +|Paige Ramsey|Los Alamos National Laboratory +|=== + +== Changelog + +Refer to the link:CHANGELOG.adoc[CHANGELOG] for a complete list of changes. + +== NIST Disclaimer + +Any identification of commercial or open-source software in this document is done so purely in order to specify the methodology adequately. Such identification is not intended to imply recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that the software identified are necessarily the best available for the purpose. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 05b9e07d..00000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# macOS Security Compliance Project -[![](https://badgen.net/badge/icon/apple?icon=apple&label)](https://www.apple.com/)[![](https://badgen.net/badge/icon/10.15?icon=apple&label)](https://www.apple.com/macos) - -The macOS security compliance project can be used to create customized security baselines of technical security controls, which are mapped to various compliance frameworks. diff --git a/baselines/all_rules.yaml b/baselines/all_rules.yaml new file mode 100644 index 00000000..2d23b465 --- /dev/null +++ b/baselines/all_rules.yaml @@ -0,0 +1,230 @@ +title: "Apple macOS 10.15 (Catalina) Security Configuration - All the rules" +description: | + This guide describes the actions to take when securing a macOS 10.15 system using every available rule. +profile: + - section: "Auditing" + rules: + - audit_acls_files_configure + - audit_acls_files_mode_configure + - audit_acls_folder_wheel_configure + - audit_acls_folders_configure + - audit_acls_folders_mode_configure + - audit_configure_capacity_notify + - audit_failure_halt + - audit_files_group_configure + - audit_files_owner_configure + - audit_flags_aa_configure + - audit_flags_ad_configure + - audit_flags_failed_file_read_restriction_enforced + - audit_flags_failed_file_write_access_restriction_enforced + - audit_flags_file_attr_mod_access_restriction_enforced + - audit_flags_lo_configure + - audit_folder_group_configure + - audit_folder_owner_configure + - audit_retention_one_week_configure + - audit_settings_failure_notify + - section: "Authentication" + rules: + - auth_pam_login_smartcard_enforce + - auth_pam_su_smartcard_enforce + - auth_pam_sudo_smartcard_enforce + - auth_smartcard_allow + - auth_smartcard_certificate_trust_enforce_high + - auth_smartcard_certificate_trust_enforce_moderate + - auth_smartcard_enforce + - auth_ssh_smartcard_enforce + - section: "SystemPreferences" + rules: + - sysprefs_ad_tracking_disable + - sysprefs_afp_disable + - sysprefs_apple_watch_unlock_disable + - sysprefs_automatic_login_disable + - sysprefs_bluetooth_disable + - sysprefs_bluetooth_sharing_disable + - sysprefs_content_caching_disable + - sysprefs_diagnostics_reports_disable + - sysprefs_filevault_enforce + - sysprefs_find_my_disable + - sysprefs_firewall_enable + - sysprefs_firewall_stealth_mode_enable + - sysprefs_gatekeeper_identified_developers_allowed + - sysprefs_gatekeeper_override_disallow + - sysprefs_hot_corners_disable + - sysprefs_internet_sharing_disable + - sysprefs_location_services_disable + - sysprefs_loginwindow_prompt_username_password_enforce + - sysprefs_media_sharing_disabled + - sysprefs_password_hints_disable + - sysprefs_rae_disable + - sysprefs_screen_sharing_disable + - sysprefs_siri_disable + - sysprefs_smbd_disable + - sysprefs_ssh_enable + - sysprefs_time_server_configure + - sysprefs_time_server_enforce + - sysprefs_token_removal_enforce + - sysprefs_touchid_unlock_disable + - sysprefs_wifi_disable + - section: "iCloud" + rules: + - icloud_addressbook_disable + - icloud_calendar_disable + - icloud_mail_disable + - icloud_notes_disable + - icloud_reminders_disable + - icloud_appleid_prefpane_disable + - icloud_bookmarks_disable + - icloud_drive_disable + - icloud_keychain_disable + - icloud_photos_disable + - icloud_sync_disable + - section: "macOS" + rules: + - os_sip_enable + - os_airdrop_disable + - os_appleid_prompt_disable + - os_bonjour_disable + - os_calendar_app_disable + - os_camera_disable + - os_certificate_authority_trust + - os_facetime_app_disable + - os_filevault_autologin_disable + - os_firewall_default_deny_require + - os_firewall_log_enable + - os_firmware_password_require + - os_gatekeeper_enable + - os_guest_access_afp_disable + - os_guest_access_smb_disable + - os_guest_account_disable + - os_handoff_disable + - os_home_folders_secure + - os_httpd_disable + - os_icloud_storage_prompt_disable + - os_internet_accounts_prefpane_disable + - os_ir_support_disable + - os_mail_app_disable + - os_messages_app_disable + - os_nfsd_disable + - os_parental_controls_enable + - os_password_autofill_disable + - os_password_proximity_disable + - os_password_sharing_disable + - os_policy_banner_loginwindow_enforce + - os_policy_banner_ssh_configure + - os_policy_banner_ssh_enforce + - os_power_nap_disable + - os_privacy_setup_prompt_disable + - os_removable_media_disable + - os_root_disable + - os_root_disable_sshd + - os_screensaver_ask_for_password_delay_enforce + - os_screensaver_loginwindow_enforce + - os_screensaver_password_enforce + - os_screensaver_timeout_enforce + - os_secure_boot_verify + - os_siri_prompt_disable + - os_ssh_client_alive_count_max_configure + - os_ssh_client_alive_interval_configure + - os_ssh_fips_140_ciphers + - os_ssh_fips_140_macs + - os_ssh_login_grace_time_configure + - os_ssh_max_sessions_configure + - os_ssh_permit_root_login_configure + - os_sudoers_tty_configure + - os_system_wide_preferences_configure + - os_time_server_enabled + - os_touchid_prompt_disable + - os_uamdm_require + - os_unlock_active_user_session_disable + - os_user_app_installation_prohibit + - os_uucp_disable + - section: "PasswordPolicy" + rules: + - pwpolicy_60_day_enforce + - pwpolicy_account_inactivity_enforce + - pwpolicy_account_lockout_enforce + - pwpolicy_account_lockout_timeout_enforce + - pwpolicy_alpha_numeric_enforce + - pwpolicy_emergency_accounts_disable + - pwpolicy_history_enforce + - pwpolicy_lower_case_character_enforce + - pwpolicy_minimum_length_enforce + - pwpolicy_minimum_lifetime_enforce + - pwpolicy_simple_sequence_disable + - pwpolicy_special_character_enforce + - pwpolicy_temporary_accounts_disable + - pwpolicy_upper_case_character_enforce + - section: "Permanent" + rules: + - audit_alert_processing_fail + - audit_enforce_dual_auth + - audit_off_load_records + - os_enforce_login_attempt_delay + - os_limit_dos_attacks + - os_limit_invalid_logons + - os_notify_account_created + - os_notify_account_disabled + - os_notify_account_enable + - os_notify_account_modified + - os_notify_account_removal + - os_notify_unauthorized_baseline_change + - os_protect_dos_attacks + - os_provide_automated_account_management + - os_reauth_devices_change_authenticators + - pwpolicy_50_percent + - pwpolicy_prevent_dictionary_words + - pwpolicy_force_password_change + - section: "Not_Applicable" + rules: + - os_auth_peripherals + - os_identify_non-org_users + - os_prohibit_cached_authenticators + - os_react_security_anomalies + - os_request_verification_name_resolution + - os_verify_security_functions + - section: "Inherent" + rules: + - audit_auditd_enabled + - os_allow_info_passed + - os_change_security_attributes + - os_crypto_audit + - os_enforce_access_restrictions + - os_error_message + - os_fail_secure_state + - os_grant_privs + - os_implement_memory_protection + - os_implement_cryptography + - os_implement_random_address_space + - os_isolate_security_functions + - os_limit_auditable_events + - os_limit_gui_sessions + - os_logical_access + - os_logoff_capability_and_message + - os_map_pki_identity + - os_mfa_network_access + - os_mfa_network_non-priv + - os_obscure_password + - os_peripherals_identify + - os_predictable_behavior + - os_preserve_information_on_crash + - os_prevent_priv_execution + - os_prevent_priv_functions + - os_prevent_restricted_software + - os_prevent_unauthorized_disclosure + - os_provide_disconnect_remote_access + - os_reauth_privilege + - os_reauth_users_change_authenticators + - os_remote_access_methods + - os_remove_software_components_after_updates + - os_required_crypto_module + - os_separate_fuctionality + - os_store_encrypted_passwords + - os_terminate_session + - os_terminate_session_inactivity + - os_unique_identification + - os_verify_remote_disconnection + - section: "Supplemental" + rules: + - supplemental_smartcard + - supplemental_firewall_pf + - supplemental_password_policy diff --git a/baselines/cnssi.yaml b/baselines/cnssi.yaml new file mode 100644 index 00000000..6c974eab --- /dev/null +++ b/baselines/cnssi.yaml @@ -0,0 +1,197 @@ +title: "Apple macOS 10.15 (Catalina) Security Configuration - CNSSI" +description: | + This guide describes the actions to take when securing a macOS 10.15 system against the CNSSI baseline. +profile: + - section: "Auditing" + rules: + - audit_acls_files_configure + - audit_acls_files_mode_configure + - audit_acls_folder_wheel_configure + - audit_acls_folders_configure + - audit_acls_folders_mode_configure + - audit_failure_halt + - audit_files_group_configure + - audit_files_owner_configure + - audit_flags_aa_configure + - audit_flags_ad_configure + - audit_flags_failed_file_read_restriction_enforced + - audit_flags_failed_file_write_access_restriction_enforced + - audit_flags_file_attr_mod_access_restriction_enforced + - audit_flags_lo_configure + - audit_folder_group_configure + - audit_folder_owner_configure + - audit_retention_one_week_configure + - section: "Authentication" + rules: + - auth_pam_login_smartcard_enforce + - auth_pam_su_smartcard_enforce + - auth_pam_sudo_smartcard_enforce + - auth_smartcard_allow + - auth_smartcard_certificate_trust_enforce_high + - auth_smartcard_certificate_trust_enforce_moderate + - auth_smartcard_enforce + - auth_ssh_smartcard_enforce + - section: "SystemPreferences" + rules: + - sysprefs_ad_tracking_disable + - sysprefs_afp_disable + - sysprefs_apple_watch_unlock_disable + - sysprefs_automatic_login_disable + - sysprefs_bluetooth_disable + - sysprefs_bluetooth_sharing_disable + - sysprefs_content_caching_disable + - sysprefs_diagnostics_reports_disable + - sysprefs_filevault_enforce + - sysprefs_find_my_disable + - sysprefs_firewall_enable + - sysprefs_firewall_stealth_mode_enable + - sysprefs_gatekeeper_identified_developers_allowed + - sysprefs_gatekeeper_override_disallow + - sysprefs_hot_corners_disable + - sysprefs_internet_sharing_disable + - sysprefs_location_services_disable + - sysprefs_loginwindow_prompt_username_password_enforce + - sysprefs_media_sharing_disabled + - sysprefs_password_hints_disable + - sysprefs_rae_disable + - sysprefs_screen_sharing_disable + - sysprefs_siri_disable + - sysprefs_smbd_disable + - sysprefs_ssh_enable + - sysprefs_time_server_configure + - sysprefs_time_server_enforce + - sysprefs_token_removal_enforce + - sysprefs_touchid_unlock_disable + - sysprefs_wifi_disable + - section: "Permanent" + rules: + - audit_alert_processing_fail + - audit_enforce_dual_auth + - os_enforce_login_attempt_delay + - os_limit_invalid_logons + - os_notify_account_created + - os_notify_account_disabled + - os_notify_account_enable + - os_notify_account_modified + - os_notify_account_removal + - os_protect_dos_attacks + - os_provide_automated_account_management + - pwpolicy_50_percent + - pwpolicy_prevent_dictionary_words + - pwpolicy_force_password_change + - section: "iCloud" + rules: + - icloud_addressbook_disable + - icloud_calendar_disable + - icloud_mail_disable + - icloud_notes_disable + - icloud_reminders_disable + - icloud_appleid_prefpane_disable + - icloud_bookmarks_disable + - icloud_drive_disable + - icloud_keychain_disable + - icloud_photos_disable + - icloud_sync_disable + - section: "Inherent" + rules: + - audit_auditd_enabled + - os_error_message + - os_implement_memory_protection + - os_implement_cryptography + - os_implement_random_address_space + - os_limit_auditable_events + - os_logical_access + - os_map_pki_identity + - os_mfa_network_access + - os_mfa_network_non-priv + - os_obscure_password + - os_prevent_priv_functions + - os_prevent_restricted_software + - os_prevent_unauthorized_disclosure + - os_remote_access_methods + - os_required_crypto_module + - os_separate_fuctionality + - os_store_encrypted_passwords + - os_terminate_session + - os_terminate_session_inactivity + - os_unique_identification + - section: "not_applicable" + rules: + - os_auth_peripherals + - os_identify_non-org_users + - os_request_verification_name_resolution + - section: "macOS" + rules: + - os_peripherals_identify + - os_sip_enable + - os_airdrop_disable + - os_appleid_prompt_disable + - os_bonjour_disable + - os_calendar_app_disable + - os_camera_disable + - os_certificate_authority_trust + - os_facetime_app_disable + - os_filevault_autologin_disable + - os_firewall_default_deny_require + - os_firewall_log_enable + - os_firmware_password_require + - os_guest_access_afp_disable + - os_guest_access_smb_disable + - os_handoff_disable + - os_home_folders_secure + - os_httpd_disable + - os_icloud_storage_prompt_disable + - os_internet_accounts_prefpane_disable + - os_ir_support_disable + - os_mail_app_disable + - os_messages_app_disable + - os_nfsd_disable + - os_password_autofill_disable + - os_password_proximity_disable + - os_password_sharing_disable + - os_policy_banner_loginwindow_enforce + - os_policy_banner_ssh_configure + - os_policy_banner_ssh_enforce + - os_power_nap_disable + - os_privacy_setup_prompt_disable + - os_removable_media_disable + - os_root_disable + - os_root_disable_sshd + - os_screensaver_ask_for_password_delay_enforce + - os_screensaver_loginwindow_enforce + - os_screensaver_password_enforce + - os_screensaver_timeout_enforce + - os_siri_prompt_disable + - os_ssh_client_alive_count_max_configure + - os_ssh_client_alive_interval_configure + - os_ssh_fips_140_ciphers + - os_ssh_fips_140_macs + - os_ssh_login_grace_time_configure + - os_sudoers_tty_configure + - os_system_wide_preferences_configure + - os_time_server_enabled + - os_touchid_prompt_disable + - os_uamdm_require + - os_unlock_active_user_session_disable + - os_uucp_disable + - section: "PasswordPolicy" + rules: + - pwpolicy_60_day_enforce + - pwpolicy_account_inactivity_enforce + - pwpolicy_account_lockout_enforce + - pwpolicy_account_lockout_timeout_enforce + - pwpolicy_alpha_numeric_enforce + - pwpolicy_emergency_accounts_disable + - pwpolicy_history_enforce + - pwpolicy_lower_case_character_enforce + - pwpolicy_minimum_length_enforce + - pwpolicy_minimum_lifetime_enforce + - pwpolicy_simple_sequence_disable + - pwpolicy_special_character_enforce + - pwpolicy_temporary_accounts_disable + - pwpolicy_upper_case_character_enforce + - section: "Supplemental" + rules: + - supplemental_firewall_pf + - supplemental_password_policy + - supplemental_smartcard \ No newline at end of file diff --git a/baselines/high.yaml b/baselines/high.yaml new file mode 100644 index 00000000..0de27016 --- /dev/null +++ b/baselines/high.yaml @@ -0,0 +1,210 @@ +title: "Apple macOS 10.15 (Catalina) Security Configuration - High" +description: | + This guide describes the actions to take when securing a macOS 10.15 system against the FISMA HIGH baseline. +profile: + - section: "Auditing" + rules: + - audit_acls_files_configure + - audit_acls_files_mode_configure + - audit_acls_folder_wheel_configure + - audit_acls_folders_configure + - audit_acls_folders_mode_configure + - audit_configure_capacity_notify + - audit_failure_halt + - audit_files_group_configure + - audit_files_owner_configure + - audit_flags_aa_configure + - audit_flags_ad_configure + - audit_flags_failed_file_read_restriction_enforced + - audit_flags_failed_file_write_access_restriction_enforced + - audit_flags_file_attr_mod_access_restriction_enforced + - audit_flags_lo_configure + - audit_folder_group_configure + - audit_folder_owner_configure + - audit_retention_one_week_configure + - audit_settings_failure_notify + - section: "Authentication" + rules: + - auth_pam_login_smartcard_enforce + - auth_pam_su_smartcard_enforce + - auth_pam_sudo_smartcard_enforce + - auth_smartcard_allow + - auth_smartcard_certificate_trust_enforce_high + - auth_smartcard_certificate_trust_enforce_moderate + - auth_smartcard_enforce + - auth_ssh_smartcard_enforce + - section: "SystemPreferences" + rules: + - sysprefs_ad_tracking_disable + - sysprefs_afp_disable + - sysprefs_apple_watch_unlock_disable + - sysprefs_automatic_login_disable + - sysprefs_bluetooth_disable + - sysprefs_bluetooth_sharing_disable + - sysprefs_content_caching_disable + - sysprefs_diagnostics_reports_disable + - sysprefs_filevault_enforce + - sysprefs_find_my_disable + - sysprefs_firewall_enable + - sysprefs_firewall_stealth_mode_enable + - sysprefs_gatekeeper_identified_developers_allowed + - sysprefs_gatekeeper_override_disallow + - sysprefs_hot_corners_disable + - sysprefs_internet_sharing_disable + - sysprefs_location_services_disable + - sysprefs_loginwindow_prompt_username_password_enforce + - sysprefs_password_hints_disable + - sysprefs_rae_disable + - sysprefs_screen_sharing_disable + - sysprefs_siri_disable + - sysprefs_smbd_disable + - sysprefs_ssh_enable + - sysprefs_time_server_configure + - sysprefs_time_server_enforce + - sysprefs_token_removal_enforce + - sysprefs_touchid_unlock_disable + - sysprefs_wifi_disable + - section: "Permanent" + rules: + - audit_alert_processing_fail + - audit_enforce_dual_auth + - os_enforce_login_attempt_delay + - os_limit_invalid_logons + - os_notify_account_created + - os_notify_account_disabled + - os_notify_account_enable + - os_notify_account_modified + - os_notify_account_removal + - os_protect_dos_attacks + - os_provide_automated_account_management + - pwpolicy_50_percent + - pwpolicy_prevent_dictionary_words + - pwpolicy_force_password_change + - section: "iCloud" + rules: + - icloud_addressbook_disable + - icloud_calendar_disable + - icloud_mail_disable + - icloud_notes_disable + - icloud_reminders_disable + - icloud_appleid_prefpane_disable + - icloud_bookmarks_disable + - icloud_drive_disable + - icloud_keychain_disable + - icloud_photos_disable + - icloud_sync_disable + - section: "Inherent" + rules: + - audit_auditd_enabled + - os_crypto_audit + - os_enforce_access_restrictions + - os_error_message + - os_fail_secure_state + - os_implement_memory_protection + - os_implement_cryptography + - os_implement_random_address_space + - os_isolate_security_functions + - os_limit_auditable_events + - os_limit_gui_sessions + - os_logical_access + - os_map_pki_identity + - os_mfa_network_access + - os_mfa_network_non-priv + - os_obscure_password + - os_preserve_information_on_crash + - os_prevent_priv_functions + - os_prevent_restricted_software + - os_prevent_unauthorized_disclosure + - os_remote_access_methods + - os_required_crypto_module + - os_separate_fuctionality + - os_store_encrypted_passwords + - os_terminate_session + - os_terminate_session_inactivity + - os_unique_identification + - section: "not_applicable" + rules: + - os_auth_peripherals + - os_identify_non-org_users + - os_react_security_anomalies + - os_request_verification_name_resolution + - os_verify_security_functions + - section: "macOS" + rules: + - os_peripherals_identify + - os_sip_enable + - os_airdrop_disable + - os_appleid_prompt_disable + - os_bonjour_disable + - os_calendar_app_disable + - os_camera_disable + - os_certificate_authority_trust + - os_facetime_app_disable + - os_filevault_autologin_disable + - os_firewall_default_deny_require + - os_firewall_log_enable + - os_firmware_password_require + - os_gatekeeper_enable + - os_guest_access_afp_disable + - os_guest_access_smb_disable + - os_guest_account_disable + - os_handoff_disable + - os_home_folders_secure + - os_httpd_disable + - os_icloud_storage_prompt_disable + - os_internet_accounts_prefpane_disable + - os_ir_support_disable + - os_mail_app_disable + - os_messages_app_disable + - os_nfsd_disable + - os_password_autofill_disable + - os_password_proximity_disable + - os_password_sharing_disable + - os_policy_banner_loginwindow_enforce + - os_policy_banner_ssh_configure + - os_policy_banner_ssh_enforce + - os_power_nap_disable + - os_privacy_setup_prompt_disable + - os_removable_media_disable + - os_root_disable + - os_root_disable_sshd + - os_screensaver_ask_for_password_delay_enforce + - os_screensaver_loginwindow_enforce + - os_screensaver_password_enforce + - os_screensaver_timeout_enforce + - os_secure_boot_verify + - os_siri_prompt_disable + - os_ssh_client_alive_count_max_configure + - os_ssh_client_alive_interval_configure + - os_ssh_fips_140_ciphers + - os_ssh_fips_140_macs + - os_ssh_login_grace_time_configure + - os_ssh_max_sessions_configure + - os_sudoers_tty_configure + - os_system_wide_preferences_configure + - os_time_server_enabled + - os_touchid_prompt_disable + - os_uamdm_require + - os_unlock_active_user_session_disable + - os_uucp_disable + - section: "PasswordPolicy" + rules: + - pwpolicy_60_day_enforce + - pwpolicy_account_inactivity_enforce + - pwpolicy_account_lockout_enforce + - pwpolicy_account_lockout_timeout_enforce + - pwpolicy_alpha_numeric_enforce + - pwpolicy_emergency_accounts_disable + - pwpolicy_history_enforce + - pwpolicy_lower_case_character_enforce + - pwpolicy_minimum_length_enforce + - pwpolicy_minimum_lifetime_enforce + - pwpolicy_simple_sequence_disable + - pwpolicy_special_character_enforce + - pwpolicy_temporary_accounts_disable + - pwpolicy_upper_case_character_enforce + - section: "Supplemental" + rules: + - supplemental_firewall_pf + - supplemental_password_policy + - supplemental_smartcard diff --git a/baselines/low.yaml b/baselines/low.yaml new file mode 100644 index 00000000..32ecfd6a --- /dev/null +++ b/baselines/low.yaml @@ -0,0 +1,155 @@ +title: "Apple macOS 10.15 (Catalina) Security Configuration - Low" +description: | + This guide describes the actions to take when securing a macOS 10.15 system against the FISMA LOW baseline. +profile: + - section: "Auditing" + rules: + - audit_acls_files_configure + - audit_acls_files_mode_configure + - audit_acls_folder_wheel_configure + - audit_acls_folders_configure + - audit_acls_folders_mode_configure + - audit_failure_halt + - audit_files_group_configure + - audit_files_owner_configure + - audit_flags_aa_configure + - audit_flags_ad_configure + - audit_flags_failed_file_read_restriction_enforced + - audit_flags_failed_file_write_access_restriction_enforced + - audit_flags_file_attr_mod_access_restriction_enforced + - audit_flags_lo_configure + - audit_folder_group_configure + - audit_folder_owner_configure + - audit_retention_one_week_configure + - section: "Authentication" + rules: + - auth_pam_login_smartcard_enforce + - auth_pam_su_smartcard_enforce + - auth_pam_sudo_smartcard_enforce + - auth_smartcard_allow + - auth_smartcard_certificate_trust_enforce_high + - auth_smartcard_certificate_trust_enforce_moderate + - auth_smartcard_enforce + - auth_ssh_smartcard_enforce + - section: "SystemPreferences" + rules: + - sysprefs_ad_tracking_disable + - sysprefs_afp_disable + - sysprefs_automatic_login_disable + - sysprefs_bluetooth_sharing_disable + - sysprefs_content_caching_disable + - sysprefs_diagnostics_reports_disable + - sysprefs_find_my_disable + - sysprefs_firewall_enable + - sysprefs_firewall_stealth_mode_enable + - sysprefs_gatekeeper_identified_developers_allowed + - sysprefs_gatekeeper_override_disallow + - sysprefs_internet_sharing_disable + - sysprefs_location_services_disable + - sysprefs_loginwindow_prompt_username_password_enforce + - sysprefs_password_hints_disable + - sysprefs_rae_disable + - sysprefs_screen_sharing_disable + - sysprefs_siri_disable + - sysprefs_smbd_disable + - section: "Permanent" + rules: + - audit_alert_processing_fail + - audit_enforce_dual_auth + - os_enforce_login_attempt_delay + - os_limit_invalid_logons + - os_protect_dos_attacks + - pwpolicy_50_percent + - pwpolicy_prevent_dictionary_words + - pwpolicy_force_password_change + - section: "iCloud" + rules: + - icloud_addressbook_disable + - icloud_calendar_disable + - icloud_mail_disable + - icloud_notes_disable + - icloud_reminders_disable + - icloud_appleid_prefpane_disable + - icloud_bookmarks_disable + - icloud_drive_disable + - icloud_keychain_disable + - icloud_photos_disable + - icloud_sync_disable + - section: "Inherent" + rules: + - audit_auditd_enabled + - os_implement_cryptography + - os_limit_auditable_events + - os_logical_access + - os_mfa_network_access + - os_obscure_password + - os_required_crypto_module + - os_store_encrypted_passwords + - os_terminate_session + - os_unique_identification + - section: "not_applicable" + rules: + - os_identify_non-org_users + - os_request_verification_name_resolution + - section: "macOS" + rules: + - os_sip_enable + - os_airdrop_disable + - os_appleid_prompt_disable + - os_bonjour_disable + - os_calendar_app_disable + - os_camera_disable + - os_facetime_app_disable + - os_filevault_autologin_disable + - os_firewall_default_deny_require + - os_firewall_log_enable + - os_firmware_password_require + - os_guest_access_afp_disable + - os_guest_access_smb_disable + - os_handoff_disable + - os_home_folders_secure + - os_httpd_disable + - os_icloud_storage_prompt_disable + - os_internet_accounts_prefpane_disable + - os_ir_support_disable + - os_mail_app_disable + - os_messages_app_disable + - os_nfsd_disable + - os_password_autofill_disable + - os_password_proximity_disable + - os_password_sharing_disable + - os_policy_banner_loginwindow_enforce + - os_policy_banner_ssh_configure + - os_policy_banner_ssh_enforce + - os_power_nap_disable + - os_privacy_setup_prompt_disable + - os_removable_media_disable + - os_root_disable + - os_root_disable_sshd + - os_siri_prompt_disable + - os_ssh_fips_140_ciphers + - os_ssh_fips_140_macs + - os_sudoers_tty_configure + - os_touchid_prompt_disable + - os_uamdm_require + - os_unlock_active_user_session_disable + - os_uucp_disable + - section: "PasswordPolicy" + rules: + - pwpolicy_60_day_enforce + - pwpolicy_account_inactivity_enforce + - pwpolicy_account_lockout_enforce + - pwpolicy_account_lockout_timeout_enforce + - pwpolicy_alpha_numeric_enforce + - pwpolicy_history_enforce + - pwpolicy_lower_case_character_enforce + - pwpolicy_minimum_length_enforce + - pwpolicy_minimum_lifetime_enforce + - pwpolicy_simple_sequence_disable + - pwpolicy_special_character_enforce + - pwpolicy_upper_case_character_enforce + - section: "Supplemental" + rules: + - supplemental_firewall_pf + - supplemental_password_policy + - supplemental_smartcard diff --git a/baselines/moderate.yaml b/baselines/moderate.yaml new file mode 100644 index 00000000..f0c36974 --- /dev/null +++ b/baselines/moderate.yaml @@ -0,0 +1,195 @@ +title: "Apple macOS 10.15 (Catalina) Security Configuration - Moderate" +description: | + This guide describes the actions to take when securing a macOS 10.15 system against the FISMA MODERATE baseline. +profile: + - section: "Auditing" + rules: + - audit_acls_files_configure + - audit_acls_files_mode_configure + - audit_acls_folder_wheel_configure + - audit_acls_folders_configure + - audit_acls_folders_mode_configure + - audit_failure_halt + - audit_files_group_configure + - audit_files_owner_configure + - audit_flags_aa_configure + - audit_flags_ad_configure + - audit_flags_failed_file_read_restriction_enforced + - audit_flags_failed_file_write_access_restriction_enforced + - audit_flags_file_attr_mod_access_restriction_enforced + - audit_flags_lo_configure + - audit_folder_group_configure + - audit_folder_owner_configure + - audit_retention_one_week_configure + - section: "Authentication" + rules: + - auth_pam_login_smartcard_enforce + - auth_pam_su_smartcard_enforce + - auth_pam_sudo_smartcard_enforce + - auth_smartcard_allow + - auth_smartcard_certificate_trust_enforce_moderate + - auth_smartcard_enforce + - auth_ssh_smartcard_enforce + - section: "SystemPreferences" + rules: + - sysprefs_ad_tracking_disable + - sysprefs_afp_disable + - sysprefs_apple_watch_unlock_disable + - sysprefs_automatic_login_disable + - sysprefs_bluetooth_disable + - sysprefs_bluetooth_sharing_disable + - sysprefs_content_caching_disable + - sysprefs_diagnostics_reports_disable + - sysprefs_filevault_enforce + - sysprefs_find_my_disable + - sysprefs_firewall_enable + - sysprefs_firewall_stealth_mode_enable + - sysprefs_gatekeeper_identified_developers_allowed + - sysprefs_gatekeeper_override_disallow + - sysprefs_hot_corners_disable + - sysprefs_internet_sharing_disable + - sysprefs_location_services_disable + - sysprefs_loginwindow_prompt_username_password_enforce + - sysprefs_password_hints_disable + - sysprefs_rae_disable + - sysprefs_screen_sharing_disable + - sysprefs_siri_disable + - sysprefs_smbd_disable + - sysprefs_ssh_enable + - sysprefs_time_server_configure + - sysprefs_time_server_enforce + - sysprefs_token_removal_enforce + - sysprefs_touchid_unlock_disable + - sysprefs_wifi_disable + - section: "Permanent" + rules: + - audit_alert_processing_fail + - audit_enforce_dual_auth + - os_enforce_login_attempt_delay + - os_limit_invalid_logons + - os_notify_account_created + - os_notify_account_disabled + - os_notify_account_enable + - os_notify_account_modified + - os_notify_account_removal + - os_protect_dos_attacks + - os_provide_automated_account_management + - pwpolicy_50_percent + - pwpolicy_prevent_dictionary_words + - pwpolicy_force_password_change + - section: "iCloud" + rules: + - icloud_addressbook_disable + - icloud_calendar_disable + - icloud_mail_disable + - icloud_notes_disable + - icloud_reminders_disable + - icloud_appleid_prefpane_disable + - icloud_bookmarks_disable + - icloud_drive_disable + - icloud_keychain_disable + - icloud_photos_disable + - icloud_sync_disable + - section: "Inherent" + rules: + - audit_auditd_enabled + - os_error_message + - os_implement_memory_protection + - os_implement_cryptography + - os_implement_random_address_space + - os_limit_auditable_events + - os_logical_access + - os_map_pki_identity + - os_mfa_network_access + - os_mfa_network_non-priv + - os_obscure_password + - os_prevent_priv_functions + - os_prevent_restricted_software + - os_prevent_unauthorized_disclosure + - os_remote_access_methods + - os_required_crypto_module + - os_separate_fuctionality + - os_store_encrypted_passwords + - os_terminate_session + - os_terminate_session_inactivity + - os_unique_identification + - section: "not_applicable" + rules: + - os_auth_peripherals + - os_identify_non-org_users + - os_request_verification_name_resolution + - section: "macOS" + rules: + - os_peripherals_identify + - os_sip_enable + - os_airdrop_disable + - os_appleid_prompt_disable + - os_bonjour_disable + - os_calendar_app_disable + - os_camera_disable + - os_certificate_authority_trust + - os_facetime_app_disable + - os_filevault_autologin_disable + - os_firewall_default_deny_require + - os_firewall_log_enable + - os_firmware_password_require + - os_guest_access_afp_disable + - os_guest_access_smb_disable + - os_handoff_disable + - os_home_folders_secure + - os_httpd_disable + - os_icloud_storage_prompt_disable + - os_internet_accounts_prefpane_disable + - os_ir_support_disable + - os_mail_app_disable + - os_messages_app_disable + - os_nfsd_disable + - os_password_autofill_disable + - os_password_proximity_disable + - os_password_sharing_disable + - os_policy_banner_loginwindow_enforce + - os_policy_banner_ssh_configure + - os_policy_banner_ssh_enforce + - os_power_nap_disable + - os_privacy_setup_prompt_disable + - os_removable_media_disable + - os_root_disable + - os_root_disable_sshd + - os_screensaver_ask_for_password_delay_enforce + - os_screensaver_loginwindow_enforce + - os_screensaver_password_enforce + - os_screensaver_timeout_enforce + - os_siri_prompt_disable + - os_ssh_client_alive_count_max_configure + - os_ssh_client_alive_interval_configure + - os_ssh_fips_140_ciphers + - os_ssh_fips_140_macs + - os_ssh_login_grace_time_configure + - os_sudoers_tty_configure + - os_system_wide_preferences_configure + - os_time_server_enabled + - os_touchid_prompt_disable + - os_uamdm_require + - os_unlock_active_user_session_disable + - os_uucp_disable + - section: "PasswordPolicy" + rules: + - pwpolicy_60_day_enforce + - pwpolicy_account_inactivity_enforce + - pwpolicy_account_lockout_enforce + - pwpolicy_account_lockout_timeout_enforce + - pwpolicy_alpha_numeric_enforce + - pwpolicy_emergency_accounts_disable + - pwpolicy_history_enforce + - pwpolicy_lower_case_character_enforce + - pwpolicy_minimum_length_enforce + - pwpolicy_minimum_lifetime_enforce + - pwpolicy_simple_sequence_disable + - pwpolicy_special_character_enforce + - pwpolicy_temporary_accounts_disable + - pwpolicy_upper_case_character_enforce + - section: "Supplemental" + rules: + - supplemental_firewall_pf + - supplemental_password_policy + - supplemental_smartcard \ No newline at end of file diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 00000000..5e7d2734 --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/custom/.gitignore b/custom/.gitignore new file mode 100644 index 00000000..6d3c7be3 --- /dev/null +++ b/custom/.gitignore @@ -0,0 +1,6 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore +!sections +!rules \ No newline at end of file diff --git a/custom/rules/.gitignore b/custom/rules/.gitignore new file mode 100644 index 00000000..86d0cb27 --- /dev/null +++ b/custom/rules/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/custom/sections/.gitignore b/custom/sections/.gitignore new file mode 100644 index 00000000..86d0cb27 --- /dev/null +++ b/custom/sections/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/includes/800-53_baselines.yaml b/includes/800-53_baselines.yaml new file mode 100644 index 00000000..a22d702c --- /dev/null +++ b/includes/800-53_baselines.yaml @@ -0,0 +1,2237 @@ +low: + - AC-1 + - AC-1(a) + - AC-1(a)(1) + - AC-1(a)(2) + - AC-1(b) + - AC-1(b)(1) + - AC-1(b)(2) + - AC-2 + - AC-2(a) + - AC-2(b) + - AC-2(c) + - AC-2(d) + - AC-2(e) + - AC-2(f) + - AC-2(g) + - AC-2(h) + - AC-2(h)(1) + - AC-2(h)(2) + - AC-2(h)(3) + - AC-2(i) + - AC-2(i)(1) + - AC-2(i)(2) + - AC-2(i)(3) + - AC-2(j) + - AC-2(k) + - AC-3 + - AC-7 + - AC-7(a) + - AC-7(b) + - AC-8 + - AC-8(a) + - AC-8(a)(1) + - AC-8(a)(2) + - AC-8(a)(3) + - AC-8(a)(4) + - AC-8(b) + - AC-8(c) + - AC-8(c)(1) + - AC-8(c)(2) + - AC-8(c)(3) + - AC-14 + - AC-14(a) + - AC-14(b) + - AC-17 + - AC-17(a) + - AC-17(b) + - AC-18 + - AC-18(a) + - AC-18(b) + - AC-19 + - AC-19(a) + - AC-19(b) + - AC-20 + - AC-20(a) + - AC-20(b) + - AC-22 + - AC-22(a) + - AC-22(b) + - AC-22(c) + - AC-22(d) + - AT-1 + - AT-1(a) + - AT-1(a)(1) + - AT-1(a)(2) + - AT-1(b) + - AT-1(b)(1) + - AT-1(b)(2) + - AT-2 + - AT-2(a) + - AT-2(b) + - AT-2(c) + - AT-3 + - AT-3(a) + - AT-3(b) + - AT-3(c) + - AT-4 + - AT-4(a) + - AT-4(b) + - AU-1 + - AU-1(a) + - AU-1(a)(1) + - AU-1(a)(2) + - AU-1(b) + - AU-1(b)(1) + - AU-1(b)(2) + - AU-2 + - AU-2(a) + - AU-2(b) + - AU-2(c) + - AU-2(d) + - AU-3 + - AU-4 + - AU-5 + - AU-5(a) + - AU-5(b) + - AU-6 + - AU-6(a) + - AU-6(b) + - AU-8 + - AU-9 + - AU-11 + - AU-12 + - AU-12(a) + - AU-12(b) + - AU-12(c) + - CA-1 + - CA-1(a) + - CA-1(a)(1) + - CA-1(a)(2) + - CA-1(b) + - CA-1(b)(1) + - CA-1(b)(2) + - CA-2 + - CA-2(a) + - CA-2(a)(1) + - CA-2(a)(2) + - CA-2(a)(3) + - CA-2(b) + - CA-2(c) + - CA-2(d) + - CA-3 + - CA-3(a) + - CA-3(b) + - CA-3(c) + - CA-5 + - CA-5(a) + - CA-5(b) + - CA-6 + - CA-6(a) + - CA-6(b) + - CA-6(c) + - CA-7 + - CA-7(a) + - CA-7(b) + - CA-7(c) + - CA-7(d) + - CA-7(e) + - CA-7(f) + - CA-7(g) + - CA-9 + - CA-9(a) + - CA-9(b) + - CM-1 + - CM-1(a) + - CM-1(a)(1) + - CM-1(a)(2) + - CM-1(b) + - CM-1(b)(1) + - CM-1(b)(2) + - CM-2 + - CM-4 + - CM-6 + - CM-6(a) + - CM-6(b) + - CM-6(c) + - CM-6(d) + - CM-7 + - CM-7(a) + - CM-7(b) + - CM-8 + - CM-8(a) + - CM-8(a)(1) + - CM-8(a)(2) + - CM-8(a)(3) + - CM-8(a)(4) + - CM-8(b) + - CM-10 + - CM-10(a) + - CM-10(b) + - CM-10(c) + - CM-11 + - CM-11(a) + - CM-11(b) + - CM-11(c) + - CP-1 + - CP-1(a) + - CP-1(a)(1) + - CP-1(a)(2) + - CP-1(b) + - CP-1(b)(1) + - CP-1(b)(2) + - CP-2 + - CP-2(a) + - CP-2(a)(1) + - CP-2(a)(2) + - CP-2(a)(3) + - CP-2(a)(4) + - CP-2(a)(5) + - CP-2(a)(6) + - CP-2(b) + - CP-2(c) + - CP-2(d) + - CP-2(e) + - CP-2(f) + - CP-2(g) + - CP-3 + - CP-3(a) + - CP-3(b) + - CP-3(c) + - CP-4 + - CP-4(a) + - CP-4(b) + - CP-4(c) + - CP-9 + - CP-9(a) + - CP-9(b) + - CP-9(c) + - CP-9(d) + - CP-10 + - IA-1 + - IA-1(a) + - IA-1(a)(1) + - IA-1(a)(2) + - IA-1(b) + - IA-1(b)(1) + - IA-1(b)(2) + - IA-2 + - IA-2(1) + - IA-2(12) + - IA-4 + - IA-4(a) + - IA-4(b) + - IA-4(c) + - IA-4(d) + - IA-4(e) + - IA-5 + - IA-5(a) + - IA-5(b) + - IA-5(c) + - IA-5(d) + - IA-5(e) + - IA-5(f) + - IA-5(g) + - IA-5(h) + - IA-5(i) + - IA-5(j) + - IA-5(1) + - IA-5(1)(a) + - IA-5(1)(b) + - IA-5(1)(c) + - IA-5(1)(d) + - IA-5(1)(e) + - IA-5(1)(f) + - IA-5(11) + - IA-6 + - IA-7 + - IA-8 + - IA-8(1) + - IA-8(2) + - IA-8(3) + - IA-8(4) + - IR-1 + - IR-1(a) + - IR-1(a)(1) + - IR-1(a)(2) + - IR-1(b) + - IR-1(b)(1) + - IR-1(b)(2) + - IR-2 + - IR-2(a) + - IR-2(b) + - IR-2(c) + - IR-4 + - IR-4(a) + - IR-4(b) + - IR-4(c) + - IR-5 + - IR-6 + - IR-6(a) + - IR-6(b) + - IR-7 + - IR-8 + - IR-8(a) + - IR-8(a)(1) + - IR-8(a)(2) + - IR-8(a)(3) + - IR-8(a)(4) + - IR-8(a)(5) + - IR-8(a)(6) + - IR-8(a)(7) + - IR-8(a)(8) + - IR-8(b) + - IR-8(c) + - IR-8(d) + - IR-8(e) + - IR-8(f) + - MA-1 + - MA-1(a) + - MA-1(a)(1) + - MA-1(a)(2) + - MA-1(b) + - MA-1(b)(1) + - MA-1(b)(2) + - MA-2 + - MA-2(a) + - MA-2(b) + - MA-2(c) + - MA-2(d) + - MA-2(e) + - MA-2(f) + - MA-4 + - MA-4(a) + - MA-4(b) + - MA-4(c) + - MA-4(d) + - MA-4(e) + - MA-5 + - MA-5(a) + - MA-5(b) + - MA-5(c) + - MP-1 + - MP-1(a) + - MP-1(a)(1) + - MP-1(a)(2) + - MP-1(b) + - MP-1(b)(1) + - MP-1(b)(2) + - MP-2 + - MP-6 + - MP-6(a) + - MP-6(b) + - MP-7 + - PE-1 + - PE-1(a) + - PE-1(a)(1) + - PE-1(a)(2) + - PE-1(b) + - PE-1(b)(1) + - PE-1(b)(2) + - PE-2 + - PE-2(a) + - PE-2(b) + - PE-2(c) + - PE-2(d) + - PE-3 + - PE-3(a) + - PE-3(a)(1) + - PE-3(a)(2) + - PE-3(b) + - PE-3(c) + - PE-3(d) + - PE-3(e) + - PE-3(f) + - PE-3(g) + - PE-6 + - PE-6(a) + - PE-6(b) + - PE-6(c) + - PE-8 + - PE-8(a) + - PE-8(b) + - PE-12 + - PE-13 + - PE-14 + - PE-14(a) + - PE-14(b) + - PE-15 + - PE-16 + - PL-1 + - PL-1(a) + - PL-1(a)(1) + - PL-1(a)(2) + - PL-1(b) + - PL-1(b)(1) + - PL-1(b)(2) + - PL-2 + - PL-2(a) + - PL-2(a)(1) + - PL-2(a)(2) + - PL-2(a)(3) + - PL-2(a)(4) + - PL-2(a)(5) + - PL-2(a)(6) + - PL-2(a)(7) + - PL-2(a)(8) + - PL-2(a)(9) + - PL-2(b) + - PL-2(c) + - PL-2(d) + - PL-2(e) + - PL-4 + - PL-4(a) + - PL-4(b) + - PL-4(c) + - PL-4(d) + - PS-1 + - PS-1(a) + - PS-1(a)(1) + - PS-1(a)(2) + - PS-1(b) + - PS-1(b)(1) + - PS-1(b)(2) + - PS-2 + - PS-2(a) + - PS-2(b) + - PS-2(c) + - PS-3 + - PS-3(a) + - PS-3(b) + - PS-4 + - PS-4(a) + - PS-4(b) + - PS-4(c) + - PS-4(d) + - PS-4(e) + - PS-4(f) + - PS-5 + - PS-5(a) + - PS-5(b) + - PS-5(c) + - PS-5(d) + - PS-6 + - PS-6(a) + - PS-6(b) + - PS-6(c) + - PS-6(c)(1) + - PS-6(c)(2) + - PS-7 + - PS-7(a) + - PS-7(b) + - PS-7(c) + - PS-7(d) + - PS-7(e) + - PS-8 + - PS-8(a) + - PS-8(b) + - RA-1 + - RA-1(a) + - RA-1(a)(1) + - RA-1(a)(2) + - RA-1(b) + - RA-1(b)(1) + - RA-1(b)(2) + - RA-2 + - RA-2(a) + - RA-2(b) + - RA-2(c) + - RA-3 + - RA-3(a) + - RA-3(b) + - RA-3(c) + - RA-3(d) + - RA-3(e) + - RA-5 + - RA-5(a) + - RA-5(b) + - RA-5(b)(1) + - RA-5(b)(2) + - RA-5(b)(3) + - RA-5(c) + - RA-5(d) + - RA-5(e) + - SA-1 + - SA-1(a) + - SA-1(a)(1) + - SA-1(a)(2) + - SA-1(b) + - SA-1(b)(1) + - SA-1(b)(2) + - SA-2 + - SA-2(a) + - SA-2(b) + - SA-2(c) + - SA-3 + - SA-3(a) + - SA-3(b) + - SA-3(c) + - SA-3(d) + - SA-4 + - SA-4(a) + - SA-4(b) + - SA-4(c) + - SA-4(d) + - SA-4(e) + - SA-4(f) + - SA-4(g) + - SA-4(10) + - SA-5 + - SA-5(a) + - SA-5(a)(1) + - SA-5(a)(2) + - SA-5(a)(3) + - SA-5(b) + - SA-5(b)(1) + - SA-5(b)(2) + - SA-5(b)(3) + - SA-5(c) + - SA-5(d) + - SA-5(e) + - SA-9 + - SA-9(a) + - SA-9(b) + - SA-9(c) + - SC-1 + - SC-1(a) + - SC-1(a)(1) + - SC-1(a)(2) + - SC-1(b) + - SC-1(b)(1) + - SC-1(b)(2) + - SC-5 + - SC-7 + - SC-7(a) + - SC-7(b) + - SC-7(c) + - SC-12 + - SC-13 + - SC-15 + - SC-15(a) + - SC-15(b) + - SC-20 + - SC-20(a) + - SC-20(b) + - SC-21 + - SC-22 + - SC-39 + - SI-1 + - SI-1(a) + - SI-1(a)(1) + - SI-1(a)(2) + - SI-1(b) + - SI-1(b)(1) + - SI-1(b)(2) + - SI-2 + - SI-2(a) + - SI-2(b) + - SI-2(c) + - SI-2(d) + - SI-3 + - SI-4 + - SI-4(a) + - SI-4(a)(1) + - SI-4(a)(2) + - SI-4(b) + - SI-4(c) + - SI-4(c)(1) + - SI-4(c)(2) + - SI-4(d) + - SI-4(e) + - SI-4(f) + - SI-4(g) + - SI-5 + - SI-5(a) + - SI-5(b) + - SI-5(c) + - SI-5(d) + - SI-12 + +moderate: + - AC-1 + - AC-1(a) + - AC-1(a)(1) + - AC-1(a)(2) + - AC-1(b) + - AC-1(b)(1) + - AC-1(b)(2) + - AC-2 + - AC-2(a) + - AC-2(b) + - AC-2(c) + - AC-2(d) + - AC-2(e) + - AC-2(f) + - AC-2(g) + - AC-2(h) + - AC-2(h)(1) + - AC-2(h)(2) + - AC-2(h)(3) + - AC-2(i) + - AC-2(i)(1) + - AC-2(i)(2) + - AC-2(i)(3) + - AC-2(j) + - AC-2(k) + - AC-2(1) + - AC-2(2) + - AC-2(3) + - AC-2(4) + - AC-3 + - AC-4 + - AC-5 + - AC-5(a) + - AC-5(b) + - AC-5(c) + - AC-6 + - AC-6(1) + - AC-6(2) + - AC-6(5) + - AC-6(9) + - AC-6(10) + - AC-7 + - AC-7(a) + - AC-7(b) + - AC-8 + - AC-8(a) + - AC-8(a)(1) + - AC-8(a)(2) + - AC-8(a)(3) + - AC-8(a)(4) + - AC-8(b) + - AC-8(c) + - AC-8(c)(1) + - AC-8(c)(2) + - AC-8(c)(3) + - AC-11 + - AC-11(a) + - AC-11(b) + - AC-11(1) + - AC-12 + - AC-14 + - AC-14(a) + - AC-14(b) + - AC-17 + - AC-17(a) + - AC-17(b) + - AC-17(1) + - AC-17(2) + - AC-17(3) + - AC-17(4) + - AC-17(4)(a) + - AC-17(4)(b) + - AC-18 + - AC-18(a) + - AC-18(b) + - AC-18(1) + - AC-19 + - AC-19(a) + - AC-19(b) + - AC-19(5) + - AC-20 + - AC-20(a) + - AC-20(b) + - AC-20(1) + - AC-20(1)(a) + - AC-20(1)(b) + - AC-20(2) + - AC-21 + - AC-21(a) + - AC-21(b) + - AC-22 + - AC-22(a) + - AC-22(b) + - AC-22(c) + - AC-22(d) + - AT-1 + - AT-1(a) + - AT-1(a)(1) + - AT-1(a)(2) + - AT-1(b) + - AT-1(b)(1) + - AT-1(b)(2) + - AT-2 + - AT-2(a) + - AT-2(b) + - AT-2(c) + - AT-2(2) + - AT-3 + - AT-3(a) + - AT-3(b) + - AT-3(c) + - AT-4 + - AT-4(a) + - AT-4(b) + - AU-1 + - AU-1(a) + - AU-1(a)(1) + - AU-1(a)(2) + - AU-1(b) + - AU-1(b)(1) + - AU-1(b)(2) + - AU-2 + - AU-2(a) + - AU-2(b) + - AU-2(c) + - AU-2(d) + - AU-2(3) + - AU-3 + - AU-3(1) + - AU-4 + - AU-5 + - AU-5(a) + - AU-5(b) + - AU-6 + - AU-6(a) + - AU-6(b) + - AU-6(1) + - AU-6(3) + - AU-7 + - AU-7(a) + - AU-7(b) + - AU-7(1) + - AU-8 + - AU-8(a) + - AU-8(b) + - AU-8(1) + - AU-8(1)(a) + - AU-8(1)(b) + - AU-9 + - AU-9(4) + - AU-11 + - AU-12 + - AU-12(a) + - AU-12(b) + - AU-12(c) + - CA-1 + - CA-1(a) + - CA-1(a)(1) + - CA-1(a)(2) + - CA-1(b) + - CA-1(b)(1) + - CA-1(b)(2) + - CA-2 + - CA-2(a) + - CA-2(a)(1) + - CA-2(a)(2) + - CA-2(a)(3) + - CA-2(b) + - CA-2(c) + - CA-2(d) + - CA-2(1) + - CA-3 + - CA-3(a) + - CA-3(b) + - CA-3(c) + - CA-3(5) + - CA-5 + - CA-5(a) + - CA-5(b) + - CA-6 + - CA-6(a) + - CA-6(b) + - CA-6(c) + - CA-7 + - CA-7(a) + - CA-7(b) + - CA-7(c) + - CA-7(d) + - CA-7(e) + - CA-7(f) + - CA-7(g) + - CA-7(1) + - CA-9 + - CA-9(a) + - CA-9(b) + - CM-1 + - CM-1(a) + - CM-1(a)(1) + - CM-1(a)(2) + - CM-1(b) + - CM-1(b)(1) + - CM-1(b)(2) + - CM-2 + - CM-2(1) + - CM-2(1)(a) + - CM-2(1)(b) + - CM-2(1)(c) + - CM-2(3) + - CM-2(7) + - CM-2(7)(a) + - CM-2(7)(b) + - CM-3 + - CM-3(a) + - CM-3(b) + - CM-3(c) + - CM-3(d) + - CM-3(e) + - CM-3(f) + - CM-3(g) + - CM-3(2) + - CM-4 + - CM-5 + - CM-6 + - CM-6(a) + - CM-6(b) + - CM-6(c) + - CM-6(d) + - CM-7 + - CM-7(a) + - CM-7(b) + - CM-7(1) + - CM-7(1)(a) + - CM-7(1)(b) + - CM-7(2) + - CM-7(4) + - CM-7(4)(a) + - CM-7(4)(b) + - CM-7(4)(c) + - CM-8 + - CM-8(a) + - CM-8(a)(1) + - CM-8(a)(2) + - CM-8(a)(3) + - CM-8(a)(4) + - CM-8(b) + - CM-8(1) + - CM-8(3) + - CM-8(3)(a) + - CM-8(3)(b) + - CM-8(5) + - CM-9 + - CM-9(a) + - CM-9(b) + - CM-9(c) + - CM-9(d) + - CM-10 + - CM-10(a) + - CM-10(b) + - CM-10(c) + - CM-11 + - CM-11(a) + - CM-11(b) + - CM-11(c) + - CP-1 + - CP-1(a) + - CP-1(a)(1) + - CP-1(a)(2) + - CP-1(b) + - CP-1(b)(1) + - CP-1(b)(2) + - CP-2 + - CP-2(a) + - CP-2(a)(1) + - CP-2(a)(2) + - CP-2(a)(3) + - CP-2(a)(4) + - CP-2(a)(5) + - CP-2(a)(6) + - CP-2(b) + - CP-2(c) + - CP-2(d) + - CP-2(e) + - CP-2(f) + - CP-2(g) + - CP-2(1) + - CP-2(3) + - CP-2(8) + - CP-3 + - CP-3(a) + - CP-3(b) + - CP-3(c) + - CP-4 + - CP-4(a) + - CP-4(b) + - CP-4(c) + - CP-4(1) + - CP-6 + - CP-6(a) + - CP-6(b) + - CP-6(1) + - CP-6(3) + - CP-7 + - CP-7(a) + - CP-7(b) + - CP-7(c) + - CP-7(1) + - CP-7(2) + - CP-7(3) + - CP-8 + - CP-8(1) + - CP-8(1)(a) + - CP-8(1)(b) + - CP-8(2) + - CP-9 + - CP-9(a) + - CP-9(b) + - CP-9(c) + - CP-9(d) + - CP-9(1) + - CP-10 + - CP-10(2) + - IA-1 + - IA-1(a) + - IA-1(a)(1) + - IA-1(a)(2) + - IA-1(b) + - IA-1(b)(1) + - IA-1(b)(2) + - IA-2 + - IA-2(1) + - IA-2(2) + - IA-2(3) + - IA-2(8) + - IA-2(11) + - IA-2(12) + - IA-3 + - IA-4 + - IA-4(a) + - IA-4(b) + - IA-4(c) + - IA-4(d) + - IA-4(e) + - IA-5 + - IA-5(a) + - IA-5(b) + - IA-5(c) + - IA-5(d) + - IA-5(e) + - IA-5(f) + - IA-5(g) + - IA-5(h) + - IA-5(i) + - IA-5(j) + - IA-5(1) + - IA-5(1)(a) + - IA-5(1)(b) + - IA-5(1)(c) + - IA-5(1)(d) + - IA-5(1)(e) + - IA-5(1)(f) + - IA-5(2) + - IA-5(2)(a) + - IA-5(2)(b) + - IA-5(2)(c) + - IA-5(2)(d) + - IA-5(3) + - IA-5(11) + - IA-6 + - IA-7 + - IA-8 + - IA-8(1) + - IA-8(2) + - IA-8(3) + - IA-8(4) + - IR-1 + - IR-1(a) + - IR-1(a)(1) + - IR-1(a)(2) + - IR-1(b) + - IR-1(b)(1) + - IR-1(b)(2) + - IR-2 + - IR-2(a) + - IR-2(b) + - IR-2(c) + - IR-3 + - IR-3(2) + - IR-4 + - IR-4(a) + - IR-4(b) + - IR-4(c) + - IR-4(1) + - IR-5 + - IR-6 + - IR-6(a) + - IR-6(b) + - IR-6(1) + - IR-7 + - IR-7(1) + - IR-8 + - IR-8(a) + - IR-8(a)(1) + - IR-8(a)(2) + - IR-8(a)(3) + - IR-8(a)(4) + - IR-8(a)(5) + - IR-8(a)(6) + - IR-8(a)(7) + - IR-8(a)(8) + - IR-8(b) + - IR-8(c) + - IR-8(d) + - IR-8(e) + - IR-8(f) + - MA-1 + - MA-1(a) + - MA-1(a)(1) + - MA-1(a)(2) + - MA-1(b) + - MA-1(b)(1) + - MA-1(b)(2) + - MA-2 + - MA-2(a) + - MA-2(b) + - MA-2(c) + - MA-2(d) + - MA-2(e) + - MA-2(f) + - MA-3 + - MA-3(1) + - MA-3(2) + - MA-4 + - MA-4(a) + - MA-4(b) + - MA-4(c) + - MA-4(d) + - MA-4(e) + - MA-4(2) + - MA-5 + - MA-5(a) + - MA-5(b) + - MA-5(c) + - MA-6 + - MP-1 + - MP-1(a) + - MP-1(a)(1) + - MP-1(a)(2) + - MP-1(b) + - MP-1(b)(1) + - MP-1(b)(2) + - MP-2 + - MP-3 + - MP-3(a) + - MP-3(b) + - MP-4 + - MP-4(a) + - MP-4(b) + - MP-5 + - MP-5(a) + - MP-5(b) + - MP-5(c) + - MP-5(d) + - MP-5(4) + - MP-6 + - MP-6(a) + - MP-6(b) + - MP-7 + - MP-7(1) + - PE-1 + - PE-1(a) + - PE-1(a)(1) + - PE-1(a)(2) + - PE-1(b) + - PE-1(b)(1) + - PE-1(b)(2) + - PE-2 + - PE-2(a) + - PE-2(b) + - PE-2(c) + - PE-2(d) + - PE-3 + - PE-3(a) + - PE-3(a)(1) + - PE-3(a)(2) + - PE-3(b) + - PE-3(c) + - PE-3(d) + - PE-3(e) + - PE-3(f) + - PE-3(g) + - PE-4 + - PE-5 + - PE-6 + - PE-6(a) + - PE-6(b) + - PE-6(c) + - PE-6(1) + - PE-8 + - PE-8(a) + - PE-8(b) + - PE-9 + - PE-10 + - PE-10(a) + - PE-10(b) + - PE-10(c) + - PE-11 + - PE-12 + - PE-13 + - PE-13(3) + - PE-14 + - PE-14(a) + - PE-14(b) + - PE-15 + - PE-16 + - PE-17 + - PE-17(a) + - PE-17(b) + - PE-17(c) + - PL-1 + - PL-1(a) + - PL-1(a)(1) + - PL-1(a)(2) + - PL-1(b) + - PL-1(b)(1) + - PL-1(b)(2) + - PL-2 + - PL-2(a) + - PL-2(a)(1) + - PL-2(a)(2) + - PL-2(a)(3) + - PL-2(a)(4) + - PL-2(a)(5) + - PL-2(a)(6) + - PL-2(a)(7) + - PL-2(a)(8) + - PL-2(a)(9) + - PL-2(b) + - PL-2(c) + - PL-2(d) + - PL-2(e) + - PL-2(3) + - PL-4 + - PL-4(a) + - PL-4(b) + - PL-4(c) + - PL-4(d) + - PL-4(1) + - PL-8 + - PL-8(a) + - PL-8(a)(1) + - PL-8(a)(2) + - PL-8(a)(3) + - PL-8(b) + - PL-8(c) + - PS-1 + - PS-1(a) + - PS-1(a)(1) + - PS-1(a)(2) + - PS-1(b) + - PS-1(b)(1) + - PS-1(b)(2) + - PS-2 + - PS-2(a) + - PS-2(b) + - PS-2(c) + - PS-3 + - PS-3(a) + - PS-3(b) + - PS-4 + - PS-4(a) + - PS-4(b) + - PS-4(c) + - PS-4(d) + - PS-4(e) + - PS-4(f) + - PS-5 + - PS-5(a) + - PS-5(b) + - PS-5(c) + - PS-5(d) + - PS-6 + - PS-6(a) + - PS-6(b) + - PS-6(c) + - PS-6(c)(1) + - PS-6(c)(2) + - PS-7 + - PS-7(a) + - PS-7(b) + - PS-7(c) + - PS-7(d) + - PS-7(e) + - PS-8 + - PS-8(a) + - PS-8(b) + - RA-1 + - RA-1(a) + - RA-1(a)(1) + - RA-1(a)(2) + - RA-1(b) + - RA-1(b)(1) + - RA-1(b)(2) + - RA-2 + - RA-2(a) + - RA-2(b) + - RA-2(c) + - RA-3 + - RA-3(a) + - RA-3(b) + - RA-3(c) + - RA-3(d) + - RA-3(e) + - RA-5 + - RA-5(a) + - RA-5(b) + - RA-5(b)(1) + - RA-5(b)(2) + - RA-5(b)(3) + - RA-5(c) + - RA-5(d) + - RA-5(e) + - RA-5(1) + - RA-5(2) + - RA-5(5) + - SA-1 + - SA-1(a) + - SA-1(a)(1) + - SA-1(a)(2) + - SA-1(b) + - SA-1(b)(1) + - SA-1(b)(2) + - SA-2 + - SA-2(a) + - SA-2(b) + - SA-2(c) + - SA-3 + - SA-3(a) + - SA-3(b) + - SA-3(c) + - SA-3(d) + - SA-4 + - SA-4(a) + - SA-4(b) + - SA-4(c) + - SA-4(d) + - SA-4(e) + - SA-4(f) + - SA-4(g) + - SA-4(1) + - SA-4(2) + - SA-4(9) + - SA-4(10) + - SA-5 + - SA-5(a) + - SA-5(a)(1) + - SA-5(a)(2) + - SA-5(a)(3) + - SA-5(b) + - SA-5(b)(1) + - SA-5(b)(2) + - SA-5(b)(3) + - SA-5(c) + - SA-5(d) + - SA-5(e) + - SA-8 + - SA-9 + - SA-9(a) + - SA-9(b) + - SA-9(c) + - SA-9(2) + - SA-10 + - SA-10(a) + - SA-10(b) + - SA-10(c) + - SA-10(d) + - SA-10(e) + - SA-11 + - SA-11(a) + - SA-11(b) + - SA-11(c) + - SA-11(d) + - SA-11(e) + - SC-1 + - SC-1(a) + - SC-1(a)(1) + - SC-1(a)(2) + - SC-1(b) + - SC-1(b)(1) + - SC-1(b)(2) + - SC-2 + - SC-4 + - SC-5 + - SC-7 + - SC-7(a) + - SC-7(b) + - SC-7(c) + - SC-7(3) + - SC-7(4) + - SC-7(4)(a) + - SC-7(4)(b) + - SC-7(4)(c) + - SC-7(4)(d) + - SC-7(4)(e) + - SC-7(5) + - SC-7(7) + - SC-8 + - SC-8(1) + - SC-10 + - SC-12 + - SC-13 + - SC-15 + - SC-15(a) + - SC-15(b) + - SC-17 + - SC-18 + - SC-18(a) + - SC-18(b) + - SC-18(c) + - SC-19 + - SC-19(a) + - SC-19(b) + - SC-20 + - SC-20(a) + - SC-20(b) + - SC-21 + - SC-22 + - SC-23 + - SC-28 + - SC-39 + - SI-1 + - SI-1(a) + - SI-1(a)(1) + - SI-1(a)(2) + - SI-1(b) + - SI-1(b)(1) + - SI-1(b)(2) + - SI-2 + - SI-2(a) + - SI-2(b) + - SI-2(c) + - SI-2(d) + - SI-2(2) + - SI-3 + - SI-3(1) + - SI-3(2) + - SI-4 + - SI-4(a) + - SI-4(a)(1) + - SI-4(a)(2) + - SI-4(b) + - SI-4(c) + - SI-4(c)(1) + - SI-4(c)(2) + - SI-4(d) + - SI-4(e) + - SI-4(f) + - SI-4(g) + - SI-4(2) + - SI-4(4) + - SI-4(5) + - SI-5 + - SI-5(a) + - SI-5(b) + - SI-5(c) + - SI-5(d) + - SI-7 + - SI-7(1) + - SI-7(7) + - SI-8 + - SI-8(a) + - SI-8(b) + - SI-8(1) + - SI-8(2) + - SI-10 + - SI-11 + - SI-11(a) + - SI-11(b) + - SI-12 + - SI-16 +high: + - AC-1 + - AC-1(a) + - AC-1(a)(1) + - AC-1(a)(2) + - AC-1(b) + - AC-1(b)(1) + - AC-1(b)(2) + - AC-2 + - AC-2(a) + - AC-2(b) + - AC-2(c) + - AC-2(d) + - AC-2(e) + - AC-2(f) + - AC-2(g) + - AC-2(h) + - AC-2(h)(1) + - AC-2(h)(2) + - AC-2(h)(3) + - AC-2(i) + - AC-2(i)(1) + - AC-2(i)(2) + - AC-2(i)(3) + - AC-2(j) + - AC-2(k) + - AC-2(1) + - AC-2(2) + - AC-2(3) + - AC-2(4) + - AC-2(5) + - AC-2(11) + - AC-2(12) + - AC-2(12)(a) + - AC-2(12)(b) + - AC-2(13) + - AC-3 + - AC-4 + - AC-5 + - AC-5(a) + - AC-5(b) + - AC-5(c) + - AC-6 + - AC-6(1) + - AC-6(2) + - AC-6(3) + - AC-6(5) + - AC-6(9) + - AC-6(10) + - AC-7 + - AC-7(a) + - AC-7(b) + - AC-8 + - AC-8(a) + - AC-8(a)(1) + - AC-8(a)(2) + - AC-8(a)(3) + - AC-8(a)(4) + - AC-8(b) + - AC-8(c) + - AC-8(c)(1) + - AC-8(c)(2) + - AC-8(c)(3) + - AC-10 + - AC-11 + - AC-11(a) + - AC-11(b) + - AC-11(1) + - AC-12 + - AC-14 + - AC-14(a) + - AC-14(b) + - AC-17 + - AC-17(a) + - AC-17(b) + - AC-17(1) + - AC-17(2) + - AC-17(3) + - AC-17(4) + - AC-17(4)(a) + - AC-17(4)(b) + - AC-18 + - AC-18(a) + - AC-18(b) + - AC-18(1) + - AC-18(4) + - AC-18(5) + - AC-19 + - AC-19(a) + - AC-19(b) + - AC-19(5) + - AC-20 + - AC-20(a) + - AC-20(b) + - AC-20(1) + - AC-20(1)(a) + - AC-20(1)(b) + - AC-20(2) + - AC-21 + - AC-21(a) + - AC-21(b) + - AC-22 + - AC-22(a) + - AC-22(b) + - AC-22(c) + - AC-22(d) + - AT-1 + - AT-1(a) + - AT-1(a)(1) + - AT-1(a)(2) + - AT-1(b) + - AT-1(b)(1) + - AT-1(b)(2) + - AT-2 + - AT-2(a) + - AT-2(b) + - AT-2(c) + - AT-2(2) + - AT-3 + - AT-3(a) + - AT-3(b) + - AT-3(c) + - AT-4 + - AT-4(a) + - AT-4(b) + - AU-1 + - AU-1(a) + - AU-1(a)(1) + - AU-1(a)(2) + - AU-1(b) + - AU-1(b)(1) + - AU-1(b)(2) + - AU-2 + - AU-2(a) + - AU-2(b) + - AU-2(c) + - AU-2(d) + - AU-2(3) + - AU-3 + - AU-3(1) + - AU-3(2) + - AU-4 + - AU-5 + - AU-5(a) + - AU-5(b) + - AU-5(1) + - AU-5(2) + - AU-6 + - AU-6(a) + - AU-6(b) + - AU-6(1) + - AU-6(3) + - AU-6(5) + - AU-6(6) + - AU-7 + - AU-7(a) + - AU-7(b) + - AU-7(1) + - AU-8 + - AU-8(a) + - AU-8(b) + - AU-8(1) + - AU-8(1)(a) + - AU-8(1)(b) + - AU-9 + - AU-9(2) + - AU-9(3) + - AU-9(4) + - AU-10 + - AU-11 + - AU-12 + - AU-12(a) + - AU-12(b) + - AU-12(c) + - AU-12(1) + - AU-12(3) + - CA-1 + - CA-1(a) + - CA-1(a)(1) + - CA-1(a)(2) + - CA-1(b) + - CA-1(b)(1) + - CA-1(b)(2) + - CA-2 + - CA-2(a) + - CA-2(a)(1) + - CA-2(a)(2) + - CA-2(a)(3) + - CA-2(b) + - CA-2(c) + - CA-2(d) + - CA-2(1) + - CA-2(2) + - CA-3 + - CA-3(a) + - CA-3(b) + - CA-3(c) + - CA-3(5) + - CA-5 + - CA-5(a) + - CA-5(b) + - CA-6 + - CA-6(a) + - CA-6(b) + - CA-6(c) + - CA-7 + - CA-7(a) + - CA-7(b) + - CA-7(c) + - CA-7(d) + - CA-7(e) + - CA-7(f) + - CA-7(g) + - CA-7(1) + - CA-8 + - CA-9 + - CA-9(a) + - CA-9(b) + - CM-1 + - CM-1(a) + - CM-1(a)(1) + - CM-1(a)(2) + - CM-1(b) + - CM-1(b)(1) + - CM-1(b)(2) + - CM-2 + - CM-2(1) + - CM-2(1)(a) + - CM-2(1)(b) + - CM-2(1)(c) + - CM-2(2) + - CM-2(3) + - CM-2(7) + - CM-2(7)(a) + - CM-2(7)(b) + - CM-3 + - CM-3(a) + - CM-3(b) + - CM-3(c) + - CM-3(d) + - CM-3(e) + - CM-3(f) + - CM-3(g) + - CM-3(1) + - CM-3(1)(a) + - CM-3(1)(b) + - CM-3(1)(c) + - CM-3(1)(d) + - CM-3(1)(e) + - CM-3(1)(f) + - CM-3(2) + - CM-4 + - CM-4(1) + - CM-5 + - CM-5(1) + - CM-5(2) + - CM-5(3) + - CM-6 + - CM-6(a) + - CM-6(b) + - CM-6(c) + - CM-6(d) + - CM-6(1) + - CM-6(2) + - CM-7 + - CM-7(a) + - CM-7(b) + - CM-7(1) + - CM-7(1)(a) + - CM-7(1)(b) + - CM-7(2) + - CM-7(5) + - CM-7(5)(a) + - CM-7(5)(b) + - CM-7(5)(c) + - CM-8 + - CM-8(a) + - CM-8(a)(1) + - CM-8(a)(2) + - CM-8(a)(3) + - CM-8(a)(4) + - CM-8(b) + - CM-8(1) + - CM-8(2) + - CM-8(3) + - CM-8(3)(a) + - CM-8(3)(b) + - CM-8(4) + - CM-8(5) + - CM-9 + - CM-9(a) + - CM-9(b) + - CM-9(c) + - CM-9(d) + - CM-10 + - CM-10(a) + - CM-10(b) + - CM-10(c) + - CM-11 + - CM-11(a) + - CM-11(b) + - CM-11(c) + - CP-1 + - CP-1(a) + - CP-1(a)(1) + - CP-1(a)(2) + - CP-1(b) + - CP-1(b)(1) + - CP-1(b)(2) + - CP-2 + - CP-2(a) + - CP-2(a)(1) + - CP-2(a)(2) + - CP-2(a)(3) + - CP-2(a)(4) + - CP-2(a)(5) + - CP-2(a)(6) + - CP-2(b) + - CP-2(c) + - CP-2(d) + - CP-2(e) + - CP-2(f) + - CP-2(g) + - CP-2(1) + - CP-2(2) + - CP-2(3) + - CP-2(4) + - CP-2(5) + - CP-2(8) + - CP-3 + - CP-3(a) + - CP-3(b) + - CP-3(c) + - CP-3(1) + - CP-4 + - CP-4(a) + - CP-4(b) + - CP-4(c) + - CP-4(1) + - CP-4(2) + - CP-4(2)(a) + - CP-4(2)(b) + - CP-6 + - CP-6(a) + - CP-6(b) + - CP-6(1) + - CP-6(2) + - CP-6(3) + - CP-7 + - CP-7(a) + - CP-7(b) + - CP-7(c) + - CP-7(1) + - CP-7(2) + - CP-7(3) + - CP-7(4) + - CP-8 + - CP-8(1) + - CP-8(1)(a) + - CP-8(1)(b) + - CP-8(2) + - CP-8(3) + - CP-8(4) + - CP-8(4)(a) + - CP-8(4)(b) + - CP-8(4)(c) + - CP-9 + - CP-9(a) + - CP-9(b) + - CP-9(c) + - CP-9(d) + - CP-9(1) + - CP-9(2) + - CP-9(3) + - CP-9(5) + - CP-10 + - CP-10(2) + - CP-10(4) + - IA-1 + - IA-1(a) + - IA-1(a)(1) + - IA-1(a)(2) + - IA-1(b) + - IA-1(b)(1) + - IA-1(b)(2) + - IA-2 + - IA-2(1) + - IA-2(2) + - IA-2(3) + - IA-2(4) + - IA-2(8) + - IA-2(9) + - IA-2(11) + - IA-2(12) + - IA-3 + - IA-4 + - IA-4(a) + - IA-4(b) + - IA-4(c) + - IA-4(d) + - IA-4(e) + - IA-5 + - IA-5(a) + - IA-5(b) + - IA-5(c) + - IA-5(d) + - IA-5(e) + - IA-5(f) + - IA-5(g) + - IA-5(h) + - IA-5(i) + - IA-5(j) + - IA-5(1) + - IA-5(1)(a) + - IA-5(1)(b) + - IA-5(1)(c) + - IA-5(1)(d) + - IA-5(1)(e) + - IA-5(1)(f) + - IA-5(2) + - IA-5(2)(a) + - IA-5(2)(b) + - IA-5(2)(c) + - IA-5(2)(d) + - IA-5(3) + - IA-5(11) + - IA-6 + - IA-7 + - IA-8 + - IA-8(1) + - IA-8(2) + - IA-8(3) + - IA-8(4) + - IR-1 + - IR-1(a) + - IR-1(a)(1) + - IR-1(a)(2) + - IR-1(b) + - IR-1(b)(1) + - IR-1(b)(2) + - IR-2 + - IR-2(a) + - IR-2(b) + - IR-2(c) + - IR-2(1) + - IR-2(2) + - IR-3 + - IR-3(2) + - IR-4 + - IR-4(a) + - IR-4(b) + - IR-4(c) + - IR-4(1) + - IR-4(4) + - IR-5 + - IR-5(1) + - IR-6 + - IR-6(a) + - IR-6(b) + - IR-6(1) + - IR-7 + - IR-7(1) + - IR-8 + - IR-8(a) + - IR-8(a)(1) + - IR-8(a)(2) + - IR-8(a)(3) + - IR-8(a)(4) + - IR-8(a)(5) + - IR-8(a)(6) + - IR-8(a)(7) + - IR-8(a)(8) + - IR-8(b) + - IR-8(c) + - IR-8(d) + - IR-8(e) + - IR-8(f) + - MA-1 + - MA-1(a) + - MA-1(a)(1) + - MA-1(a)(2) + - MA-1(b) + - MA-1(b)(1) + - MA-1(b)(2) + - MA-2 + - MA-2(a) + - MA-2(b) + - MA-2(c) + - MA-2(d) + - MA-2(e) + - MA-2(f) + - MA-2(2) + - MA-2(2)(a) + - MA-2(2)(b) + - MA-3 + - MA-3(1) + - MA-3(2) + - MA-3(3) + - MA-3(3)(a) + - MA-3(3)(b) + - MA-3(3)(c) + - MA-3(3)(d) + - MA-4 + - MA-4(a) + - MA-4(b) + - MA-4(c) + - MA-4(d) + - MA-4(e) + - MA-4(2) + - MA-4(3) + - MA-4(3)(a) + - MA-4(3)(b) + - MA-5 + - MA-5(a) + - MA-5(b) + - MA-5(c) + - MA-5(1) + - MA-5(1)(a) + - MA-5(1)(a)(1) + - MA-5(1)(a)(2) + - MA-5(1)(b) + - MA-6 + - MP-1 + - MP-1(a) + - MP-1(a)(1) + - MP-1(a)(2) + - MP-1(b) + - MP-1(b)(1) + - MP-1(b)(2) + - MP-2 + - MP-3 + - MP-3(a) + - MP-3(b) + - MP-4 + - MP-4(a) + - MP-4(b) + - MP-5 + - MP-5(a) + - MP-5(b) + - MP-5(c) + - MP-5(d) + - MP-5(4) + - MP-6 + - MP-6(a) + - MP-6(b) + - MP-6(1) + - MP-6(2) + - MP-6(3) + - MP-7 + - MP-7(1) + - PE-1 + - PE-1(a) + - PE-1(a)(1) + - PE-1(a)(2) + - PE-1(b) + - PE-1(b)(1) + - PE-1(b)(2) + - PE-2 + - PE-2(a) + - PE-2(b) + - PE-2(c) + - PE-2(d) + - PE-3 + - PE-3(a) + - PE-3(a)(1) + - PE-3(a)(2) + - PE-3(b) + - PE-3(c) + - PE-3(d) + - PE-3(e) + - PE-3(f) + - PE-3(g) + - PE-3(1) + - PE-4 + - PE-5 + - PE-6 + - PE-6(a) + - PE-6(b) + - PE-6(c) + - PE-6(1) + - PE-6(4) + - PE-8 + - PE-8(a) + - PE-8(b) + - PE-8(1) + - PE-9 + - PE-10 + - PE-10(a) + - PE-10(b) + - PE-10(c) + - PE-11 + - PE-11(1) + - PE-12 + - PE-13 + - PE-13(1) + - PE-13(2) + - PE-13(3) + - PE-14 + - PE-14(a) + - PE-14(b) + - PE-15 + - PE-15(1) + - PE-16 + - PE-17 + - PE-17(a) + - PE-17(b) + - PE-17(c) + - PE-18 + - PL-1 + - PL-1(a) + - PL-1(a)(1) + - PL-1(a)(2) + - PL-1(b) + - PL-1(b)(1) + - PL-1(b)(2) + - PL-2 + - PL-2(a) + - PL-2(a)(1) + - PL-2(a)(2) + - PL-2(a)(3) + - PL-2(a)(4) + - PL-2(a)(5) + - PL-2(a)(6) + - PL-2(a)(7) + - PL-2(a)(8) + - PL-2(a)(9) + - PL-2(b) + - PL-2(c) + - PL-2(d) + - PL-2(e) + - PL-2(3) + - PL-4 + - PL-4(a) + - PL-4(b) + - PL-4(c) + - PL-4(d) + - PL-4(1) + - PL-8 + - PL-8(a) + - PL-8(a)(1) + - PL-8(a)(2) + - PL-8(a)(3) + - PL-8(b) + - PL-8(c) + - PS-1 + - PS-1(a) + - PS-1(a)(1) + - PS-1(a)(2) + - PS-1(b) + - PS-1(b)(1) + - PS-1(b)(2) + - PS-2 + - PS-2(a) + - PS-2(b) + - PS-2(c) + - PS-3 + - PS-3(a) + - PS-3(b) + - PS-4 + - PS-4(a) + - PS-4(b) + - PS-4(c) + - PS-4(d) + - PS-4(e) + - PS-4(f) + - PS-4(2) + - PS-5 + - PS-5(a) + - PS-5(b) + - PS-5(c) + - PS-5(d) + - PS-6 + - PS-6(a) + - PS-6(b) + - PS-6(c) + - PS-6(c)(1) + - PS-6(c)(2) + - PS-7 + - PS-7(a) + - PS-7(b) + - PS-7(c) + - PS-7(d) + - PS-7(e) + - PS-8 + - PS-8(a) + - PS-8(b) + - RA-1 + - RA-1(a) + - RA-1(a)(1) + - RA-1(a)(2) + - RA-1(b) + - RA-1(b)(1) + - RA-1(b)(2) + - RA-2 + - RA-2(a) + - RA-2(b) + - RA-2(c) + - RA-3 + - RA-3(a) + - RA-3(b) + - RA-3(c) + - RA-3(d) + - RA-3(e) + - RA-5 + - RA-5(a) + - RA-5(b) + - RA-5(b)(1) + - RA-5(b)(2) + - RA-5(b)(3) + - RA-5(c) + - RA-5(d) + - RA-5(e) + - RA-5(1) + - RA-5(2) + - RA-5(4) + - RA-5(5) + - SA-1 + - SA-1(a) + - SA-1(a)(1) + - SA-1(a)(2) + - SA-1(b) + - SA-1(b)(1) + - SA-1(b)(2) + - SA-2 + - SA-2(a) + - SA-2(b) + - SA-2(c) + - SA-3 + - SA-3(a) + - SA-3(b) + - SA-3(c) + - SA-3(d) + - SA-4 + - SA-4(a) + - SA-4(b) + - SA-4(c) + - SA-4(d) + - SA-4(e) + - SA-4(f) + - SA-4(g) + - SA-4(1) + - SA-4(2) + - SA-4(9) + - SA-4(10) + - SA-5 + - SA-5(a) + - SA-5(a)(1) + - SA-5(a)(2) + - SA-5(a)(3) + - SA-5(b) + - SA-5(b)(1) + - SA-5(b)(2) + - SA-5(b)(3) + - SA-5(c) + - SA-5(d) + - SA-5(e) + - SA-8 + - SA-9 + - SA-9(a) + - SA-9(b) + - SA-9(c) + - SA-9(2) + - SA-10 + - SA-10(a) + - SA-10(b) + - SA-10(c) + - SA-10(d) + - SA-10(e) + - SA-11 + - SA-11(a) + - SA-11(b) + - SA-11(c) + - SA-11(d) + - SA-11(e) + - SA-12 + - SA-15 + - SA-15(a) + - SA-15(a)(1) + - SA-15(a)(2) + - SA-15(a)(3) + - SA-15(a)(4) + - SA-15(b) + - SA-16 + - SA-17 + - SA-17(a) + - SA-17(b) + - SA-17(c) + - SC-1 + - SC-1(a) + - SC-1(a)(1) + - SC-1(a)(2) + - SC-1(b) + - SC-1(b)(1) + - SC-1(b)(2) + - SC-2 + - SC-3 + - SC-4 + - SC-5 + - SC-7 + - SC-7(a) + - SC-7(b) + - SC-7(c) + - SC-7(3) + - SC-7(4) + - SC-7(4)(a) + - SC-7(4)(b) + - SC-7(4)(c) + - SC-7(4)(d) + - SC-7(4)(e) + - SC-7(5) + - SC-7(7) + - SC-7(8) + - SC-7(18) + - SC-7(21) + - SC-8 + - SC-8(1) + - SC-10 + - SC-12 + - SC-12(1) + - SC-13 + - SC-15 + - SC-15(a) + - SC-15(b) + - SC-17 + - SC-18 + - SC-18(a) + - SC-18(b) + - SC-18(c) + - SC-19 + - SC-19(a) + - SC-19(b) + - SC-20 + - SC-20(a) + - SC-20(b) + - SC-21 + - SC-22 + - SC-23 + - SC-24 + - SC-28 + - SC-39 + - SI-1 + - SI-1(a) + - SI-1(a)(1) + - SI-1(a)(2) + - SI-1(b) + - SI-1(b)(1) + - SI-1(b)(2) + - SI-2 + - SI-2(a) + - SI-2(b) + - SI-2(c) + - SI-2(d) + - SI-2(1) + - SI-2(2) + - SI-3 + - SI-3(a) + - SI-3(b) + - SI-3(c) + - SI-3(c)(1) + - SI-3(c)(2) + - SI-3(d) + - SI-3(1) + - SI-3(2) + - SI-4 + - SI-4(a) + - SI-4(a)(1) + - SI-4(a)(2) + - SI-4(b) + - SI-4(c) + - SI-4(c)(1) + - SI-4(c)(2) + - SI-4(d) + - SI-4(e) + - SI-4(f) + - SI-4(g) + - SI-4(2) + - SI-4(4) + - SI-4(5) + - SI-5 + - SI-5(a) + - SI-5(b) + - SI-5(c) + - SI-5(d) + - SI-5(1) + - SI-6 + - SI-6(a) + - SI-6(b) + - SI-6(c) + - SI-6(d) + - SI-7 + - SI-7(1) + - SI-7(2) + - SI-7(5) + - SI-7(7) + - SI-7(14) + - SI-7(14)(a) + - SI-7(14)(b) + - SI-8 + - SI-8(a) + - SI-8(b) + - SI-8(1) + - SI-8(2) + - SI-10 + - SI-11 + - SI-11(a) + - SI-11(b) + - SI-12 + - SI-16 diff --git a/includes/enablePF-mscp.sh b/includes/enablePF-mscp.sh new file mode 100644 index 00000000..ade19866 --- /dev/null +++ b/includes/enablePF-mscp.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +#enabling macos application firewall +enable_macos_application_firewall () { + + /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on + /usr/libexec/ApplicationFirewall/socketfilterfw --setloggingopt detail + /usr/libexec/ApplicationFirewall/socketfilterfw --setallowsigned on + /usr/libexec/ApplicationFirewall/socketfilterfw --setallowsignedapp on + +} + +#enabling pf firewall with macsec rules +enable_pf_firewall_with_macsec_rules () { + macsec_pfctl_plist="/Library/LaunchDaemons/macsec.pfctl.plist" + + if [[ -e "$macsec_pfctl_plist" ]]; then + echo "LaunchDaemon already exists, flushing and reloading rules..." + pfctl -e 2> /dev/null + pfctl -f /etc/pf.conf 2> /dev/null + return 0 + fi + + # copy system provided launchd for custom ruleset + cp "/System/Library/LaunchDaemons/com.apple.pfctl.plist" "$macsec_pfctl_plist" + #allow pf to be enabled when the job is loaded + /usr/libexec/PlistBuddy -c "Add :ProgramArguments:1 string -e" $macsec_pfctl_plist + #use new label to not conflict with System's pfctl + /usr/libexec/PlistBuddy -c "Set :Label macsec.pfctl" $macsec_pfctl_plist + + # enable the firewall + pfctl -e 2> /dev/null + + #make pf run at system startup + launchctl enable system/macsec.pfctl + launchctl bootstrap system $macsec_pfctl_plist + + pfctl -f /etc/pf.conf 2> /dev/null #flush the pf ruleset (reload the rules) + +} + +# append the macsec anchors to pf.conf +configure_pf_config_add_macsec_anchors () { + + # check to see if macsec anchors exists + anchors_exist=$(grep -c '^anchor "macsec_pf_anchors"' /etc/pf.conf) + + if [[ $anchors_exist == "0" ]];then + echo 'anchor "macsec_pf_anchors"' >> /etc/pf.conf + echo 'load anchor "macsec_pf_anchors" from "/etc/pf.anchors/macsec_pf_anchors"' >> /etc/pf.conf + else + echo "macsec anchors exist, continuing..." + fi + +} + + +# Create /etc/pf.anchors/macsec_pf_anchors +create_macsec_pf_anchors () { +if [[ -e /etc/pf.anchors/macsec_pf_anchors ]]; then + echo "macsec Anchor file exists, deleting and recreating..." + rm -f /etc/pf.anchors/macsec_pf_anchors +fi + + +cat > /etc/pf.anchors/macsec_pf_anchors <<'ENDCONFIG' + +anchor macsec_pf_anchors + +#default deny all in, allow all out and keep state +block in all +pass out all keep state + +## Allow DHCP +pass in inet proto udp from port 67 to port 68 +pass in inet6 proto udp from port 547 to port 546 + +## Allow incoming SSH +pass in proto tcp to any port 22 + +#apple file service --port 548-- pf firewall rule +block in log proto tcp to any port { 548 } + +#bonjour component SSDP --port 1900-- pf firewall rule +block log proto udp to any port 1900 + +#finger --port 79-- pf firewall rule +block log proto tcp to any port 79 + +#ftp --ports 20 21-- pf firewall rule +block in log proto { tcp udp } to any port { 20 21 } + +#http --port 80-- pf firewall rule +block in log proto { tcp udp } to any port 80 + +#icmp pf firewall rule +block in log proto icmp + +#imap --port 143-- pf firewall rule +block in log proto tcp to any port 143 + +#imaps --port 993-- pf firewall rule +block in log proto tcp to any port 993 + +#iTunes sharing --port 3689-- pf firewall rule +block log proto tcp to any port 3689 + +#mDNSResponder --port 5353-- pf firewall rule +block log proto udp to any port 5353 + +#nfs --port 2049-- pf firewall rule +block log proto tcp to any port 2049 + +#optical drive sharing --port 49152-- pf firewall rule +block log proto tcp to any port 49152 + +#pop3 --port 110-- pf firewall rule +block in log proto tcp to any port 110 + +#pop3s --port 995-- pf firewall rule +block in log proto tcp to any port 995 + +#remote apple events --port 3031-- pf firewall rule +block in log proto tcp to any port 3031 + +#screen_sharing --port 5900-- pf firewall rule +block in log proto tcp to any port 5900 +#allow screen sharing from localhost while tunneled via SSH +pass in quick on lo0 proto tcp from any to any port 5900 + +#smb --ports 139 445 137 138-- pf firewall rule +block in log proto tcp to any port { 139 445 } +block in log proto udp to any port { 137 138 } + +#smtp --port 25-- pf firewall rule +block in log proto tcp to any port 25 + +#telnet --port 23-- pf firewall rule +block in log proto { tcp udp } to any port 23 + +#tftp --port 69-- pf firewall rule +block log proto { tcp udp } to any port 69 + +#uucp --port 540-- pf firewall rule +block log proto tcp to any port 540 + +ENDCONFIG +} + +#### + +enable_macos_application_firewall +create_macsec_pf_anchors +configure_pf_config_add_macsec_anchors +enable_pf_firewall_with_macsec_rules diff --git a/includes/pwpolicy.xml b/includes/pwpolicy.xml new file mode 100644 index 00000000..85d90048 --- /dev/null +++ b/includes/pwpolicy.xml @@ -0,0 +1,138 @@ + + + + + policyCategoryAuthentication + + + policyContent + (policyAttributeFailedAuthentications < policyAttributeMaximumFailedAuthentications) OR (policyAttributeCurrentTime > (policyAttributeLastFailedAuthenticationTime + autoEnableInSeconds)) + policyIdentifier + Authentication Lockout + policyParameters + + autoEnableInSeconds + 300 + policyAttributeMaximumFailedAuthentications + 3 + + + + policyContent + policyAttributeLastAuthenticationTime > policyAttributeCurrentTime - (policyAttributeInactiveDays * 24 * 60 * 60) + policyIdentifier + Inactive Account + policyParameters + + policyAttributeInactiveDays + 35 + + + + policyCategoryPasswordChange + + + policyContent + policyAttributeCurrentTime > policyAttributeLastPasswordChangeTime + (policyAttributeExpiresEveryNDays * 24 * 60 * 60) + policyIdentifier + Password Expires after 60 days + policyParameters + + policyAttributeExpiresEveryNDays + 60 + + + + policyCategoryPasswordContent + + + policyContent + policyAttributePassword matches '(.*[A-Z].*){1,}+' + policyIdentifier + Must have at least 1 uppercase letter + policyParameters + + minimumAlphaCharactersUpperCase + 1 + + + + policyContent + policyAttributeLastPasswordChangeTime < policyAttributeCurrentTime - (policyAttributeMinimumLifetimeHours * 60 * 60) + policyIdentifier + Minimum Password Lifetime + policyParameters + + policyAttributeMinimumLifetimeHours + 24 + + + + policyContent + policyAttributePassword matches '.{15,}+' + policyIdentifier + Must be at least 15 characters + policyParameters + + minimumLength + 15 + + + + policyContent + policyAttributePassword matches '(.*[0-9].*){1,}+' + policyIdentifier + Must have at least 1 numeric value + policyParameters + + minimumNumericCharacters + 2 + + + + policyContent + policyAttributePassword matches '(.*[a-z].*){1,}+' + policyIdentifier + Must have at least 1 lowercase letter + policyParameters + + minimumAlphaCharactersLowerCase + 1 + + + + policyContent + policyAttributePassword matches '(.*[A-Z].*){1,}+' + policyIdentifier + Must have at least 1 uppercase letter + policyParameters + + minimumAlphaCharacters + 1 + + + + policyContent + policyAttributePassword matches '(.*[^a-zA-Z0-9].*){1,}+' + policyIdentifier + Must have at least 1 special characters + policyParameters + + minimumSymbols + 1 + + + + policyContent + none policyAttributePasswordHashes in policyAttributePasswordHistory + policyIdentifier + Cannot match the last 5 passwords + policyParameters + + policyAttributePasswordHistoryDepth + 5 + + + + + \ No newline at end of file diff --git a/includes/supported_payloads.yaml b/includes/supported_payloads.yaml new file mode 100644 index 00000000..5b64f49e --- /dev/null +++ b/includes/supported_payloads.yaml @@ -0,0 +1,111 @@ +payloads_types: + - com.apple.ADCertificate.managed + - com.apple.AIM.account + - com.apple.AssetCache.managed + - com.apple.Compressor + - com.apple.Dictionary + - com.apple.DirectoryService.managed + - com.apple.DiscRecording + - com.apple.Enterprise-Connect + - com.apple.FinalCut + - com.apple.MCX + - com.apple.MCX.FileVault2 + - com.apple.MCX.TimeMachine + - com.apple.ManagedClient.preferences + - com.apple.NSExtension + - com.apple.NetworkBrowser + - com.apple.Safari + - com.apple.SetupAssistant.managed + - com.apple.Siri + - com.apple.SoftwareUpdate + - com.apple.Spotlight + - com.apple.SubmitDiagInfo + - com.apple.SystemConfiguration + - com.apple.TCC.configuration-profile-policy + - com.apple.TextEdit + - com.apple.TimeMachine + - com.apple.airplay + - com.apple.airplay.security + - com.apple.airprint + - com.apple.app.lock + - com.apple.applicationaccess + - com.apple.applicationaccess.new + - com.apple.appstore + - com.apple.asam + - com.apple.assistant.support + - com.apple.caldav.account + - com.apple.carddav.account + - com.apple.cellular + - com.apple.conferenceroomdisplay + - com.apple.configurationprofile.identification + - com.apple.coreservices.uiagent + - com.apple.dashboard + - com.apple.desktop + - com.apple.desktopservices + - com.apple.dnsProxy.managed + - com.apple.dock + - com.apple.domains + - com.apple.eas.account + - com.apple.education + - com.apple.ews.account + - com.apple.familycontrols.contentfilter + - com.apple.finder + - com.apple.font + - com.apple.gamed + - com.apple.garageband10 + - com.apple.google-oauth + - com.apple.iBooksX + - com.apple.iMovieApp + - com.apple.iTunes + - com.apple.iWork.Keynote + - com.apple.iWork.Numbers + - com.apple.iWork.Pages + - com.apple.icloud.managed + - com.apple.ironwood.support + - com.apple.jabber.account + - com.apple.ldap.account + - com.apple.logic10 + - com.apple.loginitems.managed + - com.apple.loginwindow + - com.apple.mDNSResponder + - com.apple.mail.managed + - com.apple.mcxloginscripts + - com.apple.mobiledevice.passwordpolicy + - com.apple.motionapp + - com.apple.networkusagerules + - com.apple.notificationsettings + - com.apple.osxserver.account + - com.apple.preference.security + - com.apple.profileRemovalPassword + - com.apple.proxy.http.global + - com.apple.screencapture + - com.apple.screensaver + - com.apple.screensaver.user + - com.apple.security + - com.apple.security.FDERecoveryKeyEscrow + - com.apple.security.FDERecoveryRedirect + - com.apple.security.certificatetransparency + - com.apple.security.firewall + - com.apple.security.pem + - com.apple.security.pkcs1 + - com.apple.security.pkcs12 + - com.apple.security.scep + - com.apple.security.smartcard + - com.apple.shareddeviceconfiguration + - com.apple.sso + - com.apple.subscribedcalendar.account + - com.apple.syspolicy.kernel-extension-policy + - com.apple.systemmigration + - com.apple.systempolicy.control + - com.apple.systempolicy.managed + - com.apple.systempreferences + - com.apple.systemuiserver + - com.apple.touristd + - com.apple.tvremote + - com.apple.universalaccess + - com.apple.webClip.managed + - com.apple.webcontent-filter + - com.apple.wifi.managed + - com.apple.xsan + - com.apple.smb.server + - com.apple.AppleFileServer \ No newline at end of file diff --git a/rules/audit/audit_acls_files_configure.yaml b/rules/audit/audit_acls_files_configure.yaml new file mode 100644 index 00000000..eec2dc09 --- /dev/null +++ b/rules/audit/audit_acls_files_configure.yaml @@ -0,0 +1,39 @@ +id: audit_acls_files_configure +title: "Configure Audit Service to Create Log Files and Folder which prevent unauthorized access" +discussion: | + Audit information and audit tools must be configured to prevent unauthorized access, modification, and deletion. The audit service must be configured to create log files with the correct permissions to prevent normal users from reading audit logs. If log files are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + The audit log files must not have access control list (ACL) privileges set. +check: | + /bin/ls -le $(/usr/bin/awk -F: '/^dir/{print $2}' /etc/security/audit_control) | /usr/bin/awk '{print $1}' | /usr/bin/grep -c ":" +result: + integer: 0 +fix: | + [source,bash] + ---- + /bin/chmod -RN $(/usr/bin/awk -F: '/^dir/{print $2}' /etc/security/audit_control) + ---- +references: + cce: + - CCE-84701-2 + cci: + - CCI-000162 + - CCI-001314 + 800-53r4: + - AU-9 + - SI-11(b) + srg: + - SRG-OS-000057-GPOS-00027 + - SRG-OS-000206-GPOS-00084 + disa_stig: + - AOSX-14-000030 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: diff --git a/rules/audit/audit_acls_files_mode_configure.yaml b/rules/audit/audit_acls_files_mode_configure.yaml new file mode 100644 index 00000000..ad84f16e --- /dev/null +++ b/rules/audit/audit_acls_files_mode_configure.yaml @@ -0,0 +1,35 @@ +id: audit_acls_files_mode_configure +title: "Configure Audit Log Files to Mode 440 or Less Permissive" +discussion: | + The audit service must be configured to create log files with permissions which prevent normal users from reading, modifying or deleting audit logs. If log files are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + The audit log files must only be readable by the Root user and by the group Wheel. +check: | + /bin/ls -l $(/usr/bin/grep '^dir' /etc/security/audit_control | awk -F: '{print $2}') | /usr/bin/awk '!/-r--r-----|current|total/{print $1}' | /usr/bin/wc -l | tr -d ' ' +result: + integer: 0 +fix: | + [source,bash] + ---- + /bin/chmod 440 $(/usr/bin/grep '^dir' /etc/security/audit_control | awk -F: '{print $2}') + ---- +references: + cce: + - CCE-84702-0 + cci: + - CCI-000162 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001016 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: diff --git a/rules/audit/audit_acls_folder_wheel_configure.yaml b/rules/audit/audit_acls_folder_wheel_configure.yaml new file mode 100644 index 00000000..144a591a --- /dev/null +++ b/rules/audit/audit_acls_folder_wheel_configure.yaml @@ -0,0 +1,36 @@ +id: audit_acls_folder_wheel_configure +title: "Configure Audit Log Files Group ownership to Wheel" +discussion: | + The audit service must be configured to create log files with permissions which prevent normal users from reading, modifying or deleting audit logs. If log files are set to only be readable and writable by root or administrative users with sudo, the risk is mitigated. + + The audit log files must have the group ownership set to Wheel. +check: | + /bin/ls -n $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') | /usr/bin/awk '{s+=$4} END {print s}' +result: + integer: 0 +fix: | + [source,bash] + ---- + /usr/sbin/chown -R root $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') + ---- +references: + cce: + - CCE-84703-8 + cci: + - CCI-000162 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001012 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: diff --git a/rules/audit/audit_acls_folders_configure.yaml b/rules/audit/audit_acls_folders_configure.yaml new file mode 100644 index 00000000..06299226 --- /dev/null +++ b/rules/audit/audit_acls_folders_configure.yaml @@ -0,0 +1,39 @@ +id: audit_acls_folders_configure +title: "Configure Audit Log Folder to Not Contain Access Control Lists (ACLs)" +discussion: | + The audit service must be configured to create log folders with the correct permissions to prevent normal users from reading audit logs. Audit logs contain sensitive data about the system and users. If log folders are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + The audit log folder must not contain ACLs. +check: | + /bin/ls -lde $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') | /usr/bin/awk '{print $1}' | /usr/bin/grep -c ":" +result: + integer: 0 +fix: | + [source,bash] + ---- + /bin/chmod -N $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') + ---- +references: + cce: + - CCE-84704-6 + cci: + - CCI-000162 + - CCI-001314 + 800-53r4: + - AU-9 + - SI-11(b) + srg: + - SRG-OS-000057-GPOS-00027 + - SRG-OS-000206-GPOS-00084 + disa_stig: + - AOSX-14-000030 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_acls_folders_mode_configure.yaml b/rules/audit/audit_acls_folders_mode_configure.yaml new file mode 100644 index 00000000..3ea46cfa --- /dev/null +++ b/rules/audit/audit_acls_folders_mode_configure.yaml @@ -0,0 +1,39 @@ +id: audit_acls_folders_mode_configure +title: "Configure Audit Log Folders to Mode 700 or Less Permissive" +discussion: | + The audit service must be configured to create log folders with the correct permissions to prevent normal users from reading audit logs. Audit logs contain sensitive data about the system and users. If log folders are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + The audit log folder must only allow read, write, and execute by Root. +check: | + /usr/bin/stat -f %A $(/usr/bin/grep '^dir' /etc/security/audit_control | awk -F: '{print $2}') +result: + integer: 700 +fix: | + [source,bash] + ---- + /bin/chmod 700 $(/usr/bin/grep '^dir' /etc/security/audit_control | awk -F: '{print $2}') + ---- +references: + cce: + - CCE-84705-3 + cci: + - CCI-000162 + - CCI-000163 + - CCI-000164 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000058-GPOS-00028 + - SRG-OS-000059-GPOS-00029 + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001017 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: \ No newline at end of file diff --git a/rules/audit/audit_auditd_enabled.yaml b/rules/audit/audit_auditd_enabled.yaml new file mode 100644 index 00000000..6b258007 --- /dev/null +++ b/rules/audit/audit_auditd_enabled.yaml @@ -0,0 +1,75 @@ +id: audit_auditd_enabled +title: "Enable Security Auditing (auditd)" +discussion: | + Without establishing what type of events occurred, when they occurred, and by whom it would be difficult to establish, correlate, and investigate the events leading up to an outage or attack. + + Audit record content that may be necessary to satisfy this requirement includes, for example, time stamps, source and destination addresses, user/process identifiers, event descriptions, success/fail indications, filenames involved, and access control or flow control rules invoked. + + Associating event types with detected events in the operating system audit logs provides a means of investigating an attack, recognizing resource utilization or capacity thresholds, or identifying an improperly configured operating system. + + The information system initiates session audits at system start-up. +check: | + /bin/launchctl list | /usr/bin/grep -c com.apple.auditd +result: + integer: 1 +fix: | + To enable the audit service, run the following command: + + [source,bash] + ---- + /bin/launchctl load -w /System/Library/LaunchDaemons/com.apple.auditd.plist + ---- +references: + cce: + - CCE-84706-1 + cci: + - CCI-000130 + - CCI-000131 + - CCI-000132 + - CCI-000133 + - CCI-000134 + - CCI-000135 + - CCI-000159 + - CCI-001464 + - CCI-001487 + - CCI-001889 + - CCI-001890 + - CCI-001914 + - CCI-002130 + 800-53r4: + - AU-3 + - AU-3(1) + - AU-8 + - AU-8(a) + - AU-8(b) + - AU-12 + - AU-12(3) + - AU-14(1) + srg: + - SRG-OS-000037-GPOS-00015 + - SRG-OS-000038-GPOS-00016 + - SRG-OS-000039-GPOS-00017 + - SRG-OS-000040-GPOS-00018 + - SRG-OS-000041-GPOS-00019 + - SRG-OS-000042-GPOS-00020 + - SRG-OS-000042-GPOS-00021 + - SRG-OS-000055-GPOS-00026 + - SRG-OS-000254-GPOS-00095 + - SRG-OS-000255-GPOS-00096 + - SRG-OS-000303-GPOS-00120 + - SRG-OS-000337-GPOS-00129 + - SRG-OS-000358-GPOS-00145 + - SRG-OS-000359-GPOS-00146 + disa_stig: + - AOSX-14-001003 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_configure_capacity_notify.yaml b/rules/audit/audit_configure_capacity_notify.yaml new file mode 100644 index 00000000..7838ea4b --- /dev/null +++ b/rules/audit/audit_configure_capacity_notify.yaml @@ -0,0 +1,32 @@ +id: audit_configure_capacity_notify +title: "Configure Audit Capacity Warning" +discussion: | + The audit service must be configured to require a minimum percentage of free disk space in order to run. This ensures that audit will notify the administrator that action is required to free up more disk space for audit logs. +check: | + /usr/bin/grep -c "^minfree:25" /etc/security/audit_control +result: + integer: 1 +fix: | + Edit the "/etc/security/audit_control" file and change the value for "minfree" to "25" using the following command: + [source,bash] + ---- + /usr/bin/sed -i.bak 's/.*minfree.*/minfree:25/' /etc/security/audit_control; /usr/sbin/audit -s + ---- +references: + cce: + - CCE-84707-9 + cci: + - CCI-001855 + 800-53r4: + - AU-5(1) + srg: + - SRG-OS-000343-GPOS-00134 + disa_stig: + - AOSX-14-001030 +macOS: + - "10.15" +tags: + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_failure_halt.yaml b/rules/audit/audit_failure_halt.yaml new file mode 100644 index 00000000..b90b75f7 --- /dev/null +++ b/rules/audit/audit_failure_halt.yaml @@ -0,0 +1,35 @@ +id: audit_failure_halt +title: "Configure System to Shut Down Upon Audit Failure" +discussion: | + The audit service should shut down the computer if it is unable to audit system events. Once audit failure occurs, user and system activity is no longer recorded and malicious activity could go undetected. Audit processing failures include software/hardware errors, failures in the audit capturing mechanisms, and audit storage capacity being reached or exceeded. Responses to audit failure depend on the nature of the failure mode. +check: | + /usr/bin/grep -Ec "^policy.*ahlt" /etc/security/audit_control +result: + integer: 1 +fix: | + Edit the "/etc/security/audit_control file" and change the value for policy to include the setting "ahlt". + [source,bash] + ---- + /usr/bin/sed -i.bak '/^policy/ s/$/,ahlt/' /etc/security/audit_control; /usr/sbin/audit -s + ---- +references: + cce: + - CCE-84708-7 + cci: + - CCI-000140 + 800-53r4: + - AU-5(b) + srg: + - SRG-OS-000047-GPOS-00023 + disa_stig: + - AOSX-14-001010 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_files_group_configure.yaml b/rules/audit/audit_files_group_configure.yaml new file mode 100644 index 00000000..dcba506a --- /dev/null +++ b/rules/audit/audit_files_group_configure.yaml @@ -0,0 +1,36 @@ +id: audit_files_group_configure +title: "Configure Audit Log Files Group to Wheel" +discussion: | + The audit service must be configured to create log files with the correct group ownership to prevent normal users from reading audit logs. Audit logs contain sensitive data about the system and users. If log files are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + Audit log files must have the group set to Wheel. +check: | + /bin/ls -n $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') | /usr/bin/awk '{s+=$4} END {print s}' +result: + integer: 0 +fix: | + [source,bash] + ---- + /usr/bin/chgrp -R wheel $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') + ---- +references: + cce: + - CCE-84709-5 + cci: + - CCI-000162 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001014 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_files_owner_configure.yaml b/rules/audit/audit_files_owner_configure.yaml new file mode 100644 index 00000000..4e49776f --- /dev/null +++ b/rules/audit/audit_files_owner_configure.yaml @@ -0,0 +1,36 @@ +id: audit_files_owner_configure +title: "Configure Audit Log Files to be Owned by Root" +discussion: | + The audit service must be configured to create log files with the correct ownership to prevent normal users from reading audit logs. Audit logs contain sensitive data about the system and users. If log files are set to only be readable and writable by root or administrative users with sudo, the risk is mitigated. + + Audit log files must be owned by root. +check: | + /bin/ls -n $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') | /usr/bin/awk '{s+=$3} END {print s}' +result: + integer: 0 +fix: | + [source,bash] + ---- + /usr/sbin/chown -R root $(/usr/bin/grep '^dir' /etc/security/audit_control | /usr/bin/awk -F: '{print $2}') + ---- +references: + cce: + - CCE-84710-3 + cci: + - CCI-000162 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001012 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_flags_aa_configure.yaml b/rules/audit/audit_flags_aa_configure.yaml new file mode 100644 index 00000000..5deec440 --- /dev/null +++ b/rules/audit/audit_flags_aa_configure.yaml @@ -0,0 +1,37 @@ +id: audit_flags_aa_configure +title: 'Add "aa" Flag to audit_control Configuration' +discussion: | + Without generating audit records that are specific to the security and mission needs of the organization, it would be difficult to establish, correlate, and investigate the events relating to an incident or identify those responsible for one. Audit records can be generated from various components within the information system (e.g., module or policy filter). +check: | + /usr/bin/grep -Ec "^flags.*aa" /etc/security/audit_control +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak '/^flags/ s/$/,aa/' /etc/security/audit_control; /usr/sbin/audit -s + ---- +references: + cci: + - N/A + cce: + - CCE-84711-1 + 800-53r4: + - AU-12(c) + srg: + - SRG-OS-000470-GPOS-00214 + - SRG-OS-000472-GPOS-00217 + - SRG-OS-000473-GPOS-00218 + - SRG-OS-000475-GPOS-00220 + disa_stig: + - AOSX-14-001044 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_flags_ad_configure.yaml b/rules/audit/audit_flags_ad_configure.yaml new file mode 100644 index 00000000..93ea4dd6 --- /dev/null +++ b/rules/audit/audit_flags_ad_configure.yaml @@ -0,0 +1,59 @@ +id: audit_flags_ad_configure +title: 'Add "ad" Flag to audit_control Configuration' +discussion: | + Without generating audit records that are specific to the security and mission needs of the organization, it would be difficult to establish, correlate, and investigate the events relating to an incident or identify those responsible for one. Audit records can be generated from various components within the information system (e.g., module or policy filter). + + The information system audits the execution of privileged functions. +check: | + /usr/bin/grep -Ec "^flags.*ad" /etc/security/audit_control +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak '/^flags/ s/$/,ad/' /etc/security/audit_control; /usr/sbin/audit -s + ---- +references: + cce: + - CCE-84712-9 + cci: + - CCI-000018 + - CCI-000172 + - CCI-001403 + - CCI-001404 + - CCI-001405 + - CCI-002234 + - CCI-002884 + 800-53r4: + - AC-2(4) + - AC-6(9) + - AU-12(c) + - MA-4(1)(a) + srg: + - SRG-OS-000004-GPOS-00004 + - SRG-OS-000239-GPOS-00089 + - SRG-OS-000240-GPOS-00090 + - SRG-OS-000241-GPOS-00091 + - SRG-OS-000327-GPOS-00127 + - SRG-OS-000392-GPOS-00172 + - SRG-OS-000471-GPOS-00215 + - SRG-OS-000471-GPOS-00216 + - SRG-OS-000476-GPOS-00221 + - SRG-OS-000477-GPOS-00222 + - SRG-OS-000304-GPOS-00121 + - SRG-OS-000277-GPOS-00107 + - SRG-OS-000275-GPOS-00105 + - SRG-OS-000276-GPOS-00106 + - SRG-OS-000274-GPOS-00104 + disa_stig: + - AOSX-14-001001 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_flags_failed_file_read_restriction_enforced.yaml b/rules/audit/audit_flags_failed_file_read_restriction_enforced.yaml new file mode 100644 index 00000000..4ed78872 --- /dev/null +++ b/rules/audit/audit_flags_failed_file_read_restriction_enforced.yaml @@ -0,0 +1,48 @@ +id: audit_flags_failed_file_read_restriction_enforced +title: "Configure System to Audit All Failed Read Actions on the System" +discussion: | + By auditing access restriction enforcement, changes to application and OS configuration files can be audited. Without auditing the enforcement of access restrictions, it will be difficult to identify attempted attacks and an audit trail will not be available for forensic investigation. + + Enforcement actions are the methods or mechanisms used to prevent unauthorized changes to configuration settings. Enforcement action methods may be as simple as denying access to a file based on the application of file permissions (access restriction). Audit items may consist of lists of actions blocked by access restrictions or changes identified after the fact. +check: | + /usr/bin/grep -Ec "^flags.*-fr" /etc/security/audit_control +result: + integer: 1 +fix: | + To set the file read failed audit flag to the recommended setting, run the following command to add the flag "-fr". + [source,bash] + ---- + /usr/bin/sed -i.bak '/^flags/ s/$/,-fr/' /etc/security/audit_control;/usr/sbin/audit -s + ---- +references: + cce: + - CCE-84713-7 + cci: + - CCI-000162 + 800-53r4: + - AU-12(c) + - AU-9 + - CM-5(1) + srg: + - SRG-OS-000365-GPOS-00152 + - SRG-OS-000458-GPOS-00203 + - SRG-OS-000461-GPOS-00205 + - SRG-OS-000463-GPOS-00207 + - SRG-OS-000465-GPOS-00209 + - SRG-OS-000466-GPOS-00210 + - SRG-OS-000467-GPOS-00211 + - SRG-OS-000468-GPOS-00212 + - SRG-OS-000474-GPOS-00219 + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001016 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_flags_failed_file_write_access_restriction_enforced.yaml b/rules/audit/audit_flags_failed_file_write_access_restriction_enforced.yaml new file mode 100644 index 00000000..21a14246 --- /dev/null +++ b/rules/audit/audit_flags_failed_file_write_access_restriction_enforced.yaml @@ -0,0 +1,48 @@ +id: audit_flags_failed_file_write_access_restriction_enforced +title: "Configure System to Audit All Failed Write Actions on the System" +discussion: | + By auditing access restriction enforcement, changes to application and OS configuration files can be audited. Without auditing the enforcement of access restrictions, it will be difficult to identify attempted attacks and an audit trail will not be available for forensic investigation. + + Enforcement actions are the methods or mechanisms used to prevent unauthorized changes to configuration settings. Enforcement action methods may be as simple as denying access to a file based on the application of file permissions (access restriction). Audit items may consist of lists of actions blocked by access restrictions or changes identified after the fact. +check: | + /usr/bin/grep -Ec "^flags.*-fw" /etc/security/audit_control +result: + integer: 1 +fix: | + To set the file read failed audit flag to the recommended setting, run the following command to add the flag "-fw". + [source,bash] + ---- + /usr/bin/sed -i.bak '/^flags/ s/$/,-fw/' /etc/security/audit_control;/usr/sbin/audit -s + ---- +references: + cce: + - CCE-84714-5 + cci: + - CCI-000162 + 800-53r4: + - AU-12(c) + - AU-9 + - CM-5(1) + srg: + - SRG-OS-000365-GPOS-00152 + - SRG-OS-000458-GPOS-00203 + - SRG-OS-000461-GPOS-00205 + - SRG-OS-000463-GPOS-00207 + - SRG-OS-000465-GPOS-00209 + - SRG-OS-000466-GPOS-00210 + - SRG-OS-000467-GPOS-00211 + - SRG-OS-000468-GPOS-00212 + - SRG-OS-000474-GPOS-00219 + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001016 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_flags_file_attr_mod_access_restriction_enforced.yaml b/rules/audit/audit_flags_file_attr_mod_access_restriction_enforced.yaml new file mode 100644 index 00000000..00a45709 --- /dev/null +++ b/rules/audit/audit_flags_file_attr_mod_access_restriction_enforced.yaml @@ -0,0 +1,48 @@ +id: audit_flags_file_attr_mod_access_restriction_enforced +title: "Configure System to Audit All Change of Object Attributes" +discussion: | + By auditing access restriction enforcement, changes to application and OS configuration files can be audited. Without auditing the enforcement of access restrictions, it will be difficult to identify attempted attacks and an audit trail will not be available for forensic investigation. + + Enforcement actions are the methods or mechanisms used to prevent unauthorized changes to configuration settings. Enforcement action methods may be as simple as denying access to a file based on the application of file permissions (access restriction). Audit items may consist of lists of actions blocked by access restrictions or changes identified after the fact. +check: | + /usr/bin/grep -Ec "^flags.*fm" /etc/security/audit_control +result: + integer: 1 +fix: | + To set the file read failed audit flag to the recommended setting, run the following command to add the flag "fm". + [source,bash] + ---- + /usr/bin/sed -i.bak '/^flags/ s/$/,fm/' /etc/security/audit_control;/usr/sbin/audit -s + ---- +references: + cce: + - CCE-84715-2 + cci: + - CCI-000162 + 800-53r4: + - AU-12(c) + - AU-9 + - CM-5(1) + srg: + - SRG-OS-000365-GPOS-00152 + - SRG-OS-000458-GPOS-00203 + - SRG-OS-000461-GPOS-00205 + - SRG-OS-000463-GPOS-00207 + - SRG-OS-000465-GPOS-00209 + - SRG-OS-000466-GPOS-00210 + - SRG-OS-000467-GPOS-00211 + - SRG-OS-000468-GPOS-00212 + - SRG-OS-000474-GPOS-00219 + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001016 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_flags_lo_configure.yaml b/rules/audit/audit_flags_lo_configure.yaml new file mode 100644 index 00000000..2e291323 --- /dev/null +++ b/rules/audit/audit_flags_lo_configure.yaml @@ -0,0 +1,40 @@ +id: audit_flags_lo_configure +title: 'Add "lo" Flag to audit_control Configuration' +discussion: | + Frequently, an attacker that successfully gains access to a system has only gained access to an account with limited privileges, such as a guest account or a service account. The attacker must attempt to change to another user account with normal or elevated privileges in order to proceed. Auditing successful and unsuccessful attempts to switch to another user account and the escalation of privileges mitigates this risk. + + The information system monitors and login and logout events. +check: | + /usr/bin/grep -Ec "^flags*.lo" /etc/security/audit_control +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak '/^flags/ s/$/,lo/' /etc/security/audit_control; /usr/sbin/audit -s + ---- +references: + cce: + - CCE-84716-0 + cci: + - CCI-000067 + - CCI-000172 + 800-53r4: + - AC-17(1) + - AU-12(c) + srg: + - SRG-OS-000032-GPOS-00013 + - SRG-OS-000064-GPOS-00033 + - SRG-OS-000462-GPOS-00206 + disa_stig: + - AOSX-14-001002 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_folder_group_configure.yaml b/rules/audit/audit_folder_group_configure.yaml new file mode 100644 index 00000000..91ede77a --- /dev/null +++ b/rules/audit/audit_folder_group_configure.yaml @@ -0,0 +1,35 @@ +id: audit_folder_group_configure +title: "Configure Audit Log Folders Group to Wheel" +discussion: | + The audit service must be configured to create log files with the correct group ownership to prevent normal users from reading audit logs. Audit logs contain sensitive data about the system and about users. If log files are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + The audit log folder must have the group set to Wheel. +check: | + /bin/ls -dn $(/usr/bin/grep '^dir' /etc/security/audit_control | awk -F: '{print $2}') | awk '{print $4}' +result: + integer: 0 +fix: | + ---- + /usr/sbin/chgrp wheel $(/usr/bin/awk -F : '/^dir/{print $2}' /etc/security/audit_control) + ---- +references: + cce: + - CCE-84717-8 + cci: + - CCI-000162 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001015 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_folder_owner_configure.yaml b/rules/audit/audit_folder_owner_configure.yaml new file mode 100644 index 00000000..07cc27af --- /dev/null +++ b/rules/audit/audit_folder_owner_configure.yaml @@ -0,0 +1,35 @@ +id: audit_folder_owner_configure +title: "Configure Audit Log Folders to be Owned by Root" +discussion: | + The audit service must be configured to create log files with the correct ownership to prevent normal users from reading audit logs. Audit logs contain sensitive data about the system and about users. If log files are set to be readable and writable only by root or administrative users with sudo, the risk is mitigated. + + The audit log folder must be owned by Root. +check: | + /bin/ls -dn $(/usr/bin/grep '^dir' /etc/security/audit_control | awk -F: '{print $2}') | awk '{print $3}' +result: + integer: 0 +fix: | + ---- + /usr/sbin/chown root $(/usr/bin/awk -F : '/^dir/{print $2}' /etc/security/audit_control) + ---- +references: + cce: + - CCE-84718-6 + cci: + - CCI-000162 + 800-53r4: + - AU-9 + srg: + - SRG-OS-000057-GPOS-00027 + disa_stig: + - AOSX-14-001013 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_retention_one_week_configure.yaml b/rules/audit/audit_retention_one_week_configure.yaml new file mode 100644 index 00000000..9d3c9903 --- /dev/null +++ b/rules/audit/audit_retention_one_week_configure.yaml @@ -0,0 +1,34 @@ +id: audit_retention_one_week_configure +title: "Configure Audit Retention to a Minimum of 7 Days" +discussion: | + The audit service must be configured to require that records are kept for seven days or longer before deletion when there is no central audit record storage facility. When "expire-after" is set to "7d", the audit service will not delete audit logs until the log data is at least seven days old. +check: | + /usr/bin/awk -F: '/expire-after/{print $2}' /etc/security/audit_control +result: + string: 7d +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/^expire-after.*/expire-after:7d/' /etc/security/audit_control; /usr/sbin/audit -s + ---- +references: + cce: + - CCE-84719-4 + cci: + - CCI-001849 + 800-53r4: + - AU-4 + srg: + - SRG-OS-000341-GPOS-00132 + disa_stig: + - AOSX-14-001029 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/audit/audit_settings_failure_notify.yaml b/rules/audit/audit_settings_failure_notify.yaml new file mode 100644 index 00000000..dbc6c0dd --- /dev/null +++ b/rules/audit/audit_settings_failure_notify.yaml @@ -0,0 +1,32 @@ +id: audit_settings_failure_notify +title: "Configure Audit Failure Notification" +discussion: | + The audit service should be configured to immediately print messages to the console or email administrator users when an auditing failure occurs. It is critical for the appropriate personnel to be aware if a system is at risk of failing to process audit logs as required. Without a real-time alert, security personnel may be unaware of an impending failure of the audit capability and system operation may be adversely affected. + + If the argument "-s" is missing, or if "audit_warn" has not been otherwise modified to print errors to the console or send email alerts to the SA and ISSO, this is a finding. +check: | + /usr/bin/grep -c "logger -s -p" /etc/security/audit_warn +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/logger -p/logger -s -p/' /etc/security/audit_warn; /usr/sbin/audit -s + ---- +references: + cce: + - CCE-84720-2 + cci: + - CCI-001858 + 800-53r4: + - AU-5(2) + srg: + - SRG-OS-000344-GPOS-00135 + disa_stig: + - AOSX-14-001031 +macOS: + - "10.15" +tags: + - fisma-high + - STIG +mobileconfig: \ No newline at end of file diff --git a/rules/auth/auth_pam_login_smartcard_enforce.yaml b/rules/auth/auth_pam_login_smartcard_enforce.yaml new file mode 100644 index 00000000..945f5e9a --- /dev/null +++ b/rules/auth/auth_pam_login_smartcard_enforce.yaml @@ -0,0 +1,60 @@ +id: auth_pam_login_smartcard_enforce +title: "Enforce Multifactor Authentication for Login" +discussion: | + Privileged users must utilize multifactor authentication to prevent potential misuse and compromise of the system. + + Ensure that the login process enforces mutlifactor authentication. + + NOTE: /etc/pam.d/login will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -Ec '^(auth\s+sufficient\s+pam_smartcard.so|auth\s+required\s+pam_deny.so)' /etc/pam.d/login +result: + integer: 2 +fix: | + [source,bash] + ---- + /bin/cat > /etc/pam.d/login << LOGIN_END + # login: auth account password session + auth sufficient pam_smartcard.so + auth optional pam_krb5.so use_kcminit + auth optional pam_ntlm.so try_first_pass + auth optional pam_mount.so try_first_pass + auth required pam_opendirectory.so try_first_pass + auth required pam_deny.so + account required pam_nologin.so + account required pam_opendirectory.so + password required pam_opendirectory.so + session required pam_launchd.so + session required pam_uwtmp.so + session optional pam_mount.so + LOGIN_END + + + /bin/chmod 644 /etc/pam.d/login + /usr/sbin/chown root:wheel /etc/pam.d/login + ---- +references: + cce: + - CCE-84721-0 + cci: + - CCI-000366 + 800-53r4: + - IA-2(3) + - CM-6(b) + srg: + - SRG-OS-000107-GPOS-00054 + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-003050 + - AOSX-14-003051 + - AOSX-14-003052 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: diff --git a/rules/auth/auth_pam_su_smartcard_enforce.yaml b/rules/auth/auth_pam_su_smartcard_enforce.yaml new file mode 100644 index 00000000..dc104a54 --- /dev/null +++ b/rules/auth/auth_pam_su_smartcard_enforce.yaml @@ -0,0 +1,55 @@ +id: auth_pam_su_smartcard_enforce +title: "Enforce Multifactor Authentication for Privilege Escalation for the su process" +discussion: | + To assure accountability and prevent unauthenticated access, privileged users must utilize multifactor authentication to prevent potential misuse and compromise of the system. + + Ensure that use of su to elevate privilege enforces mutlifactor authentication. + + NOTE: /etc/pam.d/su will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -Ec '^(auth\s+sufficient\s+pam_smartcard.so|auth\s+required\s+pam_rootok.so)' /etc/pam.d/su +result: + integer: 2 +fix: | + [source,bash] + ---- + /bin/cat > /etc/pam.d/su << SU_END + # su: auth account password session + auth sufficient pam_smartcard.so + auth required pam_rootok.so + auth required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe + account required pam_permit.so + account required pam_opendirectory.so no_check_shell + password required pam_opendirectory.so + session required pam_launchd.so + SU_END + + # Fix new file ownership and permissions + /bin/chmod 644 /etc/pam.d/su + /usr/sbin/chown root:wheel /etc/pam.d/su + ---- +references: + cce: + - CCE-84722-8 + cci: + - CCI-000366 + 800-53r4: + - IA-2(3) + - CM-6(b) + srg: + - SRG-OS-000107-GPOS-00054 + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-003050 + - AOSX-14-003051 + - AOSX-14-003052 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: diff --git a/rules/auth/auth_pam_sudo_smartcard_enforce.yaml b/rules/auth/auth_pam_sudo_smartcard_enforce.yaml new file mode 100644 index 00000000..25b33c72 --- /dev/null +++ b/rules/auth/auth_pam_sudo_smartcard_enforce.yaml @@ -0,0 +1,54 @@ +id: auth_pam_sudo_smartcard_enforce +title: "Enforce Multifactor Authentication for Priveledge Escalation through the sudo process" +discussion: | + To assure accountability and prevent unauthenticated access, privileged users must utilize multifactor authentication to prevent potential misuse and compromise of the system. + + Ensure that use of sudo to elevate privilege enforces mutlifactor authentication. + + NOTE: /etc/pam.d/sudo will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -Ec '^(auth\s+sufficient\s+pam_smartcard.so|auth\s+required\s+pam_deny.so)' /etc/pam.d/sudo +result: + integer: 2 +fix: | + [source,bash] + ---- + + /bin/cat > /etc/pam.d/sudo << SUDO_END + # sudo: auth account password session + auth sufficient pam_smartcard.so + auth required pam_opendirectory.so + auth required pam_deny.so + account required pam_permit.so + password required pam_deny.so + session required pam_permit.so + SUDO_END + + /bin/chmod 444 /etc/pam.d/sudo + /usr/sbin/chown root:wheel /etc/pam.d/sudo + ---- +references: + cce: + - CCE-84723-6 + cci: + - CCI-000366 + 800-53r4: + - IA-2(3) + - CM-6(b) + srg: + - SRG-OS-000107-GPOS-00054 + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-003050 + - AOSX-14-003051 + - AOSX-14-003052 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: diff --git a/rules/auth/auth_smartcard_allow.yaml b/rules/auth/auth_smartcard_allow.yaml new file mode 100644 index 00000000..401ddd4d --- /dev/null +++ b/rules/auth/auth_smartcard_allow.yaml @@ -0,0 +1,34 @@ +id: auth_smartcard_allow +title: "Allow Smartcard Authentication" +discussion: | + The use of smartcard credentials facilitates standardization and reduces the risk of unauthorized access. + + When enabled the smartcard can be used for login, authorization, and screen saver unlocking. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowSmartCard = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84724-4 + cci: + - N/A + 800-53r4: + - IA-2(12) + srg: + - SRG-OS-000376-GPOS-00161 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.security.smartcard: + allowSmartCard: true diff --git a/rules/auth/auth_smartcard_certificate_trust_enforce_high.yaml b/rules/auth/auth_smartcard_certificate_trust_enforce_high.yaml new file mode 100644 index 00000000..ac938a69 --- /dev/null +++ b/rules/auth/auth_smartcard_certificate_trust_enforce_high.yaml @@ -0,0 +1,36 @@ +id: auth_smartcard_certificate_trust_enforce_high +title: "Set Smartcard Certificate Trust to High" +discussion: | + The macOS system must be configured to not allow access to users who are no longer authorized (users with revoked certificates). To prevent the use of untrusted certificates, the certificates on a smartcard card must meet the following criteria: its issuer has a system-trusted certificate, the certificate is not expired, its "valid-after" date is in the past, and it passes CRL and OCSP checking. + + This is a hard revocation, a network connection is required. A verified positive response from the OSCP/CRL server is required for authentication to succeed. + + NOTE: Before applying this setting, please see the smartcard supplemental guidance. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/awk '/checkCertificateTrust/{print substr($3, 1, length($3)-1)}' +result: + intger: 3 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84725-1 + cci: + - CCI-000186 + 800-53r4: + - IA-2(12) + - IA-5(2) + - IA-5(2)(d) + srg: + - SRG-OS-000067-GPOS-00035 + disa_stig: + - AOSX-14-003002 +macOS: + - "10.15" +tags: + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.security.smartcard: + checkCertificateTrust: 3 diff --git a/rules/auth/auth_smartcard_certificate_trust_enforce_moderate.yaml b/rules/auth/auth_smartcard_certificate_trust_enforce_moderate.yaml new file mode 100644 index 00000000..b0598437 --- /dev/null +++ b/rules/auth/auth_smartcard_certificate_trust_enforce_moderate.yaml @@ -0,0 +1,36 @@ +id: auth_smartcard_certificate_trust_enforce_moderate +title: "Set Smartcard Certificate Trust to Moderate" +discussion: | + The macOS system must be configured to not allow access to users who are no longer authorized (users with revoked certificates). To prevent the use of untrusted certificates, the certificates on a smartcard card must meet the following criteria: its issuer has a system-trusted certificate, the certificate is not expired, its "valid-after" date is in the past, and it passes CRL and OCSP checking. + + This is a soft revocation. If the OCSP/CRL server is unreachable, authentication will still succeed. + + NOTE: Before applying this setting, please see the smartcard supplemental guidance. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/awk '/checkCertificateTrust/{print substr($3, 1, length($3)-1)}' +result: + integer: 2 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84726-9 + cci: + - CCI-000186 + 800-53r4: + - IA-2(12) + - IA-5(2) + - IA-5(2)(d) + srg: + - SRG-OS-000067-GPOS-00035 + disa_stig: + - AOSX-14-003002 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate +mobileconfig: true +mobileconfig_info: + com.apple.security.smartcard: + checkCertificateTrust: 2 diff --git a/rules/auth/auth_smartcard_enforce.yaml b/rules/auth/auth_smartcard_enforce.yaml new file mode 100644 index 00000000..7834c90f --- /dev/null +++ b/rules/auth/auth_smartcard_enforce.yaml @@ -0,0 +1,61 @@ +id: auth_smartcard_enforce +title: "Enforce Smartcard Authentication" +discussion: | + The use of smartcard credentials facilitates standardization and reduces the risk of unauthorized access. + + When enforceSmartCard is set to true the smartcard must be used for login, authorization, and screen saver unlocking. + + CAUTION: enforceSmartCard will apply to the whole system. No users will be able to login with their password unless the profile is removed or a member of the NotEnforced group. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'enforceSmartCard = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84727-7 + cci: + - CCI-000187 + - CCI-000765 + - CCI-000766 + - CCI-000767 + - CCI-000768 + - CCI-000877 + - CCI-001948 + 800-53r4: + - IA-2 + - IA-2(1) + - IA-2(2) + - IA-2(3) + - IA-2(4) + - IA-2(6) + - IA-2(11) + - IA-5(2)(b) + - IA-5(2)(c) + - MA-4(c) + srg: + - SRG-OS-000068-GPOS-00036 + - SRG-OS-000105-GPOS-00052 + - SRG-OS-000106-GPOS-00053 + - SRG-OS-000107-GPOS-00054 + - SRG-OS-000108-GPOS-00055 + - SRG-OS-000125-GPOS-00065 + - SRG-OS-000375-GPOS-00160 + disa_stig: + - AOSX-14-003020 + - AOSX-14-003024 + - AOSX-14-003005 + - AOSX-14-003025 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.security.smartcard: + enforceSmartCard: true diff --git a/rules/auth/auth_ssh_smartcard_enforce.yaml b/rules/auth/auth_ssh_smartcard_enforce.yaml new file mode 100644 index 00000000..1b62a1c8 --- /dev/null +++ b/rules/auth/auth_ssh_smartcard_enforce.yaml @@ -0,0 +1,65 @@ +id: auth_ssh_smartcard_enforce +title: "Enforce Smartcard Authentication for SSH" +discussion: | + To ensure accountability and prevent unauthorized access, users must utilize multifactor authentication. + + Enforce Smartcard Authentication for user login via SSH. + + NOTE: Before applying this setting, please see the smartcard supplemental guidance. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -Ec '^(PasswordAuthentication\s+no|ChallengeResponseAuthentication\s+no)' /etc/ssh/sshd_config +result: + integer: 2 +fix: | + The following commands must be run to disable passcode based authentication for SSHD: + [source,bash] + ---- + /usr/bin/sed -i.bak_$(date "+%Y-%m-%d_%H:%M") "s|#PasswordAuthentication yes|PasswordAuthentication no|; s|#ChallengeResponseAuthentication yes|ChallengeResponseAuthentication no|" /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84729-3 + cci: + - CCI-000187 + - CCI-000765 + - CCI-000766 + - CCI-000767 + - CCI-000768 + - CCI-000877 + - CCI-001948 + 800-53r4: + - IA-2 + - IA-2(1) + - IA-2(2) + - IA-2(3) + - IA-2(4) + - IA-2(6) + - IA-2(11) + - IA-5(2)(b) + - IA-5(2)(c) + - MA-4(c) + srg: + - SRG-OS-000068-GPOS-00036 + - SRG-OS-000105-GPOS-00052 + - SRG-OS-000106-GPOS-00053 + - SRG-OS-000107-GPOS-00054 + - SRG-OS-000108-GPOS-00055 + - SRG-OS-000125-GPOS-00065 + - SRG-OS-000375-GPOS-00160 + disa_stig: + - AOSX-14-003020 + - AOSX-14-003024 + - AOSX-14-003005 + - AOSX-14-003025 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: diff --git a/rules/icloud/icloud_addressbook_disable.yaml b/rules/icloud/icloud_addressbook_disable.yaml new file mode 100644 index 00000000..ad2a6191 --- /dev/null +++ b/rules/icloud/icloud_addressbook_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_addressbook_disable +title: "Disable iCloud Address Book" +discussion: | + The macOS built-in Contacts.app connection to Apple's iCloud service, which is not a organizationally approved cloud, must be disabled. Automated contact synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudAddressBook = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84730-1 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002014 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudAddressBook: false diff --git a/rules/icloud/icloud_appleid_prefpane_disable.yaml b/rules/icloud/icloud_appleid_prefpane_disable.yaml new file mode 100644 index 00000000..fae43e35 --- /dev/null +++ b/rules/icloud/icloud_appleid_prefpane_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_appleid_prefpane_disable +title: "Disable the system preference pane for Apple ID" +discussion: | + The system preference panel for Apple ID must be disabled as it is not an organizationally approved cloud service. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'com.apple.preferences.AppleID' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84731-9 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(5)(b) + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002018 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.systempreferences: + DisabledPreferencePanes: + - com.apple.preferences.AppleIDPrefPane diff --git a/rules/icloud/icloud_bookmarks_disable.yaml b/rules/icloud/icloud_bookmarks_disable.yaml new file mode 100644 index 00000000..0d309072 --- /dev/null +++ b/rules/icloud/icloud_bookmarks_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_bookmarks_disable +title: "Disable iCloud Bookmarks" +discussion: | + The macOS built-in Safari.app bookmark synchronization via the iCloud service must be disabled as it is not an organizationally approved cloud service. Automated bookmark synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudBookmarks = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84732-7 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002042 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudBookmarks: false diff --git a/rules/icloud/icloud_calendar_disable.yaml b/rules/icloud/icloud_calendar_disable.yaml new file mode 100644 index 00000000..fcf3d108 --- /dev/null +++ b/rules/icloud/icloud_calendar_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_calendar_disable +title: "Disable the iCloud Calendar services" +discussion: | + The macOS built-in Calendar.app connection to Apple's iCloud service, which is not a organizationally approved cloud, must be disabled. Automated calendar synchronization shall be planned and controlled to approved storage. +check: + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudCalendar = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84733-5 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002012 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudCalendar: false diff --git a/rules/icloud/icloud_drive_disable.yaml b/rules/icloud/icloud_drive_disable.yaml new file mode 100644 index 00000000..05fbdd7d --- /dev/null +++ b/rules/icloud/icloud_drive_disable.yaml @@ -0,0 +1,37 @@ +id: icloud_drive_disable +title: "Disable iCloud Document Sync" +discussion: | + The macOS built-in iCloud document synchronization service must disabled to prevent organizational data from being synchronized to personal or non-approved storage. Automated synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudDocumentSync = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84734-3 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002041 + - AOSX-14-002049 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudDocumentSync: false diff --git a/rules/icloud/icloud_keychain_disable.yaml b/rules/icloud/icloud_keychain_disable.yaml new file mode 100644 index 00000000..43ed1648 --- /dev/null +++ b/rules/icloud/icloud_keychain_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_keychain_disable +title: "Disable iCloud Keychain Sync" +discussion: | + The macOS system's ability to automatically synchronize a user's passwords to their iCloud account must be disabled. Password management and synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudKeychainSync = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84735-0 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002040 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudKeychainSync: false diff --git a/rules/icloud/icloud_mail_disable.yaml b/rules/icloud/icloud_mail_disable.yaml new file mode 100644 index 00000000..1e567ae6 --- /dev/null +++ b/rules/icloud/icloud_mail_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_mail_disable +title: "Disable iCloud Mail" +discussion: | + The macOS built-in Mail.app connection to Apple's iCloud service must be disabled as it is not an organizationally approved service. Automated Mail synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudMail = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84736-8 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002015 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudMail: false diff --git a/rules/icloud/icloud_notes_disable.yaml b/rules/icloud/icloud_notes_disable.yaml new file mode 100644 index 00000000..87ab3903 --- /dev/null +++ b/rules/icloud/icloud_notes_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_notes_disable +title: "Disable iCloud Notes" +discussion: | + The macOS built-in Notes.app connection to Apple's iCloud service must be disabled. Automated Note synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudNotes = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84737-6 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002016 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudNotes: false diff --git a/rules/icloud/icloud_photos_disable.yaml b/rules/icloud/icloud_photos_disable.yaml new file mode 100644 index 00000000..3ff7baed --- /dev/null +++ b/rules/icloud/icloud_photos_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_photos_disable +title: "Disable iCloud Photo Library" +discussion: | + The macOS built-in Photos.app connection to Apple's iCloud service must be disabled. Automated file snychronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudPhotoLibrary = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84738-4 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002043 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudPhotoLibrary: false diff --git a/rules/icloud/icloud_reminders_disable.yaml b/rules/icloud/icloud_reminders_disable.yaml new file mode 100644 index 00000000..0145f5c0 --- /dev/null +++ b/rules/icloud/icloud_reminders_disable.yaml @@ -0,0 +1,36 @@ +id: icloud_reminders_disable +title: "Disable iCloud Reminders" +discussion: | + The macOS built-in Reminders.app connection to Apple's iCloud service must be disabled. Automated reminder synchronization shall be planned and controlled to approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudReminders = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84739-2 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002013 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudReminders: false diff --git a/rules/icloud/icloud_sync_disable.yaml b/rules/icloud/icloud_sync_disable.yaml new file mode 100644 index 00000000..3bef7b38 --- /dev/null +++ b/rules/icloud/icloud_sync_disable.yaml @@ -0,0 +1,34 @@ +id: icloud_sync_disable +title: "Disable iCloud Desktop and Document Folder Sync" +discussion: | + The macOS system's ability to automatically synchronize a user's desktop and documents folder to their iCloud Drive must be disabled. Automated file synchronization shall be planned and controlled to Agency approved storage. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCloudDesktopAndDocuments = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84740-0 + cci: + - N/A + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudDesktopAndDocuments: false diff --git a/rules/inherent/os_allow_info_passed.yaml b/rules/inherent/os_allow_info_passed.yaml new file mode 100644 index 00000000..361a70dd --- /dev/null +++ b/rules/inherent/os_allow_info_passed.yaml @@ -0,0 +1,28 @@ +id: os_allow_info_passed +title: "Must allow information passed to other operating systems or users" +discussion: | + The macOS is a UNIX 03-compliant operating system which allows owners of object to have discretion over who should be authorized to access information. + + link:https://support.apple.com/guide/mac-help/change-permissions-for-files-folders-or-disks-mchlp1203/mac +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84863-0 + cci: + - CCI-002165 + 800-53r4: + - AC-3(4) + disa_stig: + - AOSX-15-100024 + srg: + - SRG-OS-000312-GPOS-00122 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_change_security_attributes.yaml b/rules/inherent/os_change_security_attributes.yaml new file mode 100644 index 00000000..a13e5d2a --- /dev/null +++ b/rules/inherent/os_change_security_attributes.yaml @@ -0,0 +1,28 @@ +id: os_change_security_attributes +title: "Must allow admins to change security settings and attributes" +discussion: | + The macOS is a UNIX 03-compliant operating system which allows administrators of the system to change security settings and attributes of the system. + + link:https://support.apple.com/guide/mac-help/set-up-other-users-on-your-mac-mtusr001/mac +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84882-0 + cci: + - CCI-002165 + 800-53r4: + - AC-3(4) + disa_stig: + - AOSX-15-100026 + srg: + - SRG-OS-000312-GPOS-00124 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_crypto_audit.yaml b/rules/inherent/os_crypto_audit.yaml new file mode 100644 index 00000000..9835962d --- /dev/null +++ b/rules/inherent/os_crypto_audit.yaml @@ -0,0 +1,27 @@ +id: os_crypto_audit +title: "Must use cryptographic mechanisms to protect integrity of audit tools" +discussion: | + The information system implements cryptographic mechanisms to protect the integrity of audit information and audit tools. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84889-5 + cci: + - CCI-001496 + 800-53r4: + - AU-9(3) + disa_stig: + - AOSX-15-100018 + srg: + - SRG-OS-000278-GPOS-00108 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_enforce_access_restrictions.yaml b/rules/inherent/os_enforce_access_restrictions.yaml new file mode 100644 index 00000000..b3f94b65 --- /dev/null +++ b/rules/inherent/os_enforce_access_restrictions.yaml @@ -0,0 +1,27 @@ +id: os_enforce_access_restrictions +title: "Enforce access restrictions" +discussion: | + The information system enforces access restrictions and supports auditing of the enforcement actions. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84854-9 + cci: + - CCI-001813 + 800-53r4: + - CM-5(1) + disa_stig: + - AOSX-15-100029 + srg: + - SRG-OS-000364-GPOS-00151 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_error_message.yaml b/rules/inherent/os_error_message.yaml new file mode 100644 index 00000000..3f44f761 --- /dev/null +++ b/rules/inherent/os_error_message.yaml @@ -0,0 +1,29 @@ +id: os_error_message +title: "Generate error messages without expoitable information" +discussion: | + Generates error messages that provide information necessary for corrective actions without revealing information that could be exploited by adversaries. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84887-9 + cci: + - CCI-001312 + 800-53r4: + - SI-11(a) + disa_stig: + - AOSX-15-100016 + srg: + - SRG-OS-000205-GPOS-00083 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_fail_secure_state.yaml b/rules/inherent/os_fail_secure_state.yaml new file mode 100644 index 00000000..e3c9711c --- /dev/null +++ b/rules/inherent/os_fail_secure_state.yaml @@ -0,0 +1,27 @@ +id: os_fail_secure_state +title: "Shutdown if system initialization fails, shutdown fails, or aborts fails" +discussion: | + Failure to a known safe state helps prevent systems from failing to a state that may cause loss of data or unauthorized access to system resources. Operating systems that fail suddenly and with no incorporated failure state planning may leave the system available but with a reduced security protection capability. Preserving operating system state information also facilitates system restart and return to the operational mode of the organization with less disruption to mission-essential processes. Abort refers to stopping a program or function before it has finished naturally. The term abort refers to both requested and unexpected terminations. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84860-6 + cci: + - CCI-001190 + 800-53r4: + - SC-24 + disa_stig: + - AOSX-15-100015 + srg: + - SRG-OS-000184-GPOS-00078 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_grant_privs.yaml b/rules/inherent/os_grant_privs.yaml new file mode 100644 index 00000000..a29de6bf --- /dev/null +++ b/rules/inherent/os_grant_privs.yaml @@ -0,0 +1,28 @@ +id: os_grant_privs +title: "Must allow admins to promote users to admins" +discussion: | + The macOS is a UNIX 03-compliant operating system which allows administrators of the system to grant privileges to other users. + + link: https://support.apple.com/guide/mac-help/set-up-other-users-on-your-mac-mtusr001/mac +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84878-8 + cci: + - CCI-002165 + 800-53r4: + - AC-3(4) + disa_stig: + - AOSX-15-100025 + srg: + - SRG-OS-000312-GPOS-00123 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_implement_cryptography.yaml b/rules/inherent/os_implement_cryptography.yaml new file mode 100644 index 00000000..84e74c5f --- /dev/null +++ b/rules/inherent/os_implement_cryptography.yaml @@ -0,0 +1,30 @@ +id: os_implement_cryptography +title: "Implement approved cryptography to protect information" +discussion: | + Use of weak or untested encryption algorithms undermines the purposes of utilizing encryption to protect data. The operating system must implement cryptographic modules adhering to the higher standards approved by the federal government since this provides assurance they have been tested and validated. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement using FIPS Validated Cryptographic Modules. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84867-1 + cci: + - CCI-002450 + 800-53r4: + - SC-13 + disa_stig: + - AOSX-15-100035 + srg: + - SRG-OS-000396-GPOS-00176 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_implement_memory_protection.yaml b/rules/inherent/os_implement_memory_protection.yaml new file mode 100644 index 00000000..ea248d2d --- /dev/null +++ b/rules/inherent/os_implement_memory_protection.yaml @@ -0,0 +1,29 @@ +id: os_implement_memory_protection +title: "Must implement non-executable data to protect memory from code execution" +discussion: | + Some adversaries launch attacks with the intent of executing code in non-executable regions of memory or in memory locations that are prohibited. Security safeguards employed to protect memory include, for example, data execution prevention and address space layout randomization. Data execution prevention safeguards can either be hardware-enforced or software-enforced with hardware providing the greater strength of mechanism.Examples of attacks are buffer overflow attacks. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84866-3 + cci: + - CCI-002824 + 800-53r4: + - SI-16 + disa_stig: + - AOSX-15-100037 + srg: + - SRG-OS-000433-GPOS-00192 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_implement_random_address_space.yaml b/rules/inherent/os_implement_random_address_space.yaml new file mode 100644 index 00000000..d80c6dda --- /dev/null +++ b/rules/inherent/os_implement_random_address_space.yaml @@ -0,0 +1,29 @@ +id: os_implement_random_address_space +title: "Must implement random address space to protect memory from unauthorized code execution" +discussion: | + Some adversaries launch attacks with the intent of executing code in non-executable regions of memory or in memory locations that are prohibited. Security safeguards employed to protect memory include, for example, data execution prevention and address space layout randomization. Data execution prevention safeguards can either be hardware-enforced or software-enforced with hardware providing the greater strength of mechanism.Examples of attacks are buffer overflow attacks. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84891-1 + cci: + - CCI-002824 + 800-53r4: + - SI-16 + disa_stig: + - AOSX-15-100038 + srg: + - SRG-OS-000433-GPOS-00193 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_isolate_security_functions.yaml b/rules/inherent/os_isolate_security_functions.yaml new file mode 100644 index 00000000..3c47def0 --- /dev/null +++ b/rules/inherent/os_isolate_security_functions.yaml @@ -0,0 +1,27 @@ +id: os_isolate_security_functions +title: "Isolate security functions from non-security functions" +discussion: | + The information system isolates security functions from nonsecurity functions. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84876-2 + cci: + - CCI-001084 + 800-53r4: + - SC-3 + disa_stig: + - AOSX-15-100013 + srg: + - SRG-OS-000134-GPOS-00068 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_limit_auditable_events.yaml b/rules/inherent/os_limit_auditable_events.yaml new file mode 100644 index 00000000..2dffc26d --- /dev/null +++ b/rules/inherent/os_limit_auditable_events.yaml @@ -0,0 +1,30 @@ +id: os_limit_auditable_events +title: "Only allow authorized users to select auditable events" +discussion: | + Without the capability to restrict which roles and individuals can select which events are audited, unauthorized personnel may be able to prevent the auditing of critical events. Misconfigured audits may degrade the system's performance by overwhelming the audit log. Misconfigured audits may also make it more difficult to establish, correlate, and investigate the events relating to an incident or identify those responsible for one. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84861-4 + cci: + - CCI-000171 + 800-53r4: + - AU-12(b) + disa_stig: + - AOSX-15-100002 + srg: + - SRG-OS-000063-GPOS-00032 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_limit_gui_sessions.yaml b/rules/inherent/os_limit_gui_sessions.yaml new file mode 100644 index 00000000..29b80c86 --- /dev/null +++ b/rules/inherent/os_limit_gui_sessions.yaml @@ -0,0 +1,27 @@ +id: os_limit_gui_sessions +title: "Limit number of concurrent GUI sessions to 10 for all accounts" +discussion: | + Operating system management includes the ability to control the number of users and user sessions that utilize an operating system. Limiting the number of allowed users and sessions per user is helpful in reducing the risks related to DoS attacks.This requirement addresses concurrent sessions for information system accounts and does not address concurrent sessions by single users via multiple system accounts. The maximum number of concurrent sessions should be defined based upon mission needs and the operational environment for each system. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84855-6 + cci: + - CCI-000054 + 800-53r4: + - AC-10 + disa_stig: + - AOSX-15-100001 + srg: + - SRG-OS-000027-GPOS-00008 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_logical_access.yaml b/rules/inherent/os_logical_access.yaml new file mode 100644 index 00000000..87729bd6 --- /dev/null +++ b/rules/inherent/os_logical_access.yaml @@ -0,0 +1,30 @@ +id: os_logical_access +title: "Enforce approved authorization for logical access" +discussion: | + To mitigate the risk of unauthorized access to sensitive information by entities that have been issued certificates by DoD-approved PKIs, all DoD systems (e.g., web servers and web portals) must be properly configured to incorporate access control methods that do not rely solely on the possession of a certificate for access. Successful authentication must not automatically give an entity access to an asset or security boundary. Authorization procedures and controls must be implemented to ensure each authenticated entity also has a validated and current authorization. Authorization is the process of determining whether an entity, once authenticated, is permitted to access a specific asset. Information systems use access control policies and enforcement mechanisms to implement this requirement.Access control policies include: identity-based policies, role-based policies, and attribute-based policies. Access enforcement mechanisms include: access control lists, access control matrices, and cryptography. These policies and mechanisms must be employed by the application to control access between users (or processes acting on behalf of users) and objects (e.g., devices, files, records, processes, programs, and domains) in the information system. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84857-2 + cci: + - CCI-000213 + 800-53r4: + - AC-3 + disa_stig: + - AOSX-15-100006 + srg: + - SRG-OS-000080-GPOS-00048 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_logoff_capability_and_message.yaml b/rules/inherent/os_logoff_capability_and_message.yaml new file mode 100644 index 00000000..d21db9e8 --- /dev/null +++ b/rules/inherent/os_logoff_capability_and_message.yaml @@ -0,0 +1,32 @@ +id: os_logoff_capability_and_message +title: "Display logoff capability and message to prevent exploitation" +discussion: | + Provides a logout capability for user-initiated communications sessions whenever authentication is used to gain access to the system. + + Displays an explicit logout message to users indicating the reliable termination of authenticated communications sessions. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84859-8 + cci: + - CCI-002363 + - CCI-002364 + 800-53r4: + - AC-12(1)(a) + - AC-12(1)(b) + disa_stig: + - AOSX-15-100020 + - AOSX-15-100021 + srg: + - SRG-OS-000280-GPOS-00110 + - SRG-OS-000281-GPOS-00111 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_map_pki_identity.yaml b/rules/inherent/os_map_pki_identity.yaml new file mode 100644 index 00000000..db700eaa --- /dev/null +++ b/rules/inherent/os_map_pki_identity.yaml @@ -0,0 +1,29 @@ +id: os_map_pki_identity +title: "Map identity for PKI based authentication" +discussion: | + Without mapping the certificate used to authenticate to the user account, the ability to determine the identity of the individual user or group will not be available for forensic analysis. +check: | + For directory bound systems, the technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + For directory bound systems, the technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84873-9 + cci: + - CCI-000187 + 800-53r4: + - IA-5(2)(c) + disa_stig: + - AOSX-15-100003 + srg: + - SRG-OS-000068-GPOS-00036 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_mfa_network_access.yaml b/rules/inherent/os_mfa_network_access.yaml new file mode 100644 index 00000000..8e55c904 --- /dev/null +++ b/rules/inherent/os_mfa_network_access.yaml @@ -0,0 +1,31 @@ +id: os_mfa_network_access +title: "Enforce multifactor authentication for network access to priviledged accounts" +discussion: | + The information system implements multifactor authentication for network access to privileged accounts. +check: | + For directory bound systems: + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + For directory bound systems, the technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84883-8 + cci: + - CCI-000765 + 800-53r4: + - IA-2(1) + disa_stig: + - AOSX-15-100008 + srg: + - SRG-OS-000105-GPOS-00052 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_mfa_network_non-priv.yaml b/rules/inherent/os_mfa_network_non-priv.yaml new file mode 100644 index 00000000..46559eca --- /dev/null +++ b/rules/inherent/os_mfa_network_non-priv.yaml @@ -0,0 +1,30 @@ +id: os_mfa_network_non-priv +title: "Enforce multifactor authentication for network access to non-priviledged accounts" +discussion: | + The information system implements multifactor authentication for network access to non-privileged accounts. +check: | + For directory bound systems: + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + For directory bound systems, the technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84864-8 + cci: + - CCI-000766 + 800-53r4: + - IA-2(2) + disa_stig: + - AOSX-15-100009 + srg: + - SRG-OS-000106-GPOS-00053 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_obscure_password.yaml b/rules/inherent/os_obscure_password.yaml new file mode 100644 index 00000000..834a404f --- /dev/null +++ b/rules/inherent/os_obscure_password.yaml @@ -0,0 +1,30 @@ +id: os_obscure_password +title: "Obscure passwords" +discussion: | + The information system obscures feedback of authentication information during the authentication process to protect the information from possible exploitation/use by unauthorized individuals. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84869-7 + cci: + - CCI-000206 + 800-53r4: + - IA-6 + disa_stig: + - AOSX-15-100005 + srg: + - SRG-OS-000079-GPOS-00047 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_peripherals_identify.yaml b/rules/inherent/os_peripherals_identify.yaml new file mode 100644 index 00000000..8c567624 --- /dev/null +++ b/rules/inherent/os_peripherals_identify.yaml @@ -0,0 +1,31 @@ +id: os_peripherals_identify +title: The macOS system must uniquely identify peripherals before establishing a connection. +discussion: | + Without identifying devices, unidentified or unknown devices may be introduced, thereby facilitating malicious activity. + + Peripherals include, but are not limited to, such devices as flash drives, external storage, and printers. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84885-3 + cci: + - CCI-000778 + 800-53r4: + - IA-3 + srg: + - SRG-OS-000114-GPOS-00059 + disa_stig: + - AOSX-14-002069 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: +mobileconfig_info: diff --git a/rules/inherent/os_predictable_behavior.yaml b/rules/inherent/os_predictable_behavior.yaml new file mode 100644 index 00000000..7431c1d7 --- /dev/null +++ b/rules/inherent/os_predictable_behavior.yaml @@ -0,0 +1,26 @@ +id: os_predictable_behavior +title: "Must behave in predictable and documented manner" +discussion: | + The information system behaves in a predictable and documented manner that reflects organizational and system objectives when invalid inputs are received. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84871-3 + cci: + - CCI-002754 + 800-53r4: + - SI-10(3) + disa_stig: + - AOSX-15-100036 + srg: + - SRG-OS-000432-GPOS-00191 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_preserve_information_on_crash.yaml b/rules/inherent/os_preserve_information_on_crash.yaml new file mode 100644 index 00000000..ec55cc1b --- /dev/null +++ b/rules/inherent/os_preserve_information_on_crash.yaml @@ -0,0 +1,27 @@ +id: os_preserve_information_on_crash +title: "Must preserve crash log information" +discussion: | + Failure to a known state can address safety or security in accordance with the mission/business needs of the organization. Failure to a known secure state helps prevent a loss of confidentiality, integrity, or availability in the event of a failure of the information system or a component of the system. Preserving operating system state information helps to facilitate operating system restart and return to the operational mode of the organization with least disruption to mission/business processes. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84884-6 + cci: + - CCI-001665 + 800-53r4: + - SC-24 + disa_stig: + - AOSX-15-100017 + srg: + - SRG-OS-000269-GPOS-00103 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_prevent_priv_execution.yaml b/rules/inherent/os_prevent_priv_execution.yaml new file mode 100644 index 00000000..aab5c7c1 --- /dev/null +++ b/rules/inherent/os_prevent_priv_execution.yaml @@ -0,0 +1,26 @@ +id: os_prevent_priv_execution +title: "Prevent all software from executing at higher privilege levels than users executing the software" +discussion: | + In certain situations, software applications/programs need to execute with elevated privileges to perform required functions. However, if the privileges required for execution are at a higher level than the privileges assigned to organizational users invoking such applications/programs, those users are indirectly provided with greater privileges than assigned by the organizations.Some programs and processes are required to operate at a higher privilege level and therefore should be excluded from the organization-defined software list after review. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84862-2 + cci: + - CCI-002233 + 800-53r4: + - AC-6(8) + disa_stig: + - AOSX-15-100028 + srg: + - SRG-OS-000326-GPOS-00126 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_prevent_priv_functions.yaml b/rules/inherent/os_prevent_priv_functions.yaml new file mode 100644 index 00000000..5fe51ea3 --- /dev/null +++ b/rules/inherent/os_prevent_priv_functions.yaml @@ -0,0 +1,29 @@ +id: os_prevent_priv_functions +title: "Preventing non-privileged users from executing privileged functions" +discussion: | + The information system prevents non-privileged users from executing privileged functions to include disabling, circumventing, or altering implemented security safeguards/countermeasures. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84856-4 + cci: + - CCI-002235 + 800-53r4: + - AC-6(10) + disa_stig: + - AOSX-15-100027 + srg: + - SRG-OS-000324-GPOS-00125 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_prevent_restricted_software.yaml b/rules/inherent/os_prevent_restricted_software.yaml new file mode 100644 index 00000000..ff9425b4 --- /dev/null +++ b/rules/inherent/os_prevent_restricted_software.yaml @@ -0,0 +1,29 @@ +id: os_prevent_restricted_software +title: "Prevent program execution in accordance with policy" +discussion: | + Control of program execution is a mechanism used to prevent execution of unauthorized programs. Some operating systems may provide a capability that runs counter to the mission or provides users with functionality that exceeds mission requirements. This includes functions and services installed at the operating system-level.Some of the programs, installed by default, may be harmful or may not be necessary to support essential organizational operations (e.g., key missions, functions). Removal of executable programs is not always possible; therefore, establishing a method of preventing program execution is critical to maintaining a secure system baseline.Methods for complying with this requirement include restricting execution of programs in certain environments, while preventing execution in other environments; or limiting execution of certain program functionality based on organization-defined criteria (e.g., privileges, subnets, sandboxed environments, or roles). +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84886-1 + cci: + - CCI-001764 + 800-53r4: + - CM-7(2) + disa_stig: + - AOSX-15-100030 + srg: + - SRG-OS-000368-GPOS-00154 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_prevent_unauthorized_disclosure.yaml b/rules/inherent/os_prevent_unauthorized_disclosure.yaml new file mode 100644 index 00000000..9182c100 --- /dev/null +++ b/rules/inherent/os_prevent_unauthorized_disclosure.yaml @@ -0,0 +1,29 @@ +id: os_prevent_unauthorized_disclosure +title: "Prevent unauthorized disclosure of data via shared resources" +discussion: | + The information system prevents unauthorized and unintended information transfer via shared system resources. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84880-4 + cci: + - CCI-001090 + 800-53r4: + - SC-4 + disa_stig: + - AOSX-15-100014 + srg: + - SRG-OS-000138-GPOS-00069 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_provide_disconnect_remote_access.yaml b/rules/inherent/os_provide_disconnect_remote_access.yaml new file mode 100644 index 00000000..ce278eff --- /dev/null +++ b/rules/inherent/os_provide_disconnect_remote_access.yaml @@ -0,0 +1,26 @@ +id: os_provide_disconnect_remote_access +title: "Provide ability to disconnect or disable remote access" +discussion: | + Without the ability to immediately disconnect or disable remote access, an attack or other compromise taking place would not be immediately stopped.Operating system remote access functionality must have the capability to immediately disconnect current users remotely accessing the information system and/or disable further remote access. The speed of disconnect or disablement varies based on the criticality of missions functions and the need to eliminate immediate or future remote access to organizational information systems.The remote access functionality (e.g., RDP) may implement features such as automatic disconnect (or user-initiated disconnect) in case of adverse information based on an indicator of compromise or attack. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84875-4 + cci: + - CCI-002322 + 800-53r4: + - AC-17(9) + disa_stig: + - AOSX-15-100023 + srg: + - SRG-OS-000298-GPOS-00116 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_reauth_privilege.yaml b/rules/inherent/os_reauth_privilege.yaml new file mode 100644 index 00000000..34409388 --- /dev/null +++ b/rules/inherent/os_reauth_privilege.yaml @@ -0,0 +1,28 @@ +id: os_reauth_privilege +title: "Require users to reauthenticate for privilege escalation" +discussion: | + Without reauthentication, users may access resources or perform tasks for which they do not have authorization. When operating systems provide the capability to escalate a functional capability, it is critical the user reauthenticate. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84890-3 + cci: + - CCI-002038 + 800-53r4: + - IA-11 + disa_stig: + - AOSX-15-100031 + - AOSX-15-100032 + srg: + - SRG-OS-000373-GPOS-00156 + - SRG-OS-000373-GPOS-00157 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_reauth_users_change_authenticators.yaml b/rules/inherent/os_reauth_users_change_authenticators.yaml new file mode 100644 index 00000000..e172e2ed --- /dev/null +++ b/rules/inherent/os_reauth_users_change_authenticators.yaml @@ -0,0 +1,26 @@ +id: os_reauth_users_change_authenticators +title: "Require users to reauthenticate when changing authenticators" +discussion: | + Without reauthentication, users may access resources or perform tasks for which they do not have authorization. When operating systems provide the capability to change user authenticators, it is critical the user reauthenticate. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84872-1 + cci: + - CCI-002038 + 800-53r4: + - IA-11 + disa_stig: + - AOSX-15-100033 + srg: + - SRG-OS-000373-GPOS-00158 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_remote_access_methods.yaml b/rules/inherent/os_remote_access_methods.yaml new file mode 100644 index 00000000..153bde55 --- /dev/null +++ b/rules/inherent/os_remote_access_methods.yaml @@ -0,0 +1,29 @@ +id: os_remote_access_methods +title: "Control remote access methods" +discussion: | + The information system monitors and controls remote access methods. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84868-9 + cci: + - CCI-002314 + 800-53r4: + - AC-17(1) + disa_stig: + - AOSX-15-100022 + srg: + - SRG-OS-000297-GPOS-00115 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_remove_software_components_after_updates.yaml b/rules/inherent/os_remove_software_components_after_updates.yaml new file mode 100644 index 00000000..36a418e7 --- /dev/null +++ b/rules/inherent/os_remove_software_components_after_updates.yaml @@ -0,0 +1,26 @@ +id: os_remove_software_components_after_updates +title: "Must remove all software components after updated versions installed" +discussion: | + Previous versions of software components that are not removed from the information system after updates have been installed may be exploited by adversaries. Some information technology products may remove older versions of software automatically from the information system. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84865-5 + cci: + - CCI-002617 + 800-53r4: + - SI-2(6) + disa_stig: + - AOSX-15-100039 + srg: + - SRG-OS-000437-GPOS-00194 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_required_crypto_module.yaml b/rules/inherent/os_required_crypto_module.yaml new file mode 100644 index 00000000..e892c312 --- /dev/null +++ b/rules/inherent/os_required_crypto_module.yaml @@ -0,0 +1,30 @@ +id: os_required_crypto_module +title: "Must meet federal laws, Executive orders, directives, policies, regulations, standards, and guidance for authentication to a cryptographic module" +discussion: | + The information system implements mechanisms for authentication to a cryptographic module that meet the requirements of applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance for such authentication. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84877-0 + cci: + - CCI-000803 + 800-53r4: + - IA-7 + disa_stig: + - AOSX-15-100010 + srg: + - SRG-OS-000120-GPOS-00061 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_separate_fuctionality.yaml b/rules/inherent/os_separate_fuctionality.yaml new file mode 100644 index 00000000..792e45dd --- /dev/null +++ b/rules/inherent/os_separate_fuctionality.yaml @@ -0,0 +1,29 @@ +id: os_separate_fuctionality +title: "Must separate user and system functionality" +discussion: | + Operating system management functionality includes functions necessary for administration and requires privileged user access. Allowing non-privileged users to access operating system management functionality capabilities increases the risk that non-privileged users may obtain elevated privileges.Operating system management functionality includes functions necessary to administer console, network components, workstations, or servers and typically requires privileged user access.The separation of user functionality from information system management functionality is either physical or logical and is accomplished by using different computers, different central processing units, different instances of the operating system, different network addresses, different TCP/UDP ports, virtualization techniques, combinations of these methods, or other methods, as appropriate.An example of this type of separation is observed in web administrative interfaces that use separate authentication methods for users of any other information system resources. This may include isolating the administrative interface on a different security domain and with additional access controls. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84888-7 + cci: + - CCI-001082 + 800-53r4: + - SC-2 + disa_stig: + - AOSX-15-100012 + srg: + - SRG-OS-000132-GPOS-00067 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_store_encrypted_passwords.yaml b/rules/inherent/os_store_encrypted_passwords.yaml new file mode 100644 index 00000000..5750d257 --- /dev/null +++ b/rules/inherent/os_store_encrypted_passwords.yaml @@ -0,0 +1,30 @@ +id: os_store_encrypted_passwords +title: "Store passwords encrypted" +discussion: | + Passwords need to be protected at all times, and encryption is the standard method for protecting passwords. If passwords are not encrypted, they can be plainly read (i.e., clear text) and easily compromised. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84879-6 + cci: + - CCI-000196 + 800-53r4: + - IA-5(1)(c) + disa_stig: + - AOSX-15-100004 + srg: + - SRG-OS-000073-GPOS-00041 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_terminate_session.yaml b/rules/inherent/os_terminate_session.yaml new file mode 100644 index 00000000..ec427be9 --- /dev/null +++ b/rules/inherent/os_terminate_session.yaml @@ -0,0 +1,30 @@ +id: os_terminate_session +title: "Terminate all sessions and network connections when maintenance is completed" +discussion: | + Terminates session and network connections when nonlocal maintenance is completed. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84881-2 + cci: + - CCI-000879 + 800-53r4: + - MA-4(e) + disa_stig: + - AOSX-15-100011 + srg: + - SRG-OS-000126-GPOS-00066 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_terminate_session_inactivity.yaml b/rules/inherent/os_terminate_session_inactivity.yaml new file mode 100644 index 00000000..227a9aaf --- /dev/null +++ b/rules/inherent/os_terminate_session_inactivity.yaml @@ -0,0 +1,30 @@ +id: os_terminate_session_inactivity +title: "Automatically terminate user session after inactivity" +discussion: | + Automatic session termination addresses the termination of user-initiated logical sessions in contrast to the termination of network connections that are associated with communications sessions (i.e., network disconnect). A logical session (for local, network, and remote access) is initiated whenever a user (or process acting on behalf of a user) accesses an organizational information system. Such user sessions can be terminated (and thus terminate user access) without terminating network sessions.Session termination terminates all processes associated with a user's logical session except those processes that are specifically created by the user (i.e., session owner) to continue after the session is terminated.Conditions or trigger events requiring automatic session termination can include, for example, organization-defined periods of user inactivity, targeted responses to certain types of incidents, and time-of-day restrictions on information system use.This capability is typically reserved for specific operating system functionality where the system owner, data owner, or organization requires additional assurance. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84870-5 + cci: + - CCI-002361 + 800-53r4: + - AC-12 + disa_stig: + - AOSX-15-100019 + srg: + - SRG-OS-000279-GPOS-00109 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_unique_identification.yaml b/rules/inherent/os_unique_identification.yaml new file mode 100644 index 00000000..232e2e40 --- /dev/null +++ b/rules/inherent/os_unique_identification.yaml @@ -0,0 +1,30 @@ +id: os_unique_identification +title: "Identify and authenticate organizational users and processes" +discussion: | + The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users). +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84874-7 + cci: + - CCI-000764 + 800-53r4: + - IA-2 + disa_stig: + - AOSX-15-100007 + srg: + - SRG-OS-000104-GPOS-00051 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/os_verify_remote_disconnection.yaml b/rules/inherent/os_verify_remote_disconnection.yaml new file mode 100644 index 00000000..8798fd6f --- /dev/null +++ b/rules/inherent/os_verify_remote_disconnection.yaml @@ -0,0 +1,26 @@ +id: os_verify_remote_disconnection +title: "Verify remote disconnection of sessions" +discussion: | + The information system implements remote disconnect verification at the termination of nonlocal maintenance and diagnostic sessions. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84858-0 + cci: + - CCI-002891 + 800-53r4: + - MA-4(7) + disa_stig: + - AOSX-15-100034 + srg: + - SRG-OS-000395-GPOS-00175 +macOS: + - "10.15" +tags: + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/pwpolicy_emergency_accounts_disable.yaml b/rules/inherent/pwpolicy_emergency_accounts_disable.yaml new file mode 100644 index 00000000..b0c100c6 --- /dev/null +++ b/rules/inherent/pwpolicy_emergency_accounts_disable.yaml @@ -0,0 +1,32 @@ +id: pwpolicy_emergency_accounts_disable +title: "Automatically remove or disable emergency accounts after the crisis is resolved or within 72 hours" +discussion: | + Emergency administrator accounts are privileged accounts established in response to crisis situations where the need for rapid account activation is required. Therefore, emergency account activation may bypass normal account authorization processes. If these accounts are automatically disabled, system maintenance during emergencies may not be possible, thus adversely affecting system availability. + + Emergency administrator accounts are different from infrequently used accounts (i.e., local logon accounts used by system administrators when network or normal logon/access is not available). Infrequently used accounts also remain available and are not subject to automatic termination dates. However, an emergency administrator account is normally a different account created for use by vendors or system maintainers. + + To address access requirements, many operating systems can be integrated with enterprise-level authentication/access mechanisms that meet or exceed access control policy requirements. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84812-7 + cci: + - CCI-001682 + 800-53r4: + - AC-2(2) + srg: + - SRG-OS-00123-GPOS-00064 + disa_stig: + - AOSX-14-000013 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - inherent +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/inherent/pwpolicy_force_password_change.yaml b/rules/inherent/pwpolicy_force_password_change.yaml new file mode 100644 index 00000000..f2a22e2d --- /dev/null +++ b/rules/inherent/pwpolicy_force_password_change.yaml @@ -0,0 +1,37 @@ +id: pwpolicy_force_change +title: "Force password change at next logon" +discussion: | + Allows the use of a temporary password for system logons with an immediate change to a permanent password. + + To for a user to change their password at next logon, run the following command: + [source,bash] + ---- + /usr/bin/pwpolicy -u [USER] -setpolicy "newPasswordRequired=1" + ---- + NOTE: Replace [USER] with the username that must change the password at next logon +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84813-5 + cci: + - CCI-002041 + 800-53r4: + - IA-5(1)(f) + disa_stig: + - AOSX-15-200021 + srg: + - SRG-OS-000380-GPOS-00165 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: false +mobileconfig_info: diff --git a/rules/inherent/pwpolicy_temporary_accounts_disable.yaml b/rules/inherent/pwpolicy_temporary_accounts_disable.yaml new file mode 100644 index 00000000..6c6c1cd8 --- /dev/null +++ b/rules/inherent/pwpolicy_temporary_accounts_disable.yaml @@ -0,0 +1,39 @@ +id: pwpolicy_temporary_accounts_disable +title: "Automatically remove or disable temporary user accounts after 72 hours" +discussion: | + If temporary user accounts remain active when no longer needed or for an excessive period, these accounts may be targeted by attackers to gain unauthorized access. To mitigate this risk, automated termination of all temporary accounts must be set upon account creation. + + Temporary accounts are established as part of normal account activation procedures when there is a need for short-term accounts without the demand for immediacy in account activation. + + If temporary accounts are used, the operating system must be configured to automatically terminate these types of accounts after a defined time period of 72 hours. + + To address access requirements, many operating systems may be integrated with enterprise-level authentication/access mechanisms that meet or exceed access control policy requirements. + + If no policy is enforced by a directory service, a password policy can be set with the "pwpolicy" utility. The variable names may vary depending on how the policy was set. + + If there are no temporary accounts defined on the system, this is Not Applicable. +check: | + The technology supports this requirement and cannot be configured to be out of compliance. The technology inherently meets this requirement. +fix: | + The technology inherently meets this requirement. No fix is required. +references: + cce: + - CCE-84820-0 + cci: + - CCI-000016 + 800-53r4: + - AC-2(2) + srg: + - SRG-OS-000002-GPOS-00002 + disa_stig: + - AOSX-14-000012 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - inherent +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/not_applicable/os_auth_peripherals.yaml b/rules/not_applicable/os_auth_peripherals.yaml new file mode 100644 index 00000000..4d2a4378 --- /dev/null +++ b/rules/not_applicable/os_auth_peripherals.yaml @@ -0,0 +1,29 @@ +id: os_auth_peripherals +title: "Must authenicate peripherals before establishing a connection" +discussion: | + Without authenticating devices, unidentified or unknown devices may be introduced, thereby facilitating malicious activity. Peripherals include, but are not limited to, such devices as flash drives, external storage, and printers. +check: | + This requirement is NA for this technology. +fix: | + The requirement is NA. No fix is required. +references: + cce: + - CCE-84741-8 + cci: + - CCI-001958 + 800-53r4: + - IA-3 + disa_stig: + - AOSX-15-300002 + srg: + - SRG-OS-000378-GPOS-00163 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - n_a +mobileconfig: false +mobileconfig_info: diff --git a/rules/not_applicable/os_identify_non-org_users.yaml b/rules/not_applicable/os_identify_non-org_users.yaml new file mode 100644 index 00000000..766f032f --- /dev/null +++ b/rules/not_applicable/os_identify_non-org_users.yaml @@ -0,0 +1,30 @@ +id: os_identify_non-org_users +title: "Must uniquely identify and authenticate non-organizational users" +discussion: | + The information system uniquely identifies and authenticates non-organizational users (or processes acting on behalf of non-organizational users). +check: | + This requirement is NA for this technology. +fix: | + The requirement is NA. No fix is required. +references: + cce: + - CCE-84742-6 + cci: + - CCI-000804 + 800-53r4: + - IA-8 + disa_stig: + - AOSX-15-300001 + srg: + - SRG-OS-000121-GPOS-00062 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - n_a +mobileconfig: false +mobileconfig_info: diff --git a/rules/not_applicable/os_prohibit_cached_authenticators.yaml b/rules/not_applicable/os_prohibit_cached_authenticators.yaml new file mode 100644 index 00000000..7cedd9e3 --- /dev/null +++ b/rules/not_applicable/os_prohibit_cached_authenticators.yaml @@ -0,0 +1,26 @@ +id: os_prohibit_cached_authenticators +title: "Must prohibit the use of cached authenticators after one day" +discussion: | + If cached authentication information is out-of-date, the validity of the authentication information may be questionable. +check: | + This requirement is NA for this technology. +fix: | + The requirement is NA. No fix is required. +references: + cce: + - CCE-84743-4 + cci: + - CCI-002007 + 800-53r4: + - IA-5(13) + disa_stig: + - AOSX-15-300004 + srg: + - SRG-OS-000383-GPOS-00166 +macOS: + - "10.15" +tags: + - STIG + - n_a +mobileconfig: false +mobileconfig_info: diff --git a/rules/not_applicable/os_react_security_anomalies.yaml b/rules/not_applicable/os_react_security_anomalies.yaml new file mode 100644 index 00000000..98407fa9 --- /dev/null +++ b/rules/not_applicable/os_react_security_anomalies.yaml @@ -0,0 +1,27 @@ +id: os_react_security_anomalies +title: "Shutdown, restart, or notify when anomalies in the security functions are discovered" +discussion: | + If anomalies are not acted upon, security functions may fail to secure the system. Security function is defined as the hardware, software, and/or firmware of the information system responsible for enforcing the system security policy and supporting the isolation of code and data on which the protection is based. Security functionality includes, but is not limited to, establishing system accounts, configuring access authorizations (i.e., permissions, privileges), setting events to be audited, and setting intrusion detection parameters.Notifications provided by information systems include messages to local computer consoles, and/or hardware indications, such as lights.This capability must take into account operational requirements for availability for selecting an appropriate response. The organization may choose to shut down or restart the information system upon security function anomaly detection. +check: | + This requirement is NA for this technology. +fix: | + The requirement is NA. No fix is required. +references: + cce: + - CCE-84744-2 + cci: + - CCI-002702 + 800-53r4: + - SI-6(d) + disa_stig: + - AOSX-15-300011 + srg: + - SRG-OS-000447-GPOS-00201 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - n_a +mobileconfig: false +mobileconfig_info: diff --git a/rules/not_applicable/os_request_verification_name_resolution.yaml b/rules/not_applicable/os_request_verification_name_resolution.yaml new file mode 100644 index 00000000..36bf25de --- /dev/null +++ b/rules/not_applicable/os_request_verification_name_resolution.yaml @@ -0,0 +1,39 @@ +id: os_request_verification_name_resolution +title: "Must request data origin authentication verification on the name/address resolution responses the system receives from authoritative sources" +discussion: | + The information system requests and performs data origin authentication and data integrity verification on the name/address resolution responses the system receives from authoritative sources. +check: | + This requirement is NA for this technology. +fix: | + The requirement is NA. No fix is required. +references: + cce: + - CCE-84745-9 + cci: + - CCI-002465 + - CCI-002466 + - CCI-002467 + - CCI-002468 + 800-53r4: + - SC-21 + disa_stig: + - AOSX-15-300005 + - AOSX-15-300006 + - AOSX-15-300007 + - AOSX-15-300008 + srg: + - SRG-OS-000399-GPOS-00178 + - SRG-OS-000400-GPOS-00179 + - SRG-OS-000401-GPOS-00180 + - SRG-OS-000402-GPOS-00181 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - n_a +mobileconfig: false +mobileconfig_info: diff --git a/rules/not_applicable/os_verify_security_functions.yaml b/rules/not_applicable/os_verify_security_functions.yaml new file mode 100644 index 00000000..bf09e3fc --- /dev/null +++ b/rules/not_applicable/os_verify_security_functions.yaml @@ -0,0 +1,31 @@ +id: os_verify_security_functions +title: "Must perform verification of correct security functions upon system start up, restart, or every 30 days" +discussion: | + Without verification of the security functions, security functions may not operate correctly and the failure may go unnoticed. Security function is defined as the hardware, software, and/or firmware of the information system responsible for enforcing the system security policy and supporting the isolation of code and data on which the protection is based. Security functionality includes, but is not limited to, establishing system accounts, configuring access authorizations (i.e., permissions, privileges), setting events to be audited, and setting intrusion detection parameters.Notifications provided by information systems include, for example, electronic alerts to system administrators, messages to local computer consoles, and/or hardware indications, such as lights.This requirement applies to operating systems performing security function verification/testing and/or systems and environments that require this functionality. +check: | + This requirement is NA for this technology. +fix: | + The requirement is NA. No fix is required. +references: + cce: + - CCE-84746-7 + cci: + - CCI-002696 + - CCI-002699 + 800-53r4: + - SI-6(a) + - SI-6(b) + disa_stig: + - AOSX-15-300009 + - AOSX-15-300010 + srg: + - SRG-OS-000445-GPOS-00199 + - SRG-OS-000446-GPOS-00200 +macOS: + - "10.15" +tags: + - fisma-high + - STIG + - n_a +mobileconfig: false +mobileconfig_info: diff --git a/rules/os/os_SIP_enable.yaml b/rules/os/os_SIP_enable.yaml new file mode 100644 index 00000000..bb96200a --- /dev/null +++ b/rules/os/os_SIP_enable.yaml @@ -0,0 +1,78 @@ +id: os_sip_enable +title: "Ensure System Integrity Protection (SIP) is Enabled" +discussion: | + System Integrity Protection (SIP) is vital to prevent unauthorized and unintended information transfer via shared system resources, protect audit tools from unauthorized access, modification, and deletion, limit privileges to change software resident within software libraries, limit the ability of non-privileged users to grant other users direct access to the contents of their home directories/folders. + + SIP also ensures the presence of an audit record generation capability for defined auditable events for all operating system components, supports on-demand and after-the-fact reporting requirements, does not alter original content or time ordering of audit records, and does not alter original content or time ordering of audit records. +check: | + /usr/bin/csrutil status | grep -c 'System Integrity Protection status: enabled.' +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/csrutil enable + ---- + NOTE: To reenable "System Integrity Protection", boot the affected system into "Recovery" mode, launch "Terminal" from the "Utilities" menu, and run the command. +references: + cce: + - CCE-84790-5 + cci: + - CCI-000154 + - CCI-000158 + - CCI-000169 + - CCI-001493 + - CCI-001494 + - CCI-001495 + - CCI-001499 + - CCI-001875 + - CCI-001876 + - CCI-001877 + - CCI-001878 + - CCI-001879 + - CCI-001880 + - CCI-001881 + - CCI-001882 + 800-53r4: + - AU-12 + - AU-12(a) + - AU-6(4) + - AU-7(1) + - AU-7(a) + - AU-7(b) + - AU-9 + - AU-9(3) + - CM-5(6) + - CM-6(b) + - SC-4 + srg: + - SRG-OS-000051-GPOS-00024 + - SRG-OS-000054-GPOS-00025 + - SRG-OS-000062-GPOS-00031 + - SRG-OS-000122-GPOS-00063 + - SRG-OS-000138-GPOS-00069 + - SRG-OS-000256-GPOS-00097 + - SRG-OS-000257-GPOS-00098 + - SRG-OS-000258-GPOS-00099 + - SRG-OS-000259-GPOS-00100 + - SRG-OS-000348-GPOS-00136 + - SRG-OS-000349-GPOS-00137 + - SRG-OS-000350-GPOS-00138 + - SRG-OS-000351-GPOS-00139 + - SRG-OS-000352-GPOS-00140 + - SRG-OS-000353-GPOS-00141 + - SRG-OS-000354-GPOS-00142 + - SRG-OS-000480-GPOS-00228 + - SRG-OS-000480-GPOS-00230 + disa_stig: + - AOSX-14-005001 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_airdrop_disable.yaml b/rules/os/os_airdrop_disable.yaml new file mode 100644 index 00000000..d4e24352 --- /dev/null +++ b/rules/os/os_airdrop_disable.yaml @@ -0,0 +1,33 @@ +id: os_airdrop_disable +title: "Disable AirDrop" +discussion: + AirDrop allows you to share and receive files from other nearby Apple devices. AirDrop must be disabled to prevent file transfers to or from unauthorized devices. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'DisableAirDrop = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84747-5 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002009 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.NetworkBrowser: + DisableAirDrop: true diff --git a/rules/os/os_appleid_prompt_disable.yaml b/rules/os/os_appleid_prompt_disable.yaml new file mode 100644 index 00000000..64d602b7 --- /dev/null +++ b/rules/os/os_appleid_prompt_disable.yaml @@ -0,0 +1,35 @@ +id: os_appleid_prompt_disable +title: "Disable Apple ID setup at login" +discussion: | + The prompt for Apple ID must be disabled during login, as it might mislead new users into creating unwanted Apple ID accounts upon their first login. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'SkipCloudSetup = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84748-3 + cci: + - CCI-000381 + 800-53r4: + - CM-6(b) + - CM-7(a) + srg: + - SRG-OS-000480-GPOS-00227 + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002035 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.SetupAssistant.managed: + SkipCloudSetup: true diff --git a/rules/os/os_bonjour_disable.yaml b/rules/os/os_bonjour_disable.yaml new file mode 100644 index 00000000..d1a6f615 --- /dev/null +++ b/rules/os/os_bonjour_disable.yaml @@ -0,0 +1,34 @@ +id: os_bonjour_disable +title: "Disable Bonjour multicast" +discussion: | + Bonjour multicast advertising must be disabled to prevent the system from broadcasting its presence and available services. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'NoMulticastAdvertisements = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84749-1 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + - CM-7(b) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002005 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mDNSResponder: + NoMulticastAdvertisements: true diff --git a/rules/os/os_calendar_app_disable.yaml b/rules/os/os_calendar_app_disable.yaml new file mode 100644 index 00000000..96da9549 --- /dev/null +++ b/rules/os/os_calendar_app_disable.yaml @@ -0,0 +1,38 @@ +id: os_calendar_app_disable +title: "Disable Calendar.app" +discussion: | + The macOS built-in Calendar.app can establish a connection to non-approved services. This control is in place to prevent inadvertent data transfers. +check: + /usr/bin/profiles -P -o stdout | /usr/bin/grep -A 20 familyControlsEnabled | /usr/bin/grep -c "/Applications/Calendar.app" +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84750-9 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002023 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess.new: + familyControlsEnabled: true + pathBlackList: + - /Applications/Calendar.app diff --git a/rules/os/os_camera_disable.yaml b/rules/os/os_camera_disable.yaml new file mode 100644 index 00000000..9e9f7ffb --- /dev/null +++ b/rules/os/os_camera_disable.yaml @@ -0,0 +1,37 @@ +id: os_camera_disable +title: "Disable Camera" +discussion: | + The macOS system must be configured to disable the camera. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowCamera = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84751-7 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - SC-15(3) + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002017 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCamera: false diff --git a/rules/os/os_certificate_authority_trust.yaml b/rules/os/os_certificate_authority_trust.yaml new file mode 100644 index 00000000..6b66418e --- /dev/null +++ b/rules/os/os_certificate_authority_trust.yaml @@ -0,0 +1,33 @@ +id: os_certificate_authority_trust +title: "The macOS system must issue or obtain public key certificates under an appropriate certificate policy from an approved service provider." +discussion: | + The organization issues or obtains public key certificates from an approved service provider. +check: | + /usr/bin/security dump-keychain /Library/Keychains/System.keychain | /usr/bin/grep labl | awk -F'"' '{ print $4 }' +result: + string: "If this list does not contain approved root certificates, this is a finding." +fix: | + Obtain the approved certificates from the appropriate authority and install them to the System Keychain. +references: + cce: + - CCE-84752-5 + cci: + - CCI-000185 + - CCI-002450 + 800-53r4: + - IA-5(2)(a) + - SC-17 + disa_stig: + - AOSX-14-003001 + srg: + - SRG-OS-000066-GPOS-00034 + - SRG-OS-000478-GPOS-00223 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_facetime_app_disable.yaml b/rules/os/os_facetime_app_disable.yaml new file mode 100644 index 00000000..a775ecc2 --- /dev/null +++ b/rules/os/os_facetime_app_disable.yaml @@ -0,0 +1,38 @@ +id: os_facetime_app_disable +title: "Disable FaceTime.app" +discussion: | + The macOS built-in FaceTime.app establishes a connection to Apple's iCloud service, despite using security controls to disable iCloud access. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -A 20 familyControlsEnabled | /usr/bin/grep -c "/Applications/FaceTime.app" +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84753-3 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - ASOX-14-002010 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess.new: + familyControlsEnabled: true + pathBlackList: + - /Applications/FaceTime.app diff --git a/rules/os/os_filevault_autologin_disable.yaml b/rules/os/os_filevault_autologin_disable.yaml new file mode 100644 index 00000000..87e42aac --- /dev/null +++ b/rules/os/os_filevault_autologin_disable.yaml @@ -0,0 +1,32 @@ +id: os_filevault_autologin_disable +title: "Disable FileVault Automatic Login" +discussion: | + The default behavior of macOS when FileVault is enabled is to pass-through your FileVault credentials to the login window. Disable automatic login if FileVault is enabled, so that both FileVault and loginwindow authentication are required. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'DisableFDEAutoLogin = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84754-1 + 800-53r4: + - AC-3 + srg: + - SRG-OS-000480-GPOS-00229 + disa_stig: + - AOSX-14-002066 + cci: + - CCI-000366 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.loginwindow: + DisableFDEAutoLogin: true diff --git a/rules/os/os_firewall_default_deny_require.yaml b/rules/os/os_firewall_default_deny_require.yaml new file mode 100644 index 00000000..52a67bc4 --- /dev/null +++ b/rules/os/os_firewall_default_deny_require.yaml @@ -0,0 +1,34 @@ +id: os_firewall_default_deny_require +title: "The macOS system must employ a deny-all, allow-by-exception firewall policy for allowing connections to other systems." +discussion: | + Failure to restrict network connectivity only to authorized systems permits inbound connections from malicious systems. It also permits outbound connections that may facilitate exfiltration of data. + + If you are using a thrid-party firewall solution, this rule is N/A. This rule checks for the built in pf packet filter configuration for the default deny rule. +check: | + /sbin/pfctl -a '*' -sr &> /dev/null | grep -c "block drop in all" +result: + integer: 1 +fix: | + NOTE: See Firewall Supplemental which includes a script that has an example policy to implement this rule. +references: + cce: + - CCE-84756-6 + cci: + - CCI-000366 + - CCI-002080 + 800-53r4: + - CM-6(b) + - CA-3(5) + srg: + - SRG-OS-000480-GPOS-00231 + disa_stig: + - AOSX-14-005051 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: \ No newline at end of file diff --git a/rules/os/os_firewall_log_enable.yaml b/rules/os/os_firewall_log_enable.yaml new file mode 100644 index 00000000..f197bca0 --- /dev/null +++ b/rules/os/os_firewall_log_enable.yaml @@ -0,0 +1,37 @@ +id: os_firewall_log_enable +title: "The macOS firewall must have logging enabled." +discussion: | + Firewall logging must be enabled. This ensures that malicious network activity will be logged to the system. The firewall is logged to Apple's Unified Logging with the subsystem com.apple.alf and the data is marked as private. +check: | + /usr/libexec/ApplicationFirewall/socketfilterfw --getloggingmode | /usr/bin/grep -c "Log mode is on" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/libexec/ApplicationFirewall/socketfilterfw --setloggingmode on + ---- +references: + cce: + - CCE-84757-4 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00232 + disa_stig: + - AOSX-14-005050 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.alf: + loggingenabled: true diff --git a/rules/os/os_firmware_password_require.yaml b/rules/os/os_firmware_password_require.yaml new file mode 100644 index 00000000..5c7e8530 --- /dev/null +++ b/rules/os/os_firmware_password_require.yaml @@ -0,0 +1,40 @@ +id: os_firmware_password_require +title: "Enable firmware password" +discussion: | + Single user mode, recovery mode, and the boot picker, as well as numerous other tools are available on macOS through booting while holding the "Option" key down. Setting a firmware password restricts access to these tools. + + To set a firmware passcode use the following command: + + [source,bash] + ---- + /usr/sbin/firmwarepasswd -setpasswd + ---- + + NOTE: If firmware password or passcode is forgotten, the only way to reset the forgotten password is through the use of a machine specific binary generated and provided by Apple. Schedule a support call, and provide proof of purchase before the firmware binary will be generated. + +check: | + /usr/sbin/firmwarepasswd -check | grep -c "Password Enabled: Yes" +result: + integer: 1 +fix: | + NOTE: See discussion on remediation and how to enable firmware password. +references: + cce: + - CCE-84758-2 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-003013 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: \ No newline at end of file diff --git a/rules/os/os_gatekeeper_enable.yaml b/rules/os/os_gatekeeper_enable.yaml new file mode 100644 index 00000000..2c6b551d --- /dev/null +++ b/rules/os/os_gatekeeper_enable.yaml @@ -0,0 +1,37 @@ +id: os_gatekeeper_enable +title: "Enable Gatekeeper" +discussion: | + Gatekeeper settings must be configured correctly to only allow the system to run applications downloaded from the Mac App Store or applications signed with a valid Apple Developer ID code. Administrator users will still have the option to override these settings on a per-app basis. Gatekeeper is a security feature that ensures that applications must be digitally signed by an Apple-issued certificate in order to run. Digital signatures allow the macOS host to verify that the application has not been modified by a malicious third party. +check: | + /usr/sbin/spctl --status | grep -c "assessments enabled" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/sbin/spctl --master-enable + ---- +references: + cce: + - CCE-84759-0 + cci: + - CCI-001749 + 800-53r4: + - CM-5(3) + - CM-6(b) + srg: + - SRG-OS-000366-GPOS-00153 + disa_stig: + - AOSX-14-002064 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.systempolicy.control: + EnableAssessment: true diff --git a/rules/os/os_gatekeeper_rearm.yaml b/rules/os/os_gatekeeper_rearm.yaml new file mode 100644 index 00000000..40f28279 --- /dev/null +++ b/rules/os/os_gatekeeper_rearm.yaml @@ -0,0 +1,33 @@ +id: os_gatekeeper_rearm +title: "Enforce Gatekeeper 30 day rearm" +discussion: | + If Gatekeeper is disabled, there is an automatic setting for to be re-enabled after 30 days. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'GKAutoRearm = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84852-3 + cci: + - N/A + 800-53r4: + - CM-6(b) + srg: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.security: + GKAutoRearm: true \ No newline at end of file diff --git a/rules/os/os_guest_access_afp_disable.yaml b/rules/os/os_guest_access_afp_disable.yaml new file mode 100644 index 00000000..4d443f00 --- /dev/null +++ b/rules/os/os_guest_access_afp_disable.yaml @@ -0,0 +1,32 @@ +id: os_guest_access_afp_disable +title: "Disable Guest Access to Shared Apple File Protocol (AFP) Folders" +discussion: | + Turning off guest access prevents anonymous users from accessing files shared via AFP. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'guestAccess = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84760-8 + 800-53r4: + - IA-2 + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.AppleFileServer: + guestAccess: false \ No newline at end of file diff --git a/rules/os/os_guest_access_smb_disable.yaml b/rules/os/os_guest_access_smb_disable.yaml new file mode 100644 index 00000000..e87b658e --- /dev/null +++ b/rules/os/os_guest_access_smb_disable.yaml @@ -0,0 +1,32 @@ +id: os_guest_access_smb_disable +title: "Disable Guest Access to Shared Server Message Block (SMB) Folders" +discussion: | + Turning off guest access prevents anonymous users from accessing files shared via SMB. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'AllowGuestAccess = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84761-6 + 800-53r4: + - IA-2 + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.smb.server: + AllowGuestAccess: false \ No newline at end of file diff --git a/rules/os/os_guest_account_disable.yaml b/rules/os/os_guest_account_disable.yaml new file mode 100644 index 00000000..41ad8766 --- /dev/null +++ b/rules/os/os_guest_account_disable.yaml @@ -0,0 +1,31 @@ +id: os_guest_account_disable +title: "The macOS system must disable the guest account." +discussion: | + Turning off guest access prevents anonymous users from accessing files. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'DisableGuestAccount = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84762-4 + cci: + - CCI-001813 + 800-53r4: + - CM-5(1) + srg: + - SRG-OS-000364-GPOS-00151 + disa_stig: + - AOSX-14-002063 +macOS: + - "10.15" +tags: + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.MCX: + DisableGuestAccount: true \ No newline at end of file diff --git a/rules/os/os_handoff_disable.yaml b/rules/os/os_handoff_disable.yaml new file mode 100644 index 00000000..506df9d3 --- /dev/null +++ b/rules/os/os_handoff_disable.yaml @@ -0,0 +1,35 @@ +id: os_handoff_disable +title: "Disable Handoff" +discussion: | + Handoff allows you to continue working from one Apple device to another. This feature should be disabled to prevent data transfers to unauthorized devices. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowActivityContinuation = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84763-2 + 800-53r4: + - AC-18(3) + - CM-6(b) + - CM-7(a) + - CM-7(5)(b) + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowActivityContinuation: false diff --git a/rules/os/os_home_folders_secure.yaml b/rules/os/os_home_folders_secure.yaml new file mode 100644 index 00000000..4586a5b3 --- /dev/null +++ b/rules/os/os_home_folders_secure.yaml @@ -0,0 +1,40 @@ +id: os_home_folders_secure +title: "Secure User's Home Folders" +discussion: | + The default behavior of macOS is to allow all valid users into the top level of every other users home folder and restricts access to the Apple default folders within. The system should be configured to prevent access to the top-level folders in other user's home folders. +check: | + /usr/bin/find /System/Volumes/Data/Users -mindepth 1 -maxdepth 1 -type d -perm -1 | grep -v "Shared" | grep -v "Guest" | wc -l | xargs +result: + integer: 0 +fix: | + [source,bash] + ---- + IFS=$'\n' + for userDirs in $( find /System/Volumes/Data/Users -mindepth 1 -maxdepth 1 -type d -perm -1 | grep -v "Shared" | grep -v "Guest" ); do + /bin/chmod og-rwx "$userDirs" + done + unset IFS + ---- +references: + cce: + - CCE-84764-0 + cci: + - CCI-000366 + 800-53r4: + - AC-6 + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00230 + disa_stig: + - AOSX-14-002065 + - AOSX-14-002068 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_httpd_disable.yaml b/rules/os/os_httpd_disable.yaml new file mode 100644 index 00000000..f25e3ed5 --- /dev/null +++ b/rules/os/os_httpd_disable.yaml @@ -0,0 +1,34 @@ +id: os_httpd_disable +title: "The macOS system must be configured to disable httpd." +discussion: + Apache web server is a non-essential service built into macOS and must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"org.apache.httpd" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/org.apache.httpd + ---- +references: + cce: + - CCE-84765-7 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002008 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_icloud_storage_prompt_disable.yaml b/rules/os/os_icloud_storage_prompt_disable.yaml new file mode 100644 index 00000000..cd6a3e01 --- /dev/null +++ b/rules/os/os_icloud_storage_prompt_disable.yaml @@ -0,0 +1,33 @@ +id: os_icloud_storage_prompt_disable +title: "Disable iCloud Storage setup at login" +discussion: | + The prompt for iCloud Storage Setup services must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'SkipiCloudStorageSetup = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84766-5 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002037 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.SetupAssistant.managed: + SkipiCloudStorageSetup: true diff --git a/rules/os/os_internet_accounts_prefpane_disable.yaml b/rules/os/os_internet_accounts_prefpane_disable.yaml new file mode 100644 index 00000000..13a5e335 --- /dev/null +++ b/rules/os/os_internet_accounts_prefpane_disable.yaml @@ -0,0 +1,36 @@ +id: os_internet_accounts_prefpane_disable +title: "The macOS system must be configured to disable the system preference pane for Internet Accounts." +discussion: | + The system preference panel's Internet Accounts must be disabled to prevent the addition of unauthorized internet accounts. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'com.apple.preferences.internetaccounts' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84767-3 + cci: + - CCI-001774 + 800-53r4: + - CM-7(5)(b) + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002032 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.systempreferences: + DisabledPreferencePanes: + - com.apple.preferences.internetaccounts diff --git a/rules/os/os_ir_support_disable.yaml b/rules/os/os_ir_support_disable.yaml new file mode 100644 index 00000000..c637cb07 --- /dev/null +++ b/rules/os/os_ir_support_disable.yaml @@ -0,0 +1,34 @@ +id: os_ir_support_disable +title: "Disable Infrared (IR) support" +discussion: | + IR support must be disabled to prevent users from controlling the system with IR devices. By default, if IR is enabled, the system will accept IR control from any remote device. + Note: This is only appliciable to Mac Mini systems with a model earlier than MacMini8,1. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'DeviceEnabled = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84768-1 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-13-000075 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.driver.AppleIRController: + DeviceEnabled: false \ No newline at end of file diff --git a/rules/os/os_mail_app_disable.yaml b/rules/os/os_mail_app_disable.yaml new file mode 100644 index 00000000..2f2c999e --- /dev/null +++ b/rules/os/os_mail_app_disable.yaml @@ -0,0 +1,38 @@ +id: os_mail_app_disable +title: "Disable Mail App" +discussion: | + The macOS built-in Mail.app contains functionality that can establish connections to Apple's iCloud, despite using security controls to disable iCloud access. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -A 20 familyControlsEnabled | /usr/bin/grep -c "/Applications/Mail.app" +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84769-9 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002019 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess.new: + familyControlsEnabled: true + pathBlackList: + - /Applications/Mail.app diff --git a/rules/os/os_messages_app_disable.yaml b/rules/os/os_messages_app_disable.yaml new file mode 100644 index 00000000..6a3cd384 --- /dev/null +++ b/rules/os/os_messages_app_disable.yaml @@ -0,0 +1,38 @@ +id: os_messages_app_disable +title: "Disable Messages App" +discussion: | + The macOS built-in Messages.app establishes a connection to Apple's iCloud service, despite using security controls to disable iCloud access. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -A 20 familyControlsEnabled | /usr/bin/grep -c "/Applications/Messages.app" +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84770-7 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002011 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess.new: + familyControlsEnabled: true + pathBlackList: + - /Applications/Messages.app diff --git a/rules/os/os_nfsd_disable.yaml b/rules/os/os_nfsd_disable.yaml new file mode 100644 index 00000000..1a07cffb --- /dev/null +++ b/rules/os/os_nfsd_disable.yaml @@ -0,0 +1,35 @@ +id: os_nfsd_disable +title: "Disable Network File System (NFS) service" +discussion: | + If the system does not require access to NFS file shares or is not acting as an NFS server, support for NFS is non-essential and NFS services must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.nfsd" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/com.apple.nfsd + ---- + The system may need to be restarted for the update to take effect. +references: + cce: + - CCE-84772-3 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002003 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_parental_controls_enable.yaml b/rules/os/os_parental_controls_enable.yaml new file mode 100644 index 00000000..70e991d2 --- /dev/null +++ b/rules/os/os_parental_controls_enable.yaml @@ -0,0 +1,29 @@ +id: os_parental_controls_enable +title: "Enable Parental Controls" +discussion: | + Parental Control on macOS consists of many different payloads which are set individually depending on the type of control required. Enabling parental contols allows for further configuration of these restrictions. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'familyControlsEnabled = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84773-1 + cci: + - CCI-001812 + 800-53r4: + - CM-11(2) + srg: + - SRG-OS-000362-GPOS-00149 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess.new: + familyControlsEnabled: true diff --git a/rules/os/os_password_autofill_disable.yaml b/rules/os/os_password_autofill_disable.yaml new file mode 100644 index 00000000..154c81cf --- /dev/null +++ b/rules/os/os_password_autofill_disable.yaml @@ -0,0 +1,33 @@ +id: os_password_autofill_disable +title: "Disable Password Autofill" +discussion: | + macOS allows users to save passwords and use the AutoFill passwords feature in Safari and compatible apps. This feature shall be disabled to prevent users from being prompted to save passwords in applications. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowPasswordAutoFill = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84774-9 + 800-53r4: + - CM-6(a) + - CM-6(b) + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowPasswordAutoFill: false diff --git a/rules/os/os_password_proximity_disable.yaml b/rules/os/os_password_proximity_disable.yaml new file mode 100644 index 00000000..2381bfd7 --- /dev/null +++ b/rules/os/os_password_proximity_disable.yaml @@ -0,0 +1,36 @@ +id: os_password_proximity_disable +title: "Disable Proximity Based Password Sharing Requests" +discussion: | + macOS can request passwords from other known devices (macOS and iOS). This feature shall be disabled to prevent passwords from being shared. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowPasswordProximityRequests = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84775-6 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowPasswordProximityRequests: false diff --git a/rules/os/os_password_sharing_disable.yaml b/rules/os/os_password_sharing_disable.yaml new file mode 100644 index 00000000..4fecc20f --- /dev/null +++ b/rules/os/os_password_sharing_disable.yaml @@ -0,0 +1,35 @@ +id: os_password_sharing_disable +title: "Disable Password Sharing" +discussion: | + macOS allows you to share a password over Airdrop between other macOS and iOS devices. This feature shall be disabled to prevent passwords from being shared. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowPasswordSharing = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84776-4 + 800-53r4: + - CM-7(a) + - CM-7(5)(b) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowPasswordSharing: false diff --git a/rules/os/os_policy_banner_loginwindow_enforce.yaml b/rules/os/os_policy_banner_loginwindow_enforce.yaml new file mode 100644 index 00000000..ca4774c9 --- /dev/null +++ b/rules/os/os_policy_banner_loginwindow_enforce.yaml @@ -0,0 +1,59 @@ +id: os_policy_banner_loginwindow_enforce +title: "Display policy banner at login window" +discussion: | + Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance. + + System use notifications are required only for access via logon interfaces with human users and are not required when such human interfaces do not exist. + + The policy banner will show if a "PolicyBanner.rtf" or "PolicyBanner.rtfd" exists in the "/Library/Security" folder. + NOTE: + The banner text of the document MUST read: + + "You are accessing a U.S. Government information system, which includes: 1) this computer, 2) this computer network, 3) all Government-furnished computers connected to this network, and 4) all Government-furnished devices and storage media attached to this network or to a computer on this network. You understand and consent to the following: you may access this information system for authorized use only; unauthorized use of the system is prohibited and subject to criminal and civil penalties; you have no reasonable expectation of privacy regarding any communication or data transiting or stored on this information system at any time and for any lawful Government purpose, the Government may monitor, intercept, audit, and search and seize any communication or data transiting or stored on this information system; and any communications or data transiting or stored on this information system may be disclosed or used for any lawful Government purpose. This information system may contain Controlled Unclassified Information (CUI) that is subject to safeguarding or dissemination controls in accordance with law, regulation, or Government-wide policy. Accessing and using this system indicates your understanding of this warning." + +check: | + /bin/ls -ld /Library/Security/PolicyBanner.rtf* | /usr/bin/wc -l | tr -d ' ' +result: + integer: 1 +fix: | + [source,bash] + ---- + bannerText="You are accessing a U.S. Government information system, which includes: 1) this computer, 2) this computer network, 3) all Government-furnished computers connected to this network, and 4) all Government-furnished devices and storage media attached to this network or to a computer on this network. You understand and consent to the following: you may access this information system for authorized use only; unauthorized use of the system is prohibited and subject to criminal and civil penalties; you have no reasonable expectation of privacy regarding any communication or data transiting or stored on this information system at any time and for any lawful Government purpose, the Government may monitor, intercept, audit, and search and seize any communication or data transiting or stored on this information system; and any communications or data transiting or stored on this information system may be disclosed or used for any lawful Government purpose. This information system may contain Controlled Unclassified Information (CUI) that is subject to safeguarding or dissemination controls in accordance with law, regulation, or Government-wide policy. Accessing and using this system indicates your understanding of this warning." + /bin/mkdir /Library/Security/PolicyBanner.rtf + /usr/bin/textutil -convert rtf -output /Library/Security/PolicyBanner.rtf/TXT.rtf -stdin < /etc/banner + ---- +references: + cce: + - CCE-84778-0 + cci: + - CCI-000048 + 800-53r4: + - AC-8(a) + srg: + - SRG-OS-000023-GPOS-00006 + disa_stig: + - AOSX-14-000023 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_policy_banner_ssh_enforce.yaml b/rules/os/os_policy_banner_ssh_enforce.yaml new file mode 100644 index 00000000..f1f30085 --- /dev/null +++ b/rules/os/os_policy_banner_ssh_enforce.yaml @@ -0,0 +1,42 @@ +id: os_policy_banner_ssh_enforce +title: "Enforce SSH policy banner" +discussion: | + Display of a standardized and approved use notification before granting access to the operating system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance. + + System use notifications are required only for access via logon interfaces with human users and are not required when such human interfaces do not exist. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^Banner /etc/banner" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/^[\#]*Banner.*/Banner \/etc\/banner/' /etc/ssh/sshd_config + ---- +references: + cce: + - CCE-84779-8 + cci: + - CCI-000048 + - CCI-000050 + 800-53r4: + - AC-8(a) + - AC-8(b) + srg: + - SRG-OS-000023-GPOS-00006 + - SRG-OS-000024-GPOS-00007 + disa_stig: + - AOSX-14-000024 +macOS: + - "10.15" + - "10.14" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_power_nap_disable.yaml b/rules/os/os_power_nap_disable.yaml new file mode 100644 index 00000000..24741870 --- /dev/null +++ b/rules/os/os_power_nap_disable.yaml @@ -0,0 +1,42 @@ +id: os_power_nap_disable +title: "Disable Power Nap" +discussion: | + Power Nap allows your Mac to perform actions while a Mac is asleep. This can interfere with USB power and may cause USB readers to stop functioning until a reboot. Power Nap should be disabled on all systems. + + The following Macs support Power Nap: + + * MacBook (Early 2015 and later) + * MacBook Air (Late 2010 and later) + * MacBook Pro (all models with Retina display) + * Mac mini (Late 2012 and later) + * iMac (Late 2012 and later) + * Mac Pro (Late 2013 and later) +check: | + /usr/bin/pmset -g custom | awk '/powernap/ { sum+=$2 } END {print sum}' +result: + integer: 0 +fix: | + [source,bash] + ---- + /usr/bin/pmset -a powernap 0 + ---- +references: + cce: + - CCE-84780-6 + 800-53r4: + - CM-6(b) + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_privacy_setup_prompt_disable.yaml b/rules/os/os_privacy_setup_prompt_disable.yaml new file mode 100644 index 00000000..1ee6133f --- /dev/null +++ b/rules/os/os_privacy_setup_prompt_disable.yaml @@ -0,0 +1,35 @@ +id: os_privacy_setup_prompt_disable +title: "Disable the Privacy Setup services at login" +discussion: | + The prompt for Privacy Setup services must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'SkipPrivacySetup = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84781-4 + cci: + - CCI-000381 + 800-53r4: + - CM-6(b) + - CM-7(a) + srg: + - SRG-OS-000480-GPOS-00227 + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002036 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.SetupAssistant.managed: + SkipPrivacySetup: true \ No newline at end of file diff --git a/rules/os/os_removable_media_disable.yaml b/rules/os/os_removable_media_disable.yaml new file mode 100644 index 00000000..48b156fc --- /dev/null +++ b/rules/os/os_removable_media_disable.yaml @@ -0,0 +1,35 @@ +id: os_removable_media_disable +title: "Disable removable USB storage devices" +discussion: | + External hard drives, such as USB, must be disabled for users. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep 'harddisk-external' -A3 | grep -Ec "eject|alert" +result: + integer: 2 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84782-2 + cci: + - N/A + 800-53r4: + - MP-7(1) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.systemuiserver: + mount-controls: + harddisk-external: + - alert + - eject + diff --git a/rules/os/os_root_disable.yaml b/rules/os/os_root_disable.yaml new file mode 100644 index 00000000..79ede848 --- /dev/null +++ b/rules/os/os_root_disable.yaml @@ -0,0 +1,33 @@ +id: os_root_disable +title: "Disable Root login" +discussion: | + The macOS system must require individuals to be authenticated with an individual authenticator prior to using a group authenticator. Administrator users must never log in directlty as root. To assure individual accountability and prevent unauthorized access, logging in as root at the login window must be disabled. +check: | + /usr/bin/dscl . -read /Users/root UserShell 2>&1 | /usr/bin/grep -c "/usr/bin/false" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/dscl . -create /Users/root UserShell /usr/bin/false + ---- +references: + cce: + - CCE-84783-0 + 800-53r4: + - IA-2 + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_root_disable_sshd.yaml b/rules/os/os_root_disable_sshd.yaml new file mode 100644 index 00000000..90d52153 --- /dev/null +++ b/rules/os/os_root_disable_sshd.yaml @@ -0,0 +1,35 @@ +id: os_root_disable_sshd +title: "Disable Root login for remote connections" +discussion: | + The macOS system must require individuals to be authenticated with an individual authenticator prior to using a group authenticator. Administrator users must never log in directlty as root. To assure individual accountability and prevent unauthorized access, logging in as root over a remote connection must be disabled. Administrators shall only run commands as root after first authenticating with their individual accounts. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c '^PermitRootLogin no' /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/^[\#]*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config + ---- +references: + cce: + - CCE-84784-8 + 800-53r4: + - IA-2 + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: diff --git a/rules/os/os_screensaver_ask_for_password_delay_enforce.yaml b/rules/os/os_screensaver_ask_for_password_delay_enforce.yaml new file mode 100644 index 00000000..5e93d54d --- /dev/null +++ b/rules/os/os_screensaver_ask_for_password_delay_enforce.yaml @@ -0,0 +1,33 @@ +id: os_screensaver_ask_for_password_delay_enforce +title: "Enforce session lock no more than 5 seconds after screen saver is started" +discussion: | + A screen saver must be enabled and set to require a password to unlock. An excessive grace period impacts the ability for a session to be truly locked, requiring authentication to unlock. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'askForPasswordDelay = 5' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84785-5 + cci: + - CCI-000056 + 800-53r4: + - AC-11(b) + srg: + - SRG-OS-000028-GPOS-00009 + disa_stig: + - AOSX-14-000003 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.screensaver: + askForPasswordDelay: 5 + diff --git a/rules/os/os_screensaver_loginwindow_enforce.yaml b/rules/os/os_screensaver_loginwindow_enforce.yaml new file mode 100644 index 00000000..5ada70ab --- /dev/null +++ b/rules/os/os_screensaver_loginwindow_enforce.yaml @@ -0,0 +1,32 @@ +id: os_screensaver_loginwindow_enforce +title: "Enforce screen saver at login window" +discussion: | + A default screen saver must be configured to display at the login window and must not display any sensitive information. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c loginWindowModulePath +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84786-3 + cci: + - CCI-000060 + 800-53r4: + - AC-11(1) + srg: + - SRG-OS-000031-GPOS-00012 + disa_stig: + - AOSX-14-000006 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.screensaver: + loginWindowModulePath: "/System/Library/Screen Savers/Flurry.saver" diff --git a/rules/os/os_screensaver_password_enforce.yaml b/rules/os/os_screensaver_password_enforce.yaml new file mode 100644 index 00000000..b0fa864a --- /dev/null +++ b/rules/os/os_screensaver_password_enforce.yaml @@ -0,0 +1,32 @@ +id: os_screensaver_password_enforce +title: "Enforce screen saver password" +discussion: | + Users must authenticate when unlocking the screen saver. The screen saver acts as a session lock and prevents unauthorized users from accessing the current user's account. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'askForPassword = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84787-1 + cci: + - CCI-000056 + 800-53r4: + - AC-11(b) + srg: + - SRG-OS-000028-GPOS-00009 + disa_stig: + - AOSX-14-000002 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.screensaver: + askForPassword: true diff --git a/rules/os/os_screensaver_timeout_enforce.yaml b/rules/os/os_screensaver_timeout_enforce.yaml new file mode 100644 index 00000000..bebccfb7 --- /dev/null +++ b/rules/os/os_screensaver_timeout_enforce.yaml @@ -0,0 +1,32 @@ +id: os_screensaver_timeout_enforce +title: "Enforce screen saver time out after 15 minutes of inactivity" +discussion: | + The screen saver timeout should be set to 15 minutes of inactivity. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'idleTime = 900' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84788-9 + cci: + - CCI-000057 + 800-53r4: + - AC-11(a) + srg: + - SRG-OS-000029-GPOS-00010 + disa_stig: + - AOSX-14-000004 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.screensaver: + idleTime: 900 diff --git a/rules/os/os_secure_boot_verify.yaml b/rules/os/os_secure_boot_verify.yaml new file mode 100644 index 00000000..576b1981 --- /dev/null +++ b/rules/os/os_secure_boot_verify.yaml @@ -0,0 +1,30 @@ +id: os_secure_boot_verify +title: "Ensure Secure Boot Level set to Full" +discussion: | + Full security is the default Secure Boot setting in macOS. During startup, the mac will verify the operating system before allowing the operating system to boot. + Note - This will only return a proper result on a T2 Mac +check: | + /usr/sbin/nvram 94b73556-2197-4702-82a8-3e1337dafbfb:AppleSecureBootPolicy | grep -c '%02' +result: + integer: 1 +fix: | + NOTE: Boot into Recovery Mode and enable Full Secure Boot +references: + cce: + - CCE-84789-7 + 800-53r4: + - SI-6(a) + - SI-6(b) + - SI-6(d) + srg: + - SRG-OS-000446-GPOS-00200 + disa_stig: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_siri_prompt_disable.yaml b/rules/os/os_siri_prompt_disable.yaml new file mode 100644 index 00000000..5d96c1d0 --- /dev/null +++ b/rules/os/os_siri_prompt_disable.yaml @@ -0,0 +1,39 @@ +id: os_siri_prompt_disable +title: "Disable Siri Setup at login" +discussion: | + The prompt to setup Siri at login must be disabled, as it might mislead users into enabling Siri. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'SkipSiriSetup = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84791-3 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-6(b) + - CM-7(a) + - CM-5(5)(b) + srg: + - SRG-OS-000480-GPOS-00227 + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002034 + - AOSX-14-002039 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.SetupAssistant.managed: + SkipSiriSetup: true diff --git a/rules/os/os_ssh_client_alive_count_max_configure.yaml b/rules/os/os_ssh_client_alive_count_max_configure.yaml new file mode 100644 index 00000000..08cb353a --- /dev/null +++ b/rules/os/os_ssh_client_alive_count_max_configure.yaml @@ -0,0 +1,35 @@ +id: os_ssh_client_alive_count_max_configure +title: "Configure SSH ClientAliveCountMax option set to 0" +discussion: | + SSH should be configured with an Active Client Alive Maximum Count of 0. Terminating an idle session within a short time period reduces the window of opportunity for unauthorized personnel to take control of a management session enabled on the console or console port that has been left unattended. In addition, quickly terminating an idle session or an incomplete logon attempt will also free up resources committed by the managed network element. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^ClientAliveCountMax 0" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/.*ClientAliveCountMax.*/ClientAliveCountMax 0/' /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84792-1 + cci: + - CCI-001133 + 800-53r4: + - SC-10 + srg: + - SRG-OS-000163-GPOS-00072 + disa_stig: + - AOSX-14-000052 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_ssh_client_alive_interval_configure.yaml b/rules/os/os_ssh_client_alive_interval_configure.yaml new file mode 100644 index 00000000..2cd26995 --- /dev/null +++ b/rules/os/os_ssh_client_alive_interval_configure.yaml @@ -0,0 +1,35 @@ +id: os_ssh_client_alive_interval_configure +title: "Configure SSH ClientAliveInterval option set to 900 or less" +discussion: | + SSH should be configured to log users out after a 15-minute interval or less of inactivity. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^ClientAliveInterval 900" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/.*ClientAliveInterval.*/ClientAliveInterval 900/' /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84793-9 + cci: + - CCI-001133 + 800-53r4: + - SC-10 + srg: + - SRG-OS-000163-GPOS-00072 + disa_stig: + - AOSX-14-000051 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_ssh_fips_140_ciphers.yaml b/rules/os/os_ssh_fips_140_ciphers.yaml new file mode 100644 index 00000000..cc189916 --- /dev/null +++ b/rules/os/os_ssh_fips_140_ciphers.yaml @@ -0,0 +1,38 @@ +id: os_ssh_fips_140_ciphers +title: "Configure SSH to limit the ciphers to algorithims that are FIPS 140 validated" +discussion: | + Unapproved mechanisms that are used for authentication to the cryptographic module are not verified and therefore cannot be relied upon to provide confidentiality or integrity, and system data may be compromised. Operating systems utilizing encryption are required to use FIPS compliant mechanisms for authenticating to cryptographic + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^Ciphers aes256-ctr,aes192-ctr,aes128-ctr" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/grep -q '^Ciphers' /etc/ssh/sshd_config && /usr/bin/sed -i.bak 's/.^Ciphers.*/Ciphers aes256-ctr,aes192-ctr,aes128-ctr/' /etc/ssh/sshd_config || /bin/echo 'Ciphers aes256-ctr,aes192-ctr,aes128-ctr' >> /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84794-7 + cci: + - CCI-001133 + 800-53r4: + - AC-17(2) + - IA-7 + - CM-6(b) + srg: + - SRG-OS-000163-GPOS-00072 + disa_stig: + - AOSX-14-000053 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_ssh_fips_140_macs.yaml b/rules/os/os_ssh_fips_140_macs.yaml new file mode 100644 index 00000000..48ce5334 --- /dev/null +++ b/rules/os/os_ssh_fips_140_macs.yaml @@ -0,0 +1,38 @@ +id: os_ssh_fips_140_macs +title: "Configure SSH to limit the MACs to algorithims that are FIPS 140 validated" +discussion: | + Unapproved mechanisms that are used for authentication to the cryptographic module are not verified and therefore cannot be relied upon to provide confidentiality or integrity, and system data may be compromised. Operating systems utilizing encryption are required to use FIPS compliant mechanisms for authenticating to cryptographic + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^MACs hmac-sha2-256,hmac-sha2-512" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/grep -q '^MACs' /etc/ssh/sshd_config && /usr/bin/sed -i.bak 's/.*MACs.*/MACs hmac-sha2-256,hmac-sha2-512/' /etc/ssh/sshd_config || /bin/echo 'MACs hmac-sha2-256,hmac-sha2-512' >> /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84795-4 + cci: + - CCI-001133 + 800-53r4: + - AC-17(2) + - IA-7 + - CM-6(b) + srg: + - SRG-OS-000163-GPOS-00072 + disa_stig: + - AOSX-14-000053 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_ssh_login_grace_time_configure.yaml b/rules/os/os_ssh_login_grace_time_configure.yaml new file mode 100644 index 00000000..51669f07 --- /dev/null +++ b/rules/os/os_ssh_login_grace_time_configure.yaml @@ -0,0 +1,35 @@ +id: os_ssh_login_grace_time_configure +title: "Configure SSH to LoginGraceTime set to 30 or less" +discussion: | + SSH should be configured to wait only 30 seconds before timing out logon attempts. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^LoginGraceTime 30" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/.*LoginGraceTime.*/LoginGraceTime 30/' /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84796-2 + cci: + - CCI-001133 + 800-53r4: + - SC-10 + srg: + - SRG-OS-000163-GPOS-00072 + disa_stig: + - AOSX-14-000053 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_ssh_max_sessions_configure.yaml b/rules/os/os_ssh_max_sessions_configure.yaml new file mode 100644 index 00000000..edbd1541 --- /dev/null +++ b/rules/os/os_ssh_max_sessions_configure.yaml @@ -0,0 +1,33 @@ +id: os_ssh_max_sessions_configure +title: "Configure SSH to limit the number of concurrent SSH sessions to 10" +discussion: | + The SSH deamon should be configured to allow only 10 concurrent SSH sessions to the system. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "MaxSessions 10" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/sed -i.bak 's/^[\#]*MaxSessions.*/MaxSessions 10/' /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84797-0 + cci: + - CCI-000054 + 800-53r4: + - AC-10 + srg: + - SRG-OS-000027-GPOS-00008 + disa_stig: + - AOSX-14-000050 +macOS: + - "10.15" +tags: + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_ssh_permit_root_login_configure.yaml b/rules/os/os_ssh_permit_root_login_configure.yaml new file mode 100644 index 00000000..979ebf44 --- /dev/null +++ b/rules/os/os_ssh_permit_root_login_configure.yaml @@ -0,0 +1,33 @@ +id: os_ssh_permit_root_login_configure +title: "Configure SSH to not allow root login" +discussion: | + Administrator users must never log in directly as root. To assure individual accountability and prevent unauthorized access, logging in as root over a remote connection must be disabled. Administrators should only run commands as root after first authenticating with their individual user names and passwords. + + NOTE: /etc/ssh/sshd_config will be automatically modified to its original state following any update or major upgrade to the operating system. +check: | + /usr/bin/grep -c "^PermitRootLogin no" /etc/ssh/sshd_config +result: + integer: 1 +fix: | + To ensure that "PermitRootLogin" is set disabled by sshd, run the following command: + [source,bash] + ---- + /usr/bin/sed -i.bak 's/^[\#]*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config; /bin/launchctl kickstart -k system/com.openssh.sshd + ---- +references: + cce: + - CCE-84798-8 + cci: + - CCI-000770 + 800-53r4: + - IA-2(5) + srg: + - SRG-OS-000109-GPOS-00056 + disa_stig: + - AOSX-14-001100 +macOS: + - "10.15" +tags: + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_sudoers_tty_configure.yaml b/rules/os/os_sudoers_tty_configure.yaml new file mode 100644 index 00000000..769633ee --- /dev/null +++ b/rules/os/os_sudoers_tty_configure.yaml @@ -0,0 +1,36 @@ +id: os_sudoers_tty_configure +title: "Configure sudoers to authenticate users on a per -tty basis" +discussion: | + The "sudo" command must be configured to prompt for the administrator's password at least once in each newly opened Terminal window or remote logon session, as this prevents a malicious user from taking advantage of an unlocked computer or an abandoned logon session to bypass the normal password prompt requirement. + + Without the "tty_tickets" option, all open local and remote logon sessions would be authenticated to use sudo without a password for the duration of the configured password timeout window. +check: | + /usr/bin/grep -Ec "^Defaults tty_tickets" /etc/sudoers +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/cp /etc/sudoers /etc/sudoers.bk; /bin/echo "Defaults tty_tickets" >> /etc/sudoers + ---- +references: + cce: + - CCE-84799-6 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-004021 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_system_read_only.yaml b/rules/os/os_system_read_only.yaml new file mode 100644 index 00000000..0bccb01f --- /dev/null +++ b/rules/os/os_system_read_only.yaml @@ -0,0 +1,26 @@ +id: os_system_read_only +title: "Ensure System volune is Read Only" +discussion: | + The System volume should be mounted as read-only in order to assure that configurations critical to the integrity of the macOS has not been compromised. System Integrity Protection will prevent the System volume from being able to be mounted as read write. +check: | + /usr/sbin/system_profiler SPStorageDataType | /usr/bin/grep "Mount Point: /$" -A2 | /usr/bin/awk -F ": " '/Writable/{print $2}' +result: + string: No +fix: | + NOTE: To remount the System volume as Read Only, rebooting the computer will mount it as Read Only. +references: + cce: + - CCE-84851-5 + 800-53r4: + - SC-34 + - SI-7 + srg: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - N/A +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_system_wide_preferences_configure.yaml b/rules/os/os_system_wide_preferences_configure.yaml new file mode 100644 index 00000000..8261b341 --- /dev/null +++ b/rules/os/os_system_wide_preferences_configure.yaml @@ -0,0 +1,36 @@ +id: os_system_wide_preferences_configure +title: "Require an administrator password to access system-wide preferences" +discussion: | + Some Preference Panes in System Preferences contain settings that affect the entire system. Requiring a password to unlock these system-wide settings reduces the risk of a non-authorized user modifying system configurations. +check: | + /usr/bin/security authorizationdb read system.preferences 2> /dev/null | grep -A 1 "shared" | grep -c "" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/security authorizationdb read system.preferences > /tmp/system.preferences.plist + /usr/libexec/PlistBuddy -c "Set :shared false" /tmp/system.preferences.plist + /usr/bin/security authorizationdb write system.preferences < /tmp/system.preferences.plist + ---- +references: + cce: + - CCE-84800-2 + 800-53r4: + - AC-6 + - AC-6(1) + - AC-6(2) + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_tftpd_disable.yaml b/rules/os/os_tftpd_disable.yaml new file mode 100644 index 00000000..d60da288 --- /dev/null +++ b/rules/os/os_tftpd_disable.yaml @@ -0,0 +1,35 @@ +id: os_tftpd_disable +title: "Disable Trvial File Transfer Protocol (TFTP) service" +discussion: | + If the system does not require acting as an TFTP server, support for TFTP is non-essential and TFTP services must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.tftpd" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/com.apple.tftpd + ---- + The system may need to be restarted for the update to take effect. +references: + cce: + - CCE-84853-1 + cci: + - N/A + 800-53r4: + - CM-7(a) + srg: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_time_server_enabled.yaml b/rules/os/os_time_server_enabled.yaml new file mode 100644 index 00000000..450e7660 --- /dev/null +++ b/rules/os/os_time_server_enabled.yaml @@ -0,0 +1,36 @@ +id: os_time_server_enabled +title: "Enable time synchronization daemon (timed)" +discussion: | + The macOS time synchronization daemon(timed) must be enabled for proper time synchronization to an authorized time server. +check: | + /bin/launchctl list | /usr/bin/grep -c com.apple.timed +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl load -w /System/Library/LaunchDaemons/com.apple.timed.plist + ---- +references: + cce: + - CCE-84801-0 + cci: + - CCI-001891 + - CCI-002046 + 800-53r4: + - AU-8(1)(a) + - AU-8(1)(b) + srg: + - SRG-OS-000355-GPOS-00143 + - SRG-OS-000356-GPOS-00144 + disa_stig: + - AOSX-14-000014 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: diff --git a/rules/os/os_touchid_prompt_disable.yaml b/rules/os/os_touchid_prompt_disable.yaml new file mode 100644 index 00000000..99bdd849 --- /dev/null +++ b/rules/os/os_touchid_prompt_disable.yaml @@ -0,0 +1,32 @@ +id: os_touchid_prompt_disable +title: "Disable TouchID prompt during Setup Assistant" +discussion: | + The prompt for TouchID during Setup Assistant must be disabled, as it might mislead users into configuring TouchID for unlock during the initial setup. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'SkipTouchIDSetup = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84802-8 + cci: + - N/A + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.SetupAssistant.managed: + SkipTouchIDSetup: true diff --git a/rules/os/os_uamdm_require.yaml b/rules/os/os_uamdm_require.yaml new file mode 100644 index 00000000..c32ffe9f --- /dev/null +++ b/rules/os/os_uamdm_require.yaml @@ -0,0 +1,33 @@ +id: os_uamdm_require +title: "MDM is User Approved" +discussion: | + User Approved MDM (UAMDM) grants additional privileges to Mobile Device Management software. UAMDM is required to manage certain security settings on a Mac enrolled outside of Device Enrollment via Apple Business Manager (ABM)/Apple School Manager (ASM). Currently these include: + * Whitlisting Approved Kernel Extensions + * Privacy Preferences Policy Control Payload + * ExtensibleSingleSignOn +check: | + /usr/bin/profiles status -type enrollment | awk -F': ' 'END{print $2}' | grep -c "Yes" +result: + integer: 1 +fix: | + Ensure that system is enrolled via UAMDM. +references: + cce: + - CCE-84803-6 + 800-53r4: + - CM-6(b) + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_unlock_active_user_session_disable.yaml b/rules/os/os_unlock_active_user_session_disable.yaml new file mode 100644 index 00000000..6995d72d --- /dev/null +++ b/rules/os/os_unlock_active_user_session_disable.yaml @@ -0,0 +1,36 @@ +id: os_unlock_active_user_session_disable +title: "Disable ability to log into another user's active and locked session" +discussion: | + macOS has a privilege that can be granted to any user that will allow that user to unlock active user's sessions. Disabling the admins and/or user's ability to log into another user's active andlocked session prevents unauthorized persons from viewing potentially sensitive and/or personal information. +check: | + /usr/bin/security authorizationdb read system.login.screensaver 2>&1 | grep -c 'use-login-window-ui' +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/bin/security authorizationdb write system.login.screensaver "use-login-window-ui" + ---- +references: + cce: + - CCE-84804-4 + cci: + - N/A + 800-53r4: + - IA-2 + - IA-2(5) + disa_stig: + - N/A + srg: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/os/os_user_app_installation_prohibit.yaml b/rules/os/os_user_app_installation_prohibit.yaml new file mode 100644 index 00000000..0547a476 --- /dev/null +++ b/rules/os/os_user_app_installation_prohibit.yaml @@ -0,0 +1,31 @@ +id: os_user_app_installation_prohibit +title: "Prohibit user installation of software into /Users/" +discussion: | + Allowing regular users to install software, without explicit privileges, creates the risk that untested or potentially malicious software will be installed on the system. Explicit privileges (escalated or administrative privileges) provide the regular user with explicit capabilities and control that exceeds the rights of a regular user. +check: | + /usr/bin/profiles -P -o stdout-xml | /usr/bin/sed -n '/pathBlackList/,/key/p' | /usr/bin/grep -c "/Users/" +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84805-1 + cci: + - CCI-001812 + 800-53r4: + - CM-11(2) + srg: + - SRG-OS-000362-GPOS-00149 + disa_stig: + - AOSX-14-002067 +macOS: + - "10.15" +tags: + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess.new: + familyControlsEnabled: true + pathBlackList: + - "/Users/" diff --git a/rules/os/os_uucp_disable.yaml b/rules/os/os_uucp_disable.yaml new file mode 100644 index 00000000..9eac6cda --- /dev/null +++ b/rules/os/os_uucp_disable.yaml @@ -0,0 +1,36 @@ +id: os_uucp_disable +title: "Disable the Unix-to-Unix Copy Protocol (UUCP) service" +discussion: | + The system must not have the UUCP service active. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.uucp" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/com.apple.uucp + ---- + The system may need to be restarted for the update to take effect. +references: + cce: + - CCE-84806-9 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + - CM-7(b) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002006 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/permanent/audit_alert_processing_fail.yaml b/rules/permanent/audit_alert_processing_fail.yaml new file mode 100644 index 00000000..b19f122a --- /dev/null +++ b/rules/permanent/audit_alert_processing_fail.yaml @@ -0,0 +1,30 @@ +id: audit_alert_processing_fail +title: "Alert in the event of an audit processing failure" +discussion: | + It is critical for the appropriate personnel to be aware if a system is at risk of failing to process audit logs as required. Without this notification, the security personnel may be unaware of an impending failure of the audit capability, and system operation may be adversely affected.Audit processing failures include software/hardware errors, failures in the audit capturing mechanisms, and audit storage capacity being reached or exceeded.This requirement applies to each audit data storage repository (i.e., distinct information system component where audit records are stored), the centralized audit storage capacity of organizations (i.e., all audit data storage repositories combined), or both. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84908-3 + cci: + - CCI-000139 + 800-53r4: + - AU-5(a) + disa_stig: + - AOSX-15-200004 + srg: + - SRG-OS-000046-GPOS-00022 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/audit_enforce_dual_auth.yaml b/rules/permanent/audit_enforce_dual_auth.yaml new file mode 100644 index 00000000..41d6aa5a --- /dev/null +++ b/rules/permanent/audit_enforce_dual_auth.yaml @@ -0,0 +1,31 @@ +id: audit_enforce_dual_auth +title: "Enforce dual authorization for movement or deletion of audit information" +discussion: | + An authorized user may intentionally or accidentally move or delete audit records without those specific actions being authorized.All bulk manipulation of audit information must be authorized via automatic processes. Any manual manipulation of audit information must require dual authorization. Dual authorization mechanisms require the approval of two authorized individuals to execute. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84906-7 + cci: + - CCI-000366, CCI-001896 + 800-53r4: + - CM-6(b) + - AU-9(5) + disa_stig: + - AOSX-15-200018 + srg: + - SRG-OS-000360-GPOS-00147 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/permanent/audit_off_load_records.yaml b/rules/permanent/audit_off_load_records.yaml new file mode 100644 index 00000000..90fa796c --- /dev/null +++ b/rules/permanent/audit_off_load_records.yaml @@ -0,0 +1,28 @@ +id: audit_off_load_records +title: "Off-load audit records" +discussion: | + Information stored in one location is vulnerable to accidental or incidental deletion or alteration.Off-loading is a common process in information systems with limited audit storage capacity. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84895-2 + cci: + - CCI-001851 + 800-53r4: + - AU-4(1) + disa_stig: + - AOSX-15-200023 + - AOSX-15-200017 + srg: + - SRG-OS-000479-GPOS-00224 + - SRG-OS-000342-GPOS-00133 +macOS: + - "10.15" +tags: + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_enforce_login_attempt_delay.yaml b/rules/permanent/os_enforce_login_attempt_delay.yaml new file mode 100644 index 00000000..b048f61a --- /dev/null +++ b/rules/permanent/os_enforce_login_attempt_delay.yaml @@ -0,0 +1,30 @@ +id: os_enforce_login_attempt_delay +title: "Enforce deal of 4 second delay between login attempts" +discussion: | + Limiting the number of logon attempts over a certain time interval reduces the chances that an unauthorized user may gain access to an account. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84907-5 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + disa_stig: + - AOSX-15-200025 + srg: + - SRG-OS-000480-GPOS-00226 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_limit_dos_attacks.yaml b/rules/permanent/os_limit_dos_attacks.yaml new file mode 100644 index 00000000..6a2726c0 --- /dev/null +++ b/rules/permanent/os_limit_dos_attacks.yaml @@ -0,0 +1,26 @@ +id: os_limit_dos_attacks +title: "Limit effects of Denial of Service (DoS) attacks" +discussion: | + DoS is a condition when a resource is not available for legitimate users. When this occurs, the organization either cannot accomplish its mission or must operate at degraded capacity. Managing excess capacity ensures that sufficient capacity is available to counter flooding attacks. Employing increased capacity and service redundancy may reduce the susceptibility to some DoS attacks. Managing excess capacity may include, for example, establishing selected usage priorities, quotas, or partitioning. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84904-2 + cci: + - CCI-001095 + 800-53r4: + - SC-5(2) + disa_stig: + - AOSX-15-200010 + srg: + - SRG-OS-000142-GPOS-00071 +macOS: + - "10.15" +tags: + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_limit_invalid_logons.yaml b/rules/permanent/os_limit_invalid_logons.yaml new file mode 100644 index 00000000..26e3c467 --- /dev/null +++ b/rules/permanent/os_limit_invalid_logons.yaml @@ -0,0 +1,34 @@ +id: os_limit_invalid_logons +title: "Limit 3 consecutive invalid logon attempts in 15 minutes" +discussion: | + By limiting the number of failed logon attempts, the risk of unauthorized system access via user password guessing, otherwise known as brute forcing, is reduced. Limits are imposed by locking the account. Setting a lockout expiration of 15 minutes is an effective deterrent against brute forcing that also makes allowances for legitimate mistakes by users. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84903-4 + cci: + - CCI-000044 + - CCI-002238 + 800-53r4: + - AC-7(a) + - AC-7(b) + disa_stig: + - AOSX-15-200026 + - AOSX-15-200016 + srg: + - SRG-OS-000021-GPOS-00005 + - SRG-OS-000329-GPOS-00128 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/permanent/os_notify_account_created.yaml b/rules/permanent/os_notify_account_created.yaml new file mode 100644 index 00000000..f144628a --- /dev/null +++ b/rules/permanent/os_notify_account_created.yaml @@ -0,0 +1,29 @@ +id: os_notify_account_created +title: "Notify of account created actions" +discussion: | + Once an attacker establishes initial access to a system, the attacker often attempts to create a persistent method of reestablishing access. One way to accomplish this is for the attacker to simply create a new account. Notification of account creation is one method for mitigating this risk. A comprehensive account management process will ensure an audit trail, which documents the creation of operating system user accounts and notifies System Administrators and ISSOs that it exists. Such a process greatly reduces the risk that accounts will be surreptitiously created and provides logging that can be used for forensic purposes.To address access requirements, many operating systems can be integrated with enterprise-level authentication_access/auditing mechanisms that meet or exceed access control policy requirements. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84900-0 + cci: + - CCI-001683 + 800-53r4: + - AC-2(4) + disa_stig: + - AOSX-15-200011 + srg: + - SRG-OS-000274-GPOS-00104 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_notify_account_disabled.yaml b/rules/permanent/os_notify_account_disabled.yaml new file mode 100644 index 00000000..0f1e3ae9 --- /dev/null +++ b/rules/permanent/os_notify_account_disabled.yaml @@ -0,0 +1,29 @@ +id: os_notify_account_disabled +title: "Notify of account disabling actions" +discussion: | + When operating system accounts are disabled, user accessibility is affected. Accounts are utilized for identifying individual operating system users or for identifying the operating system processes themselves.To detect and respond to events that affect user accessibility and system processing, operating systems must audit account disabling actions and, as required, notify System Administrators and ISSOs so they can investigate the event. Such a capability greatly reduces the risk that operating system accessibility will be negatively affected for extended periods of time and also provides logging that can be used for forensic purposes.To address access requirements, many operating systems can be integrated with enterprise-level authentication_access/auditing mechanisms that meet or exceed access control policy requirements. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84905-9 + cci: + - CCI-001685 + 800-53r4: + - AC-2(4) + disa_stig: + - AOSX-15-200013 + srg: + - SRG-OS-000276-GPOS-00106 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_notify_account_enable.yaml b/rules/permanent/os_notify_account_enable.yaml new file mode 100644 index 00000000..7ca9fd6f --- /dev/null +++ b/rules/permanent/os_notify_account_enable.yaml @@ -0,0 +1,29 @@ +id: os_notify_account_enable +title: "Notify of account enabling actions" +discussion: | + Once an attacker establishes initial access to a system, the attacker often attempts to create a persistent method of reestablishing access. One way to accomplish this is for the attacker to simply enable a new or disabled account. Notification of account enabling is one method for mitigating this risk. A comprehensive account management process will ensure an audit trail, which documents the creation of operating system user accounts and notifies System Administrators and ISSOs that it exists. Such a process greatly reduces the risk that accounts will be surreptitiously enabled and provides logging that can be used for forensic purposes. To detect and respond to events that affect user accessibility and application processing, operating systems must audit account enabling actions and, as required, notify the appropriate individuals so they can investigate the event. To address access requirements, many operating systems can be integrated with enterprise-level authentication_access/auditing mechanisms that meet or exceed access control policy requirements. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84897-8 + cci: + - CCI-002132 + 800-53r4: + - AC-2(4) + disa_stig: + - AOSX-15-200015 + srg: + - SRG-OS-000304-GPOS-00121 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_notify_account_modified.yaml b/rules/permanent/os_notify_account_modified.yaml new file mode 100644 index 00000000..d34a9058 --- /dev/null +++ b/rules/permanent/os_notify_account_modified.yaml @@ -0,0 +1,29 @@ +id: os_notify_account_modified +title: "Notify of account modified actions" +discussion: | + Once an attacker establishes initial access to a system, the attacker often attempts to create a persistent method of reestablishing access. One way to accomplish this is for the attacker to simply modify an existing account. Notification of account modification is one method for mitigating this risk. A comprehensive account management process will ensure an audit trail, which documents the creation of operating system user accounts and notifies System Administrators and ISSOs that it exists. Such a process greatly reduces the risk that accounts will be surreptitiously created and provides logging that can be used for forensic purposes.To address access requirements, many operating systems can be integrated with enterprise-level authentication_access/auditing mechanisms that meet or exceed access control policy requirements. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84901-8 + cci: + - CCI-001684 + 800-53r4: + - AC-2(4) + disa_stig: + - AOSX-15-200012 + srg: + - SRG-OS-000275-GPOS-00105 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_notify_account_removal.yaml b/rules/permanent/os_notify_account_removal.yaml new file mode 100644 index 00000000..d75fdea6 --- /dev/null +++ b/rules/permanent/os_notify_account_removal.yaml @@ -0,0 +1,30 @@ +id: os_notify_account_removal +title: "Notify of account removal actions" +title: "The macOS system must notify system administrators and Information System Security Officers (ISSOs) when accounts are removed." +discussion: | + When operating system accounts are removed, user accessibility is affected. Accounts are utilized for identifying individual operating system users or for identifying the operating system processes themselves.To detect and respond to events that affect user accessibility and system processing, operating systems must audit account removal actions and, as required, notify System Administrators and ISSOs so they can investigate the event. Such a capability greatly reduces the risk that operating system accessibility will be negatively affected for extended periods of time and also provides logging that can be used for forensic purposes.To address access requirements, many operating systems can be integrated with enterprise-level authentication_access/auditing mechanisms that meet or exceed access control policy requirements. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84902-6 + cci: + - CCI-001686 + 800-53r4: + - AC-2(4) + disa_stig: + - AOSX-15-200014 + srg: + - SRG-OS-000277-GPOS-00107 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_notify_unauthorized_baseline_change.yaml b/rules/permanent/os_notify_unauthorized_baseline_change.yaml new file mode 100644 index 00000000..d4eded48 --- /dev/null +++ b/rules/permanent/os_notify_unauthorized_baseline_change.yaml @@ -0,0 +1,27 @@ +id: os_notify_unauthorized_baseline_change +title: "The macOS system must notify designated personnel if baseline configurations are changed in an unauthorized manner." +title: "Notify if baseline configurations changed in unauthorized manner" +discussion: | + Unauthorized changes to the baseline configuration could make the system vulnerable to various attacks or allow unauthorized access to the operating system. Changes to operating system configurations can have unintended side effects, some of which may be relevant to security.Detecting such changes and providing an automated response can help avoid unintended, negative consequences that could ultimately affect the security state of the operating system. The operating system's IMO/ISSO and SAs must be notified via email and/or monitoring system trap when there is an unauthorized modification of a configuration item. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84911-7 + cci: + - CCI-001744 + 800-53r4: + - CM-3(5) + disa_stig: + - AOSX-15-200019 + srg: + - SRG-OS-000363-GPOS-00150 +macOS: + - "10.15" +tags: + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_protect_dos_attacks.yaml b/rules/permanent/os_protect_dos_attacks.yaml new file mode 100644 index 00000000..01f63ca1 --- /dev/null +++ b/rules/permanent/os_protect_dos_attacks.yaml @@ -0,0 +1,30 @@ +id: os_protect_dos_attacks +title: "Protect or limit effects of Denial of Service (DoS) attacks by ensuring rate-limiting measures on network interfaces" +discussion: | + DoS is a condition when a resource is not available for legitimate users. When this occurs, the organization either cannot accomplish its mission or must operate at degraded capacity.This requirement addresses the configuration of the operating system to mitigate the impact of DoS attacks that have occurred or are ongoing on system availability. For each system, known and potential DoS attacks must be identified and solutions for each type implemented. A variety of technologies exist to limit or, in some cases, eliminate the effects of DoS attacks (e.g., limiting processes or establishing memory partitions). Employing increased capacity and bandwidth, combined with service redundancy, may reduce the susceptibility to some DoS attacks. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84909-1 + cci: + - CCI-002385 + 800-53r4: + - SC-5 + disa_stig: + - AOSX-15-200022 + srg: + - SRG-OS-000420-GPOS-00186 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_provide_automated_account_management.yaml b/rules/permanent/os_provide_automated_account_management.yaml new file mode 100644 index 00000000..f93ed2a7 --- /dev/null +++ b/rules/permanent/os_provide_automated_account_management.yaml @@ -0,0 +1,29 @@ +id: os_provide_automated_account_management +title: "Provide automated mechanisms for account management functions" +discussion: | + The organization employs automated mechanisms to support the management of information system accounts. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84899-4 + cci: + - CCI-000015 + 800-53r4: + - AC-2(1) + disa_stig: + - AOSX-15-200001 + srg: + - SRG-OS-000001-GPOS-00001 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/os_reauth_devices_change_authenticators.yaml b/rules/permanent/os_reauth_devices_change_authenticators.yaml new file mode 100644 index 00000000..c8dfe1b7 --- /dev/null +++ b/rules/permanent/os_reauth_devices_change_authenticators.yaml @@ -0,0 +1,26 @@ +id: os_reauth_devices_change_authenticators +title: "Require devices to reauthenticate when changing authenticators" +discussion: | + Without reauthentication, devices may access resources or perform tasks for which they do not have authorization. When operating systems provide the capability to change device authenticators, it is critical the device reauthenticate. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84896-0 + cci: + - CCI-002039 + 800-53r4: + - IA-11 + disa_stig: + - AOSX-15-200020 + srg: + - SRG-OS-000374-GPOS-00159 +macOS: + - "10.15" +tags: + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/pwpolicy_50_percent.yaml b/rules/permanent/pwpolicy_50_percent.yaml new file mode 100644 index 00000000..5d39fa59 --- /dev/null +++ b/rules/permanent/pwpolicy_50_percent.yaml @@ -0,0 +1,30 @@ +id: pwpolicy_50_percent +title: "Require at least 50% of the total number of characters changed when password is changed" +discussion: | + If the operating system allows the user to consecutively reuse extensive portions of passwords, this increases the chances of password compromise by increasing the window of opportunity for attempts at guessing and brute-force attacks.The number of changed characters refers to the number of changes required with respect to the total number of positions in the current password. In other words, characters may be the same within the two passwords; however, the positions of the like characters must be different. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84898-6 + cci: + - CCI-000195 + 800-53r4: + - IA-5(1)(b) + disa_stig: + - AOSX-15-200007 + srg: + - SRG-OS-000072-GPOS-00040 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/pwpolicy_prevent_dictionary_words.yaml b/rules/permanent/pwpolicy_prevent_dictionary_words.yaml new file mode 100644 index 00000000..8b64a59f --- /dev/null +++ b/rules/permanent/pwpolicy_prevent_dictionary_words.yaml @@ -0,0 +1,30 @@ +id: pwpolicy_prevent_dictionary_words +title: "Prevent the use of dictionary words for passwords" +discussion: | + If the operating system allows the user to select passwords based on dictionary words, then this increases the chances of password compromise by increasing the opportunity for successful guesses and brute-force attacks. +check: | + For systems not requiring mandatory smart card authentication or those that are not bound to a directory, the technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84910-9 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + disa_stig: + - AOSX-15-200024 + srg: + - SRG-OS-000480-GPOS-00225 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG + - permanent +mobileconfig: false +mobileconfig_info: diff --git a/rules/permanent/sysprefs_wifi_disable.yaml b/rules/permanent/sysprefs_wifi_disable.yaml new file mode 100644 index 00000000..e5a75299 --- /dev/null +++ b/rules/permanent/sysprefs_wifi_disable.yaml @@ -0,0 +1,37 @@ +id: sysprefs_wifi_disable +title: "Disable Wi-Fi when connected to ethernet" +discussion: | + Use of Wi-Fi to connect to unauthorized networks may facilitate the exfiltration of mission data. The organization disables, when not intended for use, wireless networking capabilities internally embedded within information system components prior to issuance and deployment. + + NOTE: If the system requires Wi-Fi to connect to an authorized network, this is not applicable. +check: | + The technology does not support this requirement. This is an applicable-does not meet finding. +fix: | + This requirement is a permanent finding and cannot be fixed. An appropriate mitigation for the system must be implemented, but this finding cannot be considered fixed. +references: + cce: + - CCE-84850-7 + cci: + - CCI-001967 + - CCI-001443 + - CCI-001444 + 800-53r4: + - AC-18(1) + - AC-18(3) + disa_stig: + - AOSX-14-004020 + - AOSX-14-000008 + srg: + - SRG-OS-000300-GPOS-00118 + - SRG-OS-000300-GPOS-00117 + - SRG-OS-000480-GPOS-00227 + - SRG-OS-000379-GPOS-00164 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/pwpolicy/pwpolicy_60_day_enforce.yaml b/rules/pwpolicy/pwpolicy_60_day_enforce.yaml new file mode 100644 index 00000000..b1af00c3 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_60_day_enforce.yaml @@ -0,0 +1,33 @@ +id: pwpolicy_60_day_enforce +title: "Enforce a 60-day maximum password lifetime restriction" +discussion: | + The macOS must limit the lifetime of a password to a maxiumum of at least 60 days and force users to change their passwords. +check: | + /usr/bin/profiles -P -o stdout | awk -F " = " '/maxPINAgeInDays/{sub(/;.*/,"");print $2}' +result: + integer: 60 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84807-7 + cci: + - CCI-000199 + 800-53r4: + - IA-5(1)(d) + srg: + - SRG-OS-000076-GPOS-00044 + disa_stig: + - AOSX-14-003008 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + maxPINAgeInDays: 60 diff --git a/rules/pwpolicy/pwpolicy_account_inactivity_enforce.yaml b/rules/pwpolicy/pwpolicy_account_inactivity_enforce.yaml new file mode 100644 index 00000000..025f9f50 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_account_inactivity_enforce.yaml @@ -0,0 +1,54 @@ +id: pwpolicy_account_inactivity_enforce +title: "Disable accounts after 35 days of inactivity" +discussion: | + The macOS must disable accounts after 35 days of inactivity. +check: | + /usr/bin/pwpolicy getaccountpolicies | /usr/bin/grep -v "Getting global account policies" | /usr/bin/xmllint --xpath '/plist/dict/array/dict/dict[key="policyAttributeInactiveDays"]/integer' - | /usr/bin/awk -F '[<>]' '{print $3}' +result: + integer: 35 +fix: | + This setting may be enforced using local policy or by a directory service. + + To set local policy to disable an inactive user after 35 days, edit the current password policy to contiain the followind within the "policyCategoryAuthentication": + + [source,xml] + ---- + + policyContent + policyAttributeLastAuthenticationTime > policyAttributeCurrentTime - (policyAttributeInactiveDays * 24 * 60 * 60) + policyIdentifier + Inactive Account + policyParameters + + policyAttributeInactiveDays + 35 + + + ---- + After saving the file and exiting to the command prompt, run the following command to load the new policy file, substituting the path to the file in place of "/path/to/file". + + [source,bash] + ---- + /usr/bin/pwpolicy setaccountpolicies /path/to/file + ---- + NOTE: See pwpolicy_supplemental on more information on how to implement password policies on macOS. +references: + cce: + - CCE-84808-5 + cci: + - CCI-000795 + 800-53r4: + - IA-4(e) + srg: + - SRG-OS-000118-GPOS-00060 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/pwpolicy/pwpolicy_account_lockout_enforce.yaml b/rules/pwpolicy/pwpolicy_account_lockout_enforce.yaml new file mode 100644 index 00000000..af076558 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_account_lockout_enforce.yaml @@ -0,0 +1,37 @@ +id: pwpolicy_account_lockout_enforce +title: "Enforce a limit of 3 consecutive failed logon attempts" +discussion: | + The macOS must limit the number of failed attempts to a maximum of 3 attempts. The account must be locked for a period of time after the maximum failed attempts. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'maxFailedAttempts = 3' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84809-3 + cci: + - CCI-000044 + - CCI-002238 + 800-53r4: + - AC-7(a) + - AC-7(b) + srg: + - SRG-OS-000021-GPOS-00005 + - SRG-OS-000329-GPOS-00128 + disa_stig: + - AOSX-14-000020 + - AOSX-14-000022 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + maxFailedAttempts: 3 diff --git a/rules/pwpolicy/pwpolicy_account_lockout_timeout_enforce.yaml b/rules/pwpolicy/pwpolicy_account_lockout_timeout_enforce.yaml new file mode 100644 index 00000000..dc3d1484 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_account_lockout_timeout_enforce.yaml @@ -0,0 +1,33 @@ +id: pwpolicy_account_lockout_timeout_enforce +title: "Enforce account lockout time period of 15 minutes after the maximum failed logon attempts" +discussion: | + macOS must enforce a lockout time period of at least 15 minutes after the maxium failed logon attempts. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'minutesUntilFailedLoginReset = 15' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84810-1 + cci: + - CCI-002238 + 800-53r4: + - AC-7(b) + srg: + - SRG-OS-000329-GPOS-00128 + disa_stig: + - AOSX-14-000021 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + minutesUntilFailedLoginReset: 15 diff --git a/rules/pwpolicy/pwpolicy_alpha_numeric_enforce.yaml b/rules/pwpolicy/pwpolicy_alpha_numeric_enforce.yaml new file mode 100644 index 00000000..8bcd4b2b --- /dev/null +++ b/rules/pwpolicy/pwpolicy_alpha_numeric_enforce.yaml @@ -0,0 +1,33 @@ +id: pwpolicy_alpha_numeric_enforce +title: "Enforce password complexity by requiring that at least 1 numeric character be used" +discussion: | + macOS must require at least 1 numeric character be used when creating a password. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c "requireAlphanumeric = 1;" +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84811-9 + cci: + - CCI-000194 + 800-53r4: + - IA-5(1)(a) + srg: + - SRG-OS-000071-GPOS-00039 + disa_stig: + - AOSX-14-003007 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + requireAlphanumeric: true diff --git a/rules/pwpolicy/pwpolicy_history_enforce.yaml b/rules/pwpolicy/pwpolicy_history_enforce.yaml new file mode 100644 index 00000000..f27f8938 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_history_enforce.yaml @@ -0,0 +1,34 @@ +id: pwpolicy_history_enforce +title: "Prohibit password reuse a minimum of 5 previous passwords" +discussion: | + macOS must be configured to enforce a password history of at a minimum 5 previous passwords. It must not allow re-use of those 5 previous generations of passwords. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/awk '/pinHistory/{sub(/;.*/,"");print $3}' +result: + integer: 5 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84814-3 + cci: + - CCI-000200 + 800-53r4: + - IA-5(1)(e) + - IA-5(e) + srg: + - SRG-OS-000077-GPOS-00045 + disa_stig: + - AOSX-14-003009 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + pinHistory: 5 diff --git a/rules/pwpolicy/pwpolicy_lower_case_character_enforce.yaml b/rules/pwpolicy/pwpolicy_lower_case_character_enforce.yaml new file mode 100644 index 00000000..34d18364 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_lower_case_character_enforce.yaml @@ -0,0 +1,55 @@ +id: pwpolicy_lower_case_character_enforce +title: "Enforce password complexity by requiring that at least 1 lower-case character be used" +discussion: | + macOS must require at least 1 lower-case character be used when creating a password. +check: | + /usr/bin/pwpolicy getaccountpolicies | /usr/bin/grep -v "Getting global account policies" | /usr/bin/xmllint --xpath '/plist/dict/array/dict/dict[key="minimumAlphaCharactersLowerCase"]/integer' - | /usr/bin/awk -F '[<>]' '{print $3}' +result: + integer: 1 +fix: | + This setting may be enforced using local policy or by a directory service. + + To set local policy to require at least 1 lowercase letter, edit the current password policy to contiain the following within the "policyCategoryPasswordContent": + + [source,xml] + ---- + + policyContent + policyAttributePassword matches '(.*[a-z].*){1,}+' + policyIdentifier + Must have at least 1 lowercase letter + policyParameters + + minimumAlphaCharactersLowerCase + 1 + + + ---- + After saving the file and exiting to the command prompt, run the following command to load the new policy file, substituting the path to the file in place of "/path/to/file". + + [source,bash] + ---- + /usr/bin/pwpolicy setaccountpolicies /path/to/file + ---- + NOTE: See pwpolicy_supplemental on more information on how to implement password policies on macOS. +references: + cce: + - CCE-84815-0 + cci: + - CCI-000193 + 800-53r4: + - IA-5(1)(a) + disa_stig: + - N/A + srg: + - SRG-OS-000070-GPOS-00038 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/pwpolicy/pwpolicy_minimum_length_enforce.yaml b/rules/pwpolicy/pwpolicy_minimum_length_enforce.yaml new file mode 100644 index 00000000..13285dbb --- /dev/null +++ b/rules/pwpolicy/pwpolicy_minimum_length_enforce.yaml @@ -0,0 +1,33 @@ +id: pwpolicy_minimum_length_enforce +title: "Enforce a minimum 15-character password length" +discussion: | + The minimum password length must be set to 15 characters. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'minLength = 15' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84816-8 + cci: + - CCI-000205 + 800-53r4: + - IA-5(1)(a) + srg: + - SRG-OS-000078-GPOS-00046 + disa_stig: + - AOSX-14-003010 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + minLength: 15 diff --git a/rules/pwpolicy/pwpolicy_minimum_lifetime_enforce.yaml b/rules/pwpolicy/pwpolicy_minimum_lifetime_enforce.yaml new file mode 100644 index 00000000..4dc95e4c --- /dev/null +++ b/rules/pwpolicy/pwpolicy_minimum_lifetime_enforce.yaml @@ -0,0 +1,54 @@ +id: pwpolicy_minimum_lifetime_enforce +title: "Enforce 24 hours as the minimum password lifetime" +discussion: | + macOS must enforce a minimum password lifetime limit of 24 hours. +check: | + /usr/bin/pwpolicy getaccountpolicies | /usr/bin/grep -v "Getting global account policies" | /usr/bin/xmllint --xpath '/plist/dict/array/dict/dict[key="policyAttributeMinimumLifetimeHours"]/integer' - | /usr/bin/awk -F '[<>]' '{print $3}' +result: + integer: 24 +fix: | + This setting may be enforced using local policy or by a directory service. + + To set local policy to require a minimum password lifetime, edit the current password policy to contiain the following within the "policyCategoryPasswordContent": + + [source,xml] + ---- + + policyContent + policyAttributeLastPasswordChangeTime < policyAttributeCurrentTime - (policyAttributeMinimumLifetimeHours * 60 * 60) + policyIdentifier + Minimum Password Lifetime + policyParameters + + policyAttributeMinimumLifetimeHours + 24 + + + ---- + After saving the file and exiting to the command prompt, run the following command to load the new policy file, substituting the path to the file in place of "/path/to/file". + + [source,bash] + ---- + /usr/bin/pwpolicy setaccountpolicies /path/to/file + ---- + NOTE: See pwpolicy_supplemental on more information on how to implement password policies on macOS. +references: + cce: + - CCE-84817-6 + cci: + - N/A + 800-53r4: + - IA-5(1)(d) + disa_stig: + - N/A + srg: + - SRG-OS-000075-GPOS-00043 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/pwpolicy/pwpolicy_simple_sequence_disable.yaml b/rules/pwpolicy/pwpolicy_simple_sequence_disable.yaml new file mode 100644 index 00000000..69aabf48 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_simple_sequence_disable.yaml @@ -0,0 +1,32 @@ +id: pwpolicy_simple_sequence_disable +title: "Enforce password complexity by requiring that repeating, ascending, and descending character sequences in passcodes are not used." +discussion: | + The use of repeating, ascending, and descending character sequences in passcodes is not allowed. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowSimple = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84818-4 + cci: + - N/A + 800-53r4: + - IA-5(1)(a) + srg: + - SRG-OS-000266-GPOS-00101 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + allowSimple: false diff --git a/rules/pwpolicy/pwpolicy_special_character_enforce.yaml b/rules/pwpolicy/pwpolicy_special_character_enforce.yaml new file mode 100644 index 00000000..2e9b25f5 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_special_character_enforce.yaml @@ -0,0 +1,33 @@ +id: pwpolicy_special_character_enforce +title: "Enforce password complexity by requiring that at least 1 special character be used" +discussion: | + macOS must require at least 1 special character be used when creating a password. Special characters are those characters that are not alphanumeric. Examples include: ~ ! @ # $ % ^ *. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/awk '/minComplexChars/{sub(/;.*/,"");print $3}' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84819-2 + cci: + - CCI-001619 + 800-53r4: + - IA-5(1)(a) + srg: + - SRG-OS-000266-GPOS-00101 + disa_stig: + - AOSX-14-003011 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.mobiledevice.passwordpolicy: + minComplexChars: 1 diff --git a/rules/pwpolicy/pwpolicy_upper_case_character_enforce.yaml b/rules/pwpolicy/pwpolicy_upper_case_character_enforce.yaml new file mode 100644 index 00000000..490d4be6 --- /dev/null +++ b/rules/pwpolicy/pwpolicy_upper_case_character_enforce.yaml @@ -0,0 +1,48 @@ +id: pwpolicy_upper_case_character_enforce +title: "Enforce password complexity by requiring that at least 1 upper-case character be used" +discussion: | + macOS must require at least 1 upper-case character be used when creating a password. +check: | + /usr/bin/pwpolicy getaccountpolicies | /usr/bin/grep -v "Getting global account policies" | /usr/bin/xmllint --xpath '/plist/dict/array/dict/dict[key="minimumAlphaCharactersUpperCase"]/integer' - | /usr/bin/awk -F '[<>]' '{print $3}' +result: + integer: 1 +fix: | + This setting may be enforced using local policy or by a directory service. + + To set local policy to require at least 1 lowercase letter, edit the current password policy to contiain the following within the "policyCategoryPasswordContent": + + [source,xml] + ---- + + policyContent + policyAttributePassword matches '(.*[A-Z].*){1,}+' + policyIdentifier + Must have at least 1 uppercase letter + policyParameters + + minimumAlphaCharactersUpperCase + 1 + + + ---- + NOTE: See pwpolicy_supplemental on more information on how to implement password policies on macOS. +references: + cce: + - CCE-84821-8 + cci: + - CCI-000192 + 800-53r4: + - IA-5(1)(a) + disa_stig: + - AOSX-15-200005 + srg: + - SRG-OS-000069-GPOS-00037 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/srg/srg_anti_virus_installed.yaml b/rules/srg/srg_anti_virus_installed.yaml new file mode 100644 index 00000000..66b2a224 --- /dev/null +++ b/rules/srg/srg_anti_virus_installed.yaml @@ -0,0 +1,27 @@ +id: srg_anti_virus_installed +title: "The macOS system must use an approved antivirus program." +discussion: | + An approved antivirus product must be installed and configured to run. + Malicious software can establish a base on individual desktops and servers. Employing an automated mechanism to detect this type of software will aid in elimination of the software from the operating system. +check: | + Ask the System Administrator (SA) or Information System Security Officer (ISSO) if an approved antivirus solution is loaded on the system. The antivirus solution may be bundled with an approved host-based security solution. + If there is no local antivirus solution installed on the system, this is a finding. +fix: | + Install an approved antivirus solution onto the system. +references: + cce: + - CCE-84894-5 + cci: + - CCI-000366 + 800-53r4: + - SI-2 + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-002070 +macOS: + - "10.15" +tags: + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/srg/srg_filevault_user_account.yaml b/rules/srg/srg_filevault_user_account.yaml new file mode 100644 index 00000000..17d8ecd2 --- /dev/null +++ b/rules/srg/srg_filevault_user_account.yaml @@ -0,0 +1,59 @@ +id: srg_filevault_user_account +title: The macOS system must be configured with a dedicated user account to decrypt the hard disk upon startup. +discussion: | + When "FileVault" and Multifactor Authentication are configured on the operating system, a dedicated user must be configured to ensure that the implemented Multifactor Authentication rules are enforced. If a dedicated user is not configured to decrypt the hard disk upon startup, the system will allow a user to bypass Multifactor Authentication rules during initial startup and first login. +check: | + Ensure that only one FileVault user is defined: + + # sudo fdesetup list + + fvuser,85F41F44-22B3-6CB7-85A1-BCC2EA2B887A + + If more than one user is defined, this is a finding. + + Verify that the defined FileVault user has been disabled: + + # sudo dscl . read /Users/ AuthenticationAuthority | grep "DisabledUser" + + AuthenticationAuthority: ;ShadowHash;HASHLIST: ;Kerberosv5;;unlock@LKDC:SHA1.20BABA05A6B1A86A8C57581A8487596640A3E37B;LKDC:SHA1.20CEBE04A5B1D92D8C58189D8487593350D3A40A; ;SecureToken; DisabledUser + + If the FileVault user is not disabled, this is a finding. + + Verify that password forwarding has been disabled on the system: + + # sudo defaults read /Library/Preferences/com.apple.loginwindow | grep "DisableFDEAutologin" + + DisableFDEAutologin = 1; + + If "DisableFDEAutologin" is not set to a value of "1", this is a finding. +fix: | + Create a new user account that will be used to unlock the disk on startup. + + Disable the login ability of the newly created user account: + + # sudo dscl . append /Users/ AuthenticationAuthority DisabledUser + + Disable FileVaults Auto-login feature: + + # sudo defaults write /Library/Preferences/com.apple.loginwindow DisableFDEAutologin -bool YES + + Remove all FileVault login access from each user account defined on the system that is not the designated FileVault user: + + # sudo fdesetup remove -user +references: + cce: + - CCE-84893-7 + cci: + - CCI-000014 + 800-53r4: + - N/A + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-000032 +macOS: + - "10.15" +tags: + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/srg/srg_hbss_installed.yaml b/rules/srg/srg_hbss_installed.yaml new file mode 100644 index 00000000..5e15e118 --- /dev/null +++ b/rules/srg/srg_hbss_installed.yaml @@ -0,0 +1,34 @@ +id: srg_hbss_installed +title: The macOS system must utilize an HBSS solution and implement all DoD required modules. +discussion: | + The macOS system must employ automated mechanisms to determine the state of system components. The DoD requires the installation and use of an approved HBSS solution to be implemented on the operating system. For additional information, reference all applicable HBSS OPORDs and FRAGOs on SIPRNet. +check: | + Verify that there is an approved HBSS solution installed on the system. + + If there is not an approved HBSS solution installed, this is a finding. + + Verify that all installed components of the HBSS Solution are at the DoD approved minimal version. + + If the installed components are not at the DoD approved minimal versions, this is a finding. +fix: | + Install an approved HBSS solution onto the system and ensure that all components are at least updated to their DoD approved minimal versions. +references: + cce: + - CCE-84892-9 + cci: + - CCI-001233 + 800-53r4: + - SI-2(2) + srg: + - SRG-OS-000191-GPOS-00080 + disa_stig: + - AOSX-14-000015 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: +mobileconfig_info: \ No newline at end of file diff --git a/rules/supplemental/supplemental_firewall_pf.yaml b/rules/supplemental/supplemental_firewall_pf.yaml new file mode 100644 index 00000000..f48a9ea1 --- /dev/null +++ b/rules/supplemental/supplemental_firewall_pf.yaml @@ -0,0 +1,112 @@ +id: supplemental_firewall_pf +title: "Packet Filter (pf) Supplemental" +discussion: | + macOS contains an application layer firewall (ALF) (https://support.apple.com/en-ca/HT201642) and a packet filter firewall (PF). The Application firewall can block incoming traffic on per-application basis and prevent applications from listening on network ports, but it cannot be configured to block outgoing traffic. The packet filter firewall can manipulate virtually any packet data and is highly configurable. + + Included is a script that configures PF to match settings in the NIST 800-53 guideline. + + The script will make sure the application layer firewall is enabled, set logging to detailed, set built-in signed applications to automatically receive incoming connections, and set downloaded signed applications to automatically receive incoming connections. It will then create a custom rule set and copy com.apple.pfctl.plist from /System/Library/LaunchDaemons/ into the /Library/LaunchDaemons folder and name it 800-53.pfctl.plist. This is done to not conflict with the system's pf ruleset. + + The custom pf rules are created at /etc/pf.anchors/800_53_pf_anchors. + + The ruleset will block connections on the following ports: + + [%header,width="100%",cols="3,7"] + |=== + ^.^|Port + ^.^|Service + + |548 + |Apple File Protocol (AFP) + + |1900 + |Bonjour + + |79 + |Finger + + |20, 21 + |File Transfer Protocol (FTP) + + |80 + |HTTP + + |icmp + |ping + + |143 + |Internet Message Access Protocol (IMAP) + + |993 + |Internet Message Access Protocol over SSL (IMAPS) + + |3689 + |Music Sharing + + |5353 + |mDNSResponder + + |2049 + |Network File System (NFS) + + |49152 + |Optical Media Sharing + + |110 + |Post Office Protocol (POP3) + + |995 + |Post Office Protocol Secure (POP3S) + + |631 + |Printer Sharing + + |3031 + |Remote Apple Events + + |5900 + |Screen Sharing + + |137, 138, 138, 445 + |Samba (SMB) + + |25 + |Simple Mail Transfer Protocol (SMTP) + + |22 + |Secure Shell (SSH) + + |23 + |Telnet + + |69 + |Trivial File Transfer Protocol (TFTP) + + |540 + |Unix-to-Unix Copy (UUCP) + + |=== + + For more on configuring the packet filter firewall check out the man pages on pf.conf and pfctl. + + [source,bash] + ---- + include::../includes/enablePF-mscp.sh[] + ---- +check: | +fix: | +references: + cci: + - N/A + 800-53r4: + - N/A + srg: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - supplemental +mobileconfig: false +mobileconfig_info: diff --git a/rules/supplemental/supplemental_password_policy.yaml b/rules/supplemental/supplemental_password_policy.yaml new file mode 100644 index 00000000..2508bed1 --- /dev/null +++ b/rules/supplemental/supplemental_password_policy.yaml @@ -0,0 +1,45 @@ +id: supplemental_password_policy +title: "Password Policy Supplemental" +discussion: | + Password policies should be enforced as much as they can with Configuration Profiles. Certain policies are currently not possible and must be enabled using the pwpolicy command: + + * Enforcing at least 1 lowercase character + * Enforcing at least 1 uppercase character + * Disabling an account after 35 days of inactivity + * Password minimum lifetime + + To set local policy to require these requirements. Save the following XML password policy to a file. + + [source,xml] + ---- + include::../includes/pwpolicy.xml[] + ---- + + Run the following command to load the new policy file, substituting the path to the file in place of "/path/to/file". + + [source,bash] + ---- + /usr/bin/pwpolicy setaccountpolicies /path/to/file + ---- + + [NOTE] + ==== + If directory services is being utilized, password policies should come from the domain. + ==== +check: | +fix: | +references: + cci: + - N/A + 800-53r4: + - N/A + srg: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - supplemental +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/supplemental/supplemental_smartcard.yaml b/rules/supplemental/supplemental_smartcard.yaml new file mode 100644 index 00000000..460b0e80 --- /dev/null +++ b/rules/supplemental/supplemental_smartcard.yaml @@ -0,0 +1,229 @@ +id: supplemental_smartcard +title: "Smartcard Supplemental" +discussion: | + macOS supports smartcards, such as U.S. Personal Identity Verification (PIV) cards and U.S. Department of Defense Common Access Cards (CAC). Smartcards can be used in macOS for the following: + + * Authentication (Loginwindow, Screensaver, SSH, PKINIT, Safari, Finder, and PAM Authorization (sudo, login, su) ) + * Digital Encryption + * Digital Signing + * Remote Access (VPN:L2TP) + * Port-based Network Access Control (802.1X) + * Keychain Unlock + + macOS has built-in support for USB CCID class-compliant smartcard readers. + + [discrete] + ==== Smartcard Pairing + + The default method for using smartcards in macOS is a method called "Local Account Pairing". This occurs when a user inserts their smartcard into the Mac. The user is prompted to pair their smartcard with their account. If a user receives a new smartcard, the previous card must be unpaired and the new card paired to the account. This does a fixed key mapping with the hash of a public key on the user's smartcard with a local account. + + [discrete] + ==== Smartcard Attribute Mapping + Smartcards can be used to authenticate against a directory using attribute mapping configured in /private/etc/SmartcardLogin.plist. This file takes precedence over local account pairing. Attribute mapping matches the configured certificate field values from the smart card to the value in a directory. This may be used with network accounts, mobile accounts, or local accounts. + + [discrete] + ==== Smartcard Management in macOS + + The following settings are available to manage smartcards (com.apple.security.smartcard): + + [%header,cols="1,1,9"] + |=== + |Key + |Type + |Value + + <.^|userPairing + ^.^|Boolean + |If false, users will not get the pairing dialog, although existing pairings will still work. + + <.^|allowSmartCard + ^.^|Boolean + |If false, the SmartCard is disabled for logins, authorizations, and screensaver unlocking. It is still allowed for other functions, such as signing emails and web access. A restart is required for a change of setting to take effect. + + <.^|checkCertificateTrust + ^.^|Integer + a|Valid values are 0-3: + + - 0: certificate trust check is turned off + + - 1: certificate trust check is turned on. Standard validity check is being performed but this does not include additional revocation checks. + + - 2: certificate trust check is turned on, plus a soft revocation check is performed. Until the certificate is explicitly rejected by CRL/OCSP, it is considered as valid. This implies that unavailable/unreachable CRL/OCSP allows this check to succeed. + + - 3: certificate trust check is turned on, plus a hard revocation check is performed. Unless CRL/OCSP explicitly says “this certificate is OK”, the certificate is considered as invalid. This is the most secure value for this setting. + + <.^|oneCardPerUser + ^.^|Boolean + |If true, a user can pair with only one smartcard, although existing pairings will be allowed if already set up. + + <.^|enforceSmartCard + ^.^|Boolean + |If true, a user can only login or authenticate with a smartcard. + + <.^|tokenRemovalAction + ^.^|Integer + |If 1, enables screen saver when the smartcard is removed. + + <.^|allowUnmappedUsers + ^.^|Integer + |If 1, allows users who are in a directory group to be exempt from smartcard only enforcement. The group allowed for exemption is defined in /private/etc/SmartcardLogin.plist + + |=== + + A custom configuration profile (com.apple.loginwindow) should be created to disable automatic login when FileVault is enabled. This ensures that authorized users boot their Macs, enter a password at the pre-boot screen, which decrypts the boot volume, and then are presented with a login window where they can authenticate using a smartcard. + + [%header,cols="1,1,9"] + |=== + |Key + |Type + |Value + + <.^|DisableFDEAutoLogin + ^.^|Boolean + |If true, both EFI login password and loginwindow PIN are required + + |=== + + [discrete] + ==== Trusted Authorities + + In macOS you can specify which certificate authorities (CA) can be used for trust evaluation during smartcard authentication. Only CAs listed in the TrustedAuthorities section of the SmartcardLogin.plist will be evaluated as trusted. This setting only works if checkCertificateTrust is set to either 1, 2, or 3 in com.apple.security.smartcard. + + To get the SHA-256 hash in the correct format, run the following command within terminal: + [source,bash] + ---- + openssl x509 -noout -fingerprint -sha256 -inform pem -in | awk -F '=' '{print $2}' | sed 's/://g' + ---- + + To configure Trusted Authorities, the SmartcardLogin.plist should be minimally configured as below: + + [source,xml] + ---- + + + + + AttributeMapping + + fields + + NT Principal Name + + formatString + Kerberos:$1 + dsAttributeString + dsAttrTypeStandard:AltSecurityIdentities + + TrustedAuthorities + + SHA256_HASH_OF_CERTDOMAIN_1 + SHA256_HASH_OF_CERTDOMAIN_2 + + + + ---- + + [discrete] + ==== NotEnforcedGroup + + Starting in macOS 10.15, enforcement on a system can be granularly configured by adding a field to /private/etc/SmartcardLogin.plist. The NotEnforcedGroup can be added to the file to list a Directory group that will not be included in smartcard enforcement. In order to activate this feature, enforceSmartCard and allowUnmappedUsers be applied via a configuration profile (com.apple.security.smartcard). + + To configure the NotEnforcedGroup, the SmartcardLogin.plist should be minimally configured as below: + [source,xml] + ---- + + + + + AttributeMapping + + fields + + NT Principal Name + + formatString + Kerberos:$1 + dsAttributeString + dsAttrTypeStandard:AltSecurityIdentities + + TrustedAuthorities + + SHA256_HASH_OF_CERTDOMAIN_1 + SHA256_HASH_OF_CERTDOMAIN_2 + + NotEnforcedGroup + GROUPGOESHERE + + + ---- + + Once a system is configured for the NotEnforcedGroup a user can be added to the assigned group by running the following: + [source,bash] + ---- + /usr/sbin/dseditgroup -o edit -a -t user + ---- + + [discrete] + ==== Pluggable Authentication Module (PAM) + + Terminal sessions in macOS can be configured for smartcard enforcement by modifying the PAM modules for sudo, su, and login. + + [source,bash] + /etc/pam.d/sudo + ---- + # sudo: auth account password session + auth sufficient pam_smartcard.so + auth required pam_opendirectory.so + auth required pam_deny.so + account required pam_permit.so + password required pam_deny.so + session required pam_permit.so + ---- + + [source,bash] + /etc/pam.d/su + ---- + # su: auth account password session + auth sufficient pam_smartcard.so + auth required pam_rootok.so + auth required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe + account required pam_permit.so + account required pam_opendirectory.so no_check_shell + password required pam_opendirectory.so + session required pam_launchd.so + ---- + + [source,bash] + /etc/pam.d/login + ---- + # login: auth account password session + auth sufficient pam_smartcard.so + auth optional pam_krb5.so use_kcminit + auth optional pam_ntlm.so try_first_pass + auth optional pam_mount.so try_first_pass + auth required pam_opendirectory.so try_first_pass + auth required pam_deny.so + account required pam_nologin.so + account required pam_opendirectory.so + password required pam_opendirectory.so + session required pam_launchd.so + session required pam_uwtmp.so + session optional pam_mount.so + ---- +check: | +fix: | +references: + cci: + - N/A + 800-53r4: + - N/A + srg: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - supplemental +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_ad_tracking_disable.yaml b/rules/sysprefs/sysprefs_ad_tracking_disable.yaml new file mode 100644 index 00000000..52f4446e --- /dev/null +++ b/rules/sysprefs/sysprefs_ad_tracking_disable.yaml @@ -0,0 +1,35 @@ +id: sysprefs_ad_tracking_disable +title: "Disable Ad Tracking" +discussion: | + Ad tracking and targeted ads must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c '"forceLimitAdTracking" = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84822-6 + cci: + - + 800-53r4: + - CM-7(5)(b) + - CM-7(b) + srg: + - + disa_stig: + - +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.AdLib: + forceLimitAdTracking: "1" diff --git a/rules/sysprefs/sysprefs_afp_disable.yaml b/rules/sysprefs/sysprefs_afp_disable.yaml new file mode 100644 index 00000000..ea4840a1 --- /dev/null +++ b/rules/sysprefs/sysprefs_afp_disable.yaml @@ -0,0 +1,35 @@ +id: sysprefs_afp_disable +title: "Disable Apple File (AFP) Sharing" +discussion: | + If the system does not require AFP Sharing, support it is non-essential and must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.AppleFileServer" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/com.apple.AppleFileServer + ---- + The system may need to be restarted for the update to take effect. +references: + cce: + - CCE-84823-4 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002002 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_apple_watch_unlock_disable.yaml b/rules/sysprefs/sysprefs_apple_watch_unlock_disable.yaml new file mode 100644 index 00000000..f26e0873 --- /dev/null +++ b/rules/sysprefs/sysprefs_apple_watch_unlock_disable.yaml @@ -0,0 +1,33 @@ +id: sysprefs_apple_watch_unlock_disable +title: "Prevent Apple Watch from terminating a session lock" +discussion: | + Apple Watches are not an approved authenticator and their use should be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowAutoUnlock = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84824-2 + cci: + - CCI-000056 + 800-53r4: + - AC-11(b) + srg: + - SRG-OS-000028-GPOS-00009 + disa_stig: + - AOSX-14-000001 +macOS: + - "10.15" + - "10.14" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowAutoUnlock: false diff --git a/rules/sysprefs/sysprefs_automatic_login_disable.yaml b/rules/sysprefs/sysprefs_automatic_login_disable.yaml new file mode 100644 index 00000000..ec795352 --- /dev/null +++ b/rules/sysprefs/sysprefs_automatic_login_disable.yaml @@ -0,0 +1,33 @@ +id: sysprefs_automatic_login_disable +title: "Disable unattended or automatic logon to the system" +discussion: | + When automatic logons are enabled, the default user account is automatically logged on at boot time without prompting the user for a password. Even if the screen is later locked, a malicious user would be able to reboot the computer to log on. Disabling automatic logons mitigates this risk. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c '"com.apple.login.mcx.DisableAutoLoginClient" = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84825-9 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00229 + disa_stig: + - AOSX-14-002066 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.loginwindow: + com.apple.login.mcx.DisableAutoLoginClient: true diff --git a/rules/sysprefs/sysprefs_bluetooth_disable.yaml b/rules/sysprefs/sysprefs_bluetooth_disable.yaml new file mode 100644 index 00000000..f8e79c09 --- /dev/null +++ b/rules/sysprefs/sysprefs_bluetooth_disable.yaml @@ -0,0 +1,34 @@ +id: sysprefs_bluetooth_disable +title: "The macOS system must be configured with Bluetooth disabled when no device is paired" +discussion: | + The macOS system must be configured to disable Bluetooth unless there is an approved paired device. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'DisableBluetooth = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84826-7 + cci: + - CCI-002418 + 800-53r4: + - AC-18(3) + - SC-8 + srg: + - SRG-OS-000481-GPOS-000481 + disa_stig: + - AOSX-14-002062 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.MCXBluetooth: + DisableBluetooth: true diff --git a/rules/sysprefs/sysprefs_bluetooth_sharing_disable.yaml b/rules/sysprefs/sysprefs_bluetooth_sharing_disable.yaml new file mode 100644 index 00000000..f9b86fce --- /dev/null +++ b/rules/sysprefs/sysprefs_bluetooth_sharing_disable.yaml @@ -0,0 +1,48 @@ +id: sysprefs_bluetooth_sharing_disable +title: "Disable Bluetooth Sharing" +discussion: | + Bluetooth sharing allows users to wirelessly transmit files between the macOS and Bluetooth-enabled devices, including personally owned cellphones and tablets. A malicious user might introduce viruses or malware onto the system or extract sensitive files. + + Disabling Bluetooth Sharing mitigates this risk. + + [NOTE] + ==== + The check and fix are for the currently logged in user. To get the currently logged in user, run the following. + [source,bash] + ---- + CURRENT_USER=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' ) + ---- + ==== +check: | + /usr/bin/sudo -u "$CURRENT_USER" /usr/bin/defaults -currentHost read com.apple.Bluetooth PrefKeyServicesEnabled +result: + boolean: 0 +fix: | + [source,bash] + ---- + /usr/bin/sudo -u "$CURRENT_USER" /usr/bin/defaults -currentHost write com.apple.Bluetooth PrefKeyServicesEnabled -bool false + ---- +references: + cce: + - CCE-84827-5 + cci: + - N/A + 800-53r4: + - AC-18 + - AC-18(4) + - CM-6(b) + - CM-7(1) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: + diff --git a/rules/sysprefs/sysprefs_content_caching_disable.yaml b/rules/sysprefs/sysprefs_content_caching_disable.yaml new file mode 100644 index 00000000..08a2cf38 --- /dev/null +++ b/rules/sysprefs/sysprefs_content_caching_disable.yaml @@ -0,0 +1,32 @@ +id: sysprefs_content_caching_disable +title: "Disable Content Caching service" +discussion: | + Content caching is a macOS service that helps reduce Internet data usage and speed up software installation on Mac computers. Organization devices shall not be acting as a caching server. General purpose systems should not server as content caches, known designated systems may as their use can then be properly monitored. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowContentCaching = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84828-3 + cci: + - + 800-53r4: + - CM-7(b) + srg: + - + disa_stig: + - +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowContentCaching: false \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_diagnostics_reports_disable.yaml b/rules/sysprefs/sysprefs_diagnostics_reports_disable.yaml new file mode 100644 index 00000000..d1b85c99 --- /dev/null +++ b/rules/sysprefs/sysprefs_diagnostics_reports_disable.yaml @@ -0,0 +1,36 @@ +id: sysprefs_diagnostics_reports_disable +title: "Disable sending diagnostic and usage data to Apple" +discussion: | + The ability to submit diagnostic data to Apple must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -Ec '(allowDiagnosticSubmission = 0|AutoSubmit = 0)' +result: + integer: 2 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84829-1 + cci: + - CCI-000382 + 800-53r4: + - CM-7(b) + - SC-7(10) + - SI-4 + srg: + - SRG-OS-000096-GPOS-00050 + disa_stig: + - AOSX-14-002021 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.SubmitDiagInfo: + AutoSubmit: false + com.apple.applicationaccess: + allowDiagnosticSubmission: false diff --git a/rules/sysprefs/sysprefs_filevault_enforce.yaml b/rules/sysprefs/sysprefs_filevault_enforce.yaml new file mode 100644 index 00000000..18972c05 --- /dev/null +++ b/rules/sysprefs/sysprefs_filevault_enforce.yaml @@ -0,0 +1,74 @@ +id: sysprefs_filevault_enforce +title: "Enforce FileVault" +discussion: | + The information system implements cryptographic mechanisms to protect the confidentiality and integrity of information stored on digital media during transport outside of controlled areas. + + FileVault full-disk encryption (FileVault 2) uses XTS-AES-128 encryption with a 256-bit key to help prevent unauthorized access to the information on your startup disk. + + FileVault2 is described in https://support.apple.com/en-us/HT204837 + + FileVault can be enabled in two ways within the macOS. It can be managed using the fdesetup command or by a Configuration Profile. When enabling FileVault, the user name and password must be a local OpenDirectory account with a valid Secure Token password. + Using the command line in the Terminal application you can run the following command. + + [source,bash] + ---- + /usr/bin/fdesetup enable + ---- + This will enable FileVault after prompting for a user name and password, and return the personal recovery key. + There are a number of management features available when managing FileVault using the command line instead of a configuration profile. These are available in the manpage for fdesetup. Apple has depcrecated fdesetup command line tool from recognizing user name and password for seucirty reasons and may remove the ability in future versions of macOS. + + When managing FileVault with a configuration profile you must deploy a profile with the payload type of com.apple.MCX.FileVault2. When using the key enable to enable FileVault with a configuraiton profile, you must include 1 of the following + + [source,xml] + ---- + Enable + On + Defer + + ---- + [source,xml] + ---- + Enable + On + UserEntersMissingInfo + + ---- + + If using the key UserEntersMissingInfo it will only work if installed through manual installation and will prompt for the user name and password. + If using the Defer key it will prompt for the user name and password at logout. + If using a configuration profile you can escrow the Recovery Key to an MDM Server. Documentation for that can be found on link:https://developer.apple.com/documentation/devicemanagement/fderecoverykeyescrow[Apple's Developer site]. + + It's recommended that you use a Personal Recovery Key instead of an Institutional Key as it will generate a specific key for each device. + + Important to note, FileVault also only uses password based authentication and can not use a smartcard or any other multi factor authication. +check: | + /usr/bin/fdesetup status | /usr/bin/grep -c "FileVault is On." +result: + integer: 1 +fix: | + NOTE: See discussion on remediation and how to enable FileVault. +references: + cce: + - CCE-84830-9 + cci: + - CCI-001199 + - CCI-002475 + - CCI-002476 + 800-53r4: + - SC-28 + - SC-28(1) + srg: + - SRG-OS-000185-GPOS-00079 + - SRG-OS-000404-GPOS-00183 + - SRG-OS-000405-GPOS-00184 + disa_stig: + - AOSX-14-005020 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_find_my_disable.yaml b/rules/sysprefs/sysprefs_find_my_disable.yaml new file mode 100644 index 00000000..c3bbdf70 --- /dev/null +++ b/rules/sysprefs/sysprefs_find_my_disable.yaml @@ -0,0 +1,40 @@ +id: sysprefs_find_my_disable +title: "Disable Find My service" +discussion: | + Ensure that the Find My is not enabled. An MDM solution shall be used instead of a personal AppleID to use Find My features, such as Remote Lock and Remote Wipe. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -Ec '(allowCloudFMM = 0|allowFindMyDevice = 0|allowFindMyFriends = 0|DisableFMMiCloudSetting = 1)' +result: + integer: 4 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84831-7 + cci: + - N/A + 800-53r4: + - CM-7(5)(b) + - CM-7(b) + - CM-8(8) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowCloudFMM: false + allowFindMyDevice: false + allowFindMyFriends: false + com.apple.icloud.managed: + DisableFMMiCloudSetting: true + diff --git a/rules/sysprefs/sysprefs_firewall_enable.yaml b/rules/sysprefs/sysprefs_firewall_enable.yaml new file mode 100644 index 00000000..d2685130 --- /dev/null +++ b/rules/sysprefs/sysprefs_firewall_enable.yaml @@ -0,0 +1,39 @@ +id: sysprefs_firewall_enable +title: "Enable macOS Application Firewall" +discussion: | + The Application Firewall is the built-in firewall that comes with macOS and must be enabled. The information system enforces approved authorizations for controlling the flow of information within the system and between interconnected systems. +check: | + /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate | grep -c "Firewall is enabled" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on + ---- +references: + cce: + - CCE-84832-5 + cci: + - CCI-000366 + 800-53r4: + - AC-4 + - AC-6(1) + - AC-19 + - CM-6(b) + - CM-7 + - SC-7(12) + srg: + - SRG-OS-000480-GPOS-00232 + disa_stig: + - AOSX-14-005050 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_firewall_stealth_mode_enable.yaml b/rules/sysprefs/sysprefs_firewall_stealth_mode_enable.yaml new file mode 100644 index 00000000..450e11ce --- /dev/null +++ b/rules/sysprefs/sysprefs_firewall_stealth_mode_enable.yaml @@ -0,0 +1,36 @@ +id: sysprefs_firewall_stealth_mode_enable +title: "Enable Firewall Stealth Mode" +discussion: | + The information system prevents discovery of specific system components composing a managed interface. + + When stealth mode is enabled, the Mac will not respond to any probing requests. All requests from authorized apps will still be authorized. +check: | + /usr/libexec/ApplicationFirewall/socketfilterfw --getstealthmode | /usr/bin/grep -c "Stealth mode enabled" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on + ---- +references: + cce: + - CCE-84833-3 + 800-53r4: + - CM-6(b) + - SC-7(16) + srg: + - N/A + cci: + - N/A + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: false +mobileconfig_info: diff --git a/rules/sysprefs/sysprefs_gatekeeper_identified_developers_allowed.yaml b/rules/sysprefs/sysprefs_gatekeeper_identified_developers_allowed.yaml new file mode 100644 index 00000000..f48c613c --- /dev/null +++ b/rules/sysprefs/sysprefs_gatekeeper_identified_developers_allowed.yaml @@ -0,0 +1,42 @@ +id: sysprefs_gatekeeper_identified_developers_allowed +title: "Only allow applications from identified developers and downloaded from the App Store to run" +discussion: | + The information system implements cryptographic mechanisms to authenticate software prior to installation. + + Gatekeeper settings must be configured correctly to only allow the system to run applications downloaded from the Mac App Store or applications signed with a valid Apple Developer ID code. Administrator users will still have the option to override these settings on a per-app basis. Gatekeeper is a security feature that ensures that applications must be digitally signed by an Apple-issued certificate in order to run. Digital signatures allow the macOS to verify that the application has not been modified by a malicious third party. +check: | + /usr/sbin/spctl --status --verbose | /usr/bin/grep -c "developer id enabled" +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/sbin/spctl --master-enable; /usr/sbin/spctl --enable + ---- +references: + cce: + - CCE-84834-1 + cci: + - CCI-000366 + 800-53r4: + - CM-5(3) + - CM-6(b) + - SI-7(15) + srg: + - SRG-OS-000366-GPOS-00153 + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-002060 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.systempolicy.control: + AllowIdentifiedDevelopers: true + EnableAssessment: true \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_gatekeeper_override_disallow.yaml b/rules/sysprefs/sysprefs_gatekeeper_override_disallow.yaml new file mode 100644 index 00000000..3393550b --- /dev/null +++ b/rules/sysprefs/sysprefs_gatekeeper_override_disallow.yaml @@ -0,0 +1,43 @@ +id: sysprefs_gatekeeper_override_disallow +title: "Configure Gatekeeper to disallow end user override" +discussion: | + The information system implements cryptographic mechanisms to authenticate software prior to installation. + + Gatekeeper must be configured with a configuration profile to prevent normal users from overriding its setting. If users are allowed to disable Gatekeeper or set it to a less restrictive setting, malware could be introduced into the system. Gatekeeper is a security feature that ensures applications must be digitally signed by an Apple-issued certificate in order to run. Digital signatures allow Mac macOS to verify the application has not been modified by a malicious third party. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'DisableOverride = 1' +result: + integer: 1 +fix: | + To implement the prescribed state with a Configuration Profile, create a configuration profile (com.apple.systempolicy.managed) with the following key DisableOverride set to true + [source,xml] + ---- + DisableOverride + + ---- + NOTE - This will apply to the whole system +references: + cce: + - CCE-84835-8 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + - SI-7(15) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-002061 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.systempolicy.managed: + DisableOverride: true + diff --git a/rules/sysprefs/sysprefs_hot_corners_disable.yaml b/rules/sysprefs/sysprefs_hot_corners_disable.yaml new file mode 100644 index 00000000..09c51aa3 --- /dev/null +++ b/rules/sysprefs/sysprefs_hot_corners_disable.yaml @@ -0,0 +1,38 @@ +id: sysprefs_hot_corners_disable +title: "Disable Hot Corners" +discussion: | + The information system conceals, via the session lock, information previously visible on the display with a publicly viewable image. + + Although hot comers can be used to initiate a session lock or launch useful applications, they can also be configured to disable an automatic session lock from initiating. Such a configuration introduces the risk that a user might forget to manually lock the screen before stepping away from the computer. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -Ec '"wvous-bl-corner" = 0|"wvous-br-corner" = 0|"wvous-tl-corner" = 0|"wvous-tr-corner" = 0' +result: + integer: 4 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84836-6 + cci: + - CCI-000060 + 800-53r4: + - AC-11(1) + srg: + - SRG-OS-000031-GPOS-00012 + disa_stig: + - AOSX-14-000007 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.dock: + wvous-bl-corner: 0 + wvous-br-corner: 0 + wvous-tr-corner: 0 + wvous-tl-corner: 0 diff --git a/rules/sysprefs/sysprefs_internet_sharing_disable.yaml b/rules/sysprefs/sysprefs_internet_sharing_disable.yaml new file mode 100644 index 00000000..29c1218b --- /dev/null +++ b/rules/sysprefs/sysprefs_internet_sharing_disable.yaml @@ -0,0 +1,33 @@ +id: sysprefs_internet_sharing_disable +title: "Disable Internet Sharing" +discussion: | + If the system does not require Internet Sharing, support it is non-essential and must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'forceInternetSharingOff = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84837-4 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002007 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.MCX: + forceInternetSharingOff: true diff --git a/rules/sysprefs/sysprefs_location_services_disable.yaml b/rules/sysprefs/sysprefs_location_services_disable.yaml new file mode 100644 index 00000000..13778e16 --- /dev/null +++ b/rules/sysprefs/sysprefs_location_services_disable.yaml @@ -0,0 +1,36 @@ +id: sysprefs_location_services_disable +title: "Disable Location Services" +discussion: | + Configures the information system to provide only essential capabilities. + + If the system does not require Location Services, support it is non-essential and must be disabled. +check: | + /usr/bin/defaults read /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.plist LocationServicesEnabled +result: + integer: 0 +fix: | + [source,bash] + ---- + /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 0; /bin/launchctl kickstart -k system/com.apple.locationd + ---- +references: + cce: + - CCE-84838-2 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002004 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_loginwindow_prompt_username_password_enforce.yaml b/rules/sysprefs/sysprefs_loginwindow_prompt_username_password_enforce.yaml new file mode 100644 index 00000000..6b4a9798 --- /dev/null +++ b/rules/sysprefs/sysprefs_loginwindow_prompt_username_password_enforce.yaml @@ -0,0 +1,32 @@ +id: sysprefs_loginwindow_prompt_username_password_enforce +title: "Configure login window to prompt for username and password" +discussion: | + The logon window must be configured to prompt all users for both a username and a password. By default, the system displays a list of known users at the logon screen. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'SHOWFULLNAME = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84839-0 + cci: + - N/A + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00229 + disa_stig: + - N/A +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high +mobileconfig: true +mobileconfig_info: + com.apple.loginwindow: + SHOWFULLNAME: true diff --git a/rules/sysprefs/sysprefs_media_sharing_disabled.yaml b/rules/sysprefs/sysprefs_media_sharing_disabled.yaml new file mode 100644 index 00000000..687e0793 --- /dev/null +++ b/rules/sysprefs/sysprefs_media_sharing_disabled.yaml @@ -0,0 +1,28 @@ +id: sysprefs_media_sharing_disabled +title: "Disable Media Sharing" +discussion: | + When Media Sharing is enabled, the computer starts a network listening service that shares the contents of the user's music collection with other users in the same subnet. Unnecessary network services should always be disabled because they increase the attack surface of the system. Disabling Media Sharing mitigates this risk. +check: | + pfctl -a '*' -sr &> /dev/null | grep -c "block drop log proto tcp from any to any port = 3689" +result: + integer: 1 +fix: | + NOTE: Even if the user enables this service, the firewall is configured to block access to it. See Firewall Supplemental which includes a script that has an example policy to implement this rule. +references: + cce: + - CCE-84771-5 + 800-53r4: + - CM-7(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - N/A + cci: + - N/A +macOS: + - "10.15" +tags: + - STIG +mobileconfig: false +mobileconfig_info: + diff --git a/rules/sysprefs/sysprefs_password_hints_disable.yaml b/rules/sysprefs/sysprefs_password_hints_disable.yaml new file mode 100644 index 00000000..efe3f628 --- /dev/null +++ b/rules/sysprefs/sysprefs_password_hints_disable.yaml @@ -0,0 +1,34 @@ +id: sysprefs_password_hints_disable +title: "Disable Password Hints" +discussion: | + Password hints leak information about passwords in use and can lead to loss of confidentiality. Password hints must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'RetriesUntilHint = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84840-8 + cci: + - CCI-000366 + 800-53r4: + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-003012 +macOS: + - "10.15" + - "10.14" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.loginwindow: + RetriesUntilHint: 0 diff --git a/rules/sysprefs/sysprefs_rae_disable.yaml b/rules/sysprefs/sysprefs_rae_disable.yaml new file mode 100644 index 00000000..a5cbc358 --- /dev/null +++ b/rules/sysprefs/sysprefs_rae_disable.yaml @@ -0,0 +1,36 @@ +id: sysprefs_rae_disable +title: "Disable Remote Apple Events" +discussion: | + If the system does not require Remote Apple Events, support for Apple Remote Events is non-essential and must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.AEServer" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /usr/sbin/systemsetup -setremoteappleevents off + /bin/launchctl disable system/com.apple.AEServer + ---- + NOTE: Systemsetup with -setremoteappleevents flag will fail unless you grant Full Disk Access to systemsetup or it's parent process. Requires UAMDM. +references: + cce: + - CCE-84841-6 + cci: + - CCI-000382 + 800-53r4: + - CM-7(b) + srg: + - SRG-OS-000096-GPOS-00050 + disa_stig: + - AOSX-14-002022 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_screen_sharing_disable.yaml b/rules/sysprefs/sysprefs_screen_sharing_disable.yaml new file mode 100644 index 00000000..27a2c3ea --- /dev/null +++ b/rules/sysprefs/sysprefs_screen_sharing_disable.yaml @@ -0,0 +1,36 @@ +id: sysprefs_screen_sharing_disable +title: "Disable Apple Remote Desktop (ARD) and Screen Sharing" +discussion: | + If the system does not require Screen Sharing or ARD, support for both is non-essential and must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.screensharing" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/com.apple.screensharing + ---- + NOTE - This will apply to the whole system +references: + cce: + - CCE-84842-4 + cci: + - CCI-000366 + 800-53r4: + - AC-17 + - CM-6(b) + srg: + - SRG-OS-000480-GPOS-00227 + disa_stig: + - AOSX-14-002050 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_siri_disable.yaml b/rules/sysprefs/sysprefs_siri_disable.yaml new file mode 100644 index 00000000..3bc28811 --- /dev/null +++ b/rules/sysprefs/sysprefs_siri_disable.yaml @@ -0,0 +1,36 @@ +id: sysprefs_siri_disable +title: "Disable Siri" +discussion: | + If the system does not require Siri, support for Siri is non-essential and must be disabled. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c '"Ironwood Allowed" = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84843-2 + cci: + - CCI-000381 + - CCI-001774 + 800-53r4: + - CM-7(5)(b) + - CM-7(b) + srg: + - SRG-OS-000095-GPOS-00049 + - SRG-OS-000370-GPOS-00155 + disa_stig: + - AOSX-14-002020 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.Siri: + "Ironwood Allowed": false diff --git a/rules/sysprefs/sysprefs_smbd_disable.yaml b/rules/sysprefs/sysprefs_smbd_disable.yaml new file mode 100644 index 00000000..55713dc5 --- /dev/null +++ b/rules/sysprefs/sysprefs_smbd_disable.yaml @@ -0,0 +1,35 @@ +id: sysprefs_smbd_disable +title: "Disable Server Message Block (SMB) Sharing" +discussion: | + If the system does not require SMB file sharing, support it is non-essential and must be disabled. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.apple.smbd" => true' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl disable system/com.apple.smbd + ---- + The system may need to be restarted for the update to take effect. +references: + cce: + - CCE-84844-0 + cci: + - CCI-000381 + 800-53r4: + - CM-7(a) + srg: + - SRG-OS-000095-GPOS-00049 + disa_stig: + - AOSX-14-002001 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-low + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_ssh_enable.yaml b/rules/sysprefs/sysprefs_ssh_enable.yaml new file mode 100644 index 00000000..d4df064c --- /dev/null +++ b/rules/sysprefs/sysprefs_ssh_enable.yaml @@ -0,0 +1,63 @@ +id: sysprefs_ssh_enable +title: "Enable SSH for remote access sessions" +discussion: | + Remote acces sessions must use encrypted methods to protect unauthorized individuals from gaining access. SSH service must be enabled for remote access. +check: | + /bin/launchctl print-disabled system | /usr/bin/grep -c '"com.openssh.sshd" => false' +result: + integer: 1 +fix: | + [source,bash] + ---- + /bin/launchctl enable system/com.openssh.sshd + ---- +references: + cce: + - CCE-84845-7 + cci: + - CCI-001941 + - CCI-001942 + - CCI-002890 + - CCI-002420 + - CCI-002421 + - CCI-002422 + - CCI-003123 + - CCI-001453 + - CCI-000068 + - CCI-002418 + 800-53r4: + - AC-17(2) + - AC-17(4) + - IA-2(8) + - IA-2(9) + - MA-4(6) + - SC-8 + - SC-8(1) + - SC-8(2) + srg: + - SRG-OS-000393-GPOS-00173 + - SRG-OS-000394-GPOS-00174 + - SRG-OS-000112-GPOS-00057 + - SRG-OS-000113-GPOS-00058 + - SRG-OS-000033-GPOS-00014 + - SRG-OS-000423-GPOS-00187 + - SRG-OS-000424-GPOS-00188 + - SRG-OS-000425-GPOS-00189 + - SRG-OS-000426-GPOS-00190 + - SRG-OS-000033-GPOS-00014 + - SRG-OS-000250-GPOS-00093 + disa_stig: + - AOSX-14-000040 + - AOSX-14-004011 + - AOSX-14-004010 + - AOSX-14-000011 + - AOSX-14-000010 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: false +mobileconfig_info: \ No newline at end of file diff --git a/rules/sysprefs/sysprefs_time_server_configure.yaml b/rules/sysprefs/sysprefs_time_server_configure.yaml new file mode 100644 index 00000000..17dc7a2a --- /dev/null +++ b/rules/sysprefs/sysprefs_time_server_configure.yaml @@ -0,0 +1,35 @@ +id: sysprefs_time_server_configure +title: "Configured to use an authorized time server" +discussion: | + Only approved time servers should be configured for use. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/awk -F "= " '/timeServer/{print $2}' | /usr/bin/tr -d ';' +result: + string: "time-a.nist.gov,time-b.nist.gov" +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84846-5 + cci: + - CCI-001891 + - CCI-002046 + 800-53r4: + - AU-8(1)(a) + - AU-8(1)(b) + srg: + - SRG-OS-000355-GPOS-00143 + - SRG-OS-000356-GPOS-00144 + disa_stig: + - AOSX-14-000014 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.MCX: + timeServer: "time-a.nist.gov,time-b.nist.gov" diff --git a/rules/sysprefs/sysprefs_time_server_enforce.yaml b/rules/sysprefs/sysprefs_time_server_enforce.yaml new file mode 100644 index 00000000..f80fc491 --- /dev/null +++ b/rules/sysprefs/sysprefs_time_server_enforce.yaml @@ -0,0 +1,37 @@ +id: sysprefs_time_server_enforce +title: "Enable macOS Time Synchronization Daemon (timed)" +discussion: | + The timed service must be enabled on all networked systems and configured to set time automatically from the approved time server. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'TMAutomaticTimeOnlyEnabled = 1' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84847-3 + cci: + - CCI-001891 + - CCI-002046 + 800-53r4: + - AU-8(1)(a) + - AU-8(1)(b) + srg: + - SRG-OS-000355-GPOS-00143 + - SRG-OS-000356-GPOS-00144 + disa_stig: + - AOSX-14-000014 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.ManagedClient.preferences: + com.apple.timed: + TMAutomaticTimeOnlyEnabled: true + diff --git a/rules/sysprefs/sysprefs_token_removal_enforce.yaml b/rules/sysprefs/sysprefs_token_removal_enforce.yaml new file mode 100644 index 00000000..b716495c --- /dev/null +++ b/rules/sysprefs/sysprefs_token_removal_enforce.yaml @@ -0,0 +1,32 @@ +id: sysprefs_token_removal_enforce +title: "Configure user session lock when a smart token is removed" +discussion: | + The screen lock must initiate when the smart token is removed from the system. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'tokenRemovalAction = 1' +result: + integer: 1 +fix: + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84848-1 + cci: + - CCI-000058 + 800-53r4: + - AC-11(a) + srg: + - SRG-OS-000030-GPOS-00011 + disa_stig: + - AOSX-14-000005 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.security.smartcard: + tokenRemovalAction: 1 diff --git a/rules/sysprefs/sysprefs_touchid_unlock_disable.yaml b/rules/sysprefs/sysprefs_touchid_unlock_disable.yaml new file mode 100644 index 00000000..996549a2 --- /dev/null +++ b/rules/sysprefs/sysprefs_touchid_unlock_disable.yaml @@ -0,0 +1,32 @@ +id: sysprefs_touchid_unlock_disable +title: "Disable TouchID to unlock the device" +discussion: | + TouchID enables the ability to unlock a Mac system with a user fingerprint. Disable TouchID for "Unlocking your Mac" on enabled Macs. TouchID must be disabled for "Unlocking your Mac" on all Macs that are capable of using Touch ID. The system must retains the session lock until the user reestablishes access using established identification and authentication procedures. +check: | + /usr/bin/profiles -P -o stdout | /usr/bin/grep -c 'allowFingerprintForUnlock = 0' +result: + integer: 1 +fix: | + This is implemented by a Configuration Profile. +references: + cce: + - CCE-84849-9 + cci: + - CCI-000056 + 800-53r4: + - AC-11(b) + srg: + - SRG-OS-000028-GPOS-00009 + disa_stig: + - AOSX-14-000001 +macOS: + - "10.15" +tags: + - cnssi-1253 + - fisma-moderate + - fisma-high + - STIG +mobileconfig: true +mobileconfig_info: + com.apple.applicationaccess: + allowFingerprintForUnlock: false diff --git a/scripts/KNOWN_ISSUES b/scripts/KNOWN_ISSUES new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/scripts/KNOWN_ISSUES @@ -0,0 +1 @@ + diff --git a/scripts/baseline-identify.py b/scripts/baseline-identify.py new file mode 100755 index 00000000..f7f7bf74 --- /dev/null +++ b/scripts/baseline-identify.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# filename: baseline_identify.py +# description: Identify which rules fall on specific baselines. + +import argparse +import io +import yaml +import os +from string import Template +from itertools import groupby +import glob + + +# File path setup +file_dir = os.path.dirname(os.path.abspath(__file__)) +parent_dir = os.path.dirname(file_dir) + +# import profile_manifests.plist +baselines_file = os.path.join(parent_dir, 'includes', '800-53_baselines.yaml') +with open(baselines_file) as r: + baselines = yaml.load(r, Loader=yaml.SafeLoader) + +low_rules = [] +mod_rules = [] +high_rules = [] + +# Create sections and rules +for rule in sorted(glob.glob(parent_dir + '/rules/*/*.yaml')): + with open(rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + + try: + rule_yaml['references']['800-53r4'] + except KeyError: + nist_80053r4 = 'N/A' + else: + #nist_80053r4 = ulify(rule_yaml['references']['800-53r4']) + nist_80053r4 = rule_yaml['references']['800-53r4'] + + for control in nist_80053r4: + if control in baselines['low']: + #print("rule: {} contains: {} which falls on low baseline".format(rule_yaml['id'], control)) + if rule_yaml['id'] not in low_rules: + low_rules.append(rule_yaml['id']) + if control in baselines['moderate']: + #print("rule: {} contains: {} which falls on moderate baseline".format(rule_yaml['id'], control)) + if rule_yaml['id'] not in mod_rules: + mod_rules.append(rule_yaml['id']) + if control in baselines['high']: + #print("rule: {} contains: {} which falls on high baseline".format(rule_yaml['id'], control)) + if rule_yaml['id'] not in high_rules: + high_rules.append(rule_yaml['id']) + +print("{} Rules belong on LOW baseline".format(len(low_rules))) +for rule in low_rules: + print(" - {}".format(rule)) + +print("\n {} Rules that belong on MODERATE baseline".format(len(mod_rules))) +for rule in mod_rules: + print(" - {}".format(rule)) + +print("\n {} Rules that belong on HIGH baseline".format(len(high_rules))) +for rule in high_rules: + print(" - {}".format(rule)) \ No newline at end of file diff --git a/scripts/create_guide.py b/scripts/create_guide.py new file mode 100755 index 00000000..e16a225b --- /dev/null +++ b/scripts/create_guide.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python3 +# filename: create_guide.py +# description: Create AsciiDoc guide from YAML + +import argparse +import io +import yaml +import os +from string import Template +from itertools import groupby +import glob + +# Convert a list to AsciiDoc +def ulify(elements): + string = "\n" + for s in elements: + string += "* " + str(s) + "\n" + return string + +def group_ulify(elements): + string = "\n * " + for s in elements: + string += str(s) + ", " + return string[:-2] + + +# Setup argparse +parser = argparse.ArgumentParser( + description='Given a baseline, create an AsciiDoc guide.') +parser.add_argument("baseline", default=None, + help="Baseline YAML file used to create the guide.", type=argparse.FileType('rt')) +parser.add_argument("-o", "--output", default=None, + help="Output file", type=argparse.FileType('wt')) + +try: + results = parser.parse_args() + output_basename = os.path.basename(results.baseline.name) + output_filename = os.path.splitext(output_basename)[0] + if results.output: + output_file = results.output + else: + output_file = open("../build/{}.adoc".format(output_filename), 'w') + print('Profile YAML:', results.baseline.name) + print('Output file:', output_file.name) +except IOError as msg: + parser.error(str(msg)) + +# Read the profile YAML details +profile_yaml = yaml.load(results.baseline, Loader=yaml.SafeLoader) + +# Setup AsciiDoc templates +with open('../templates/adoc_rule.adoc') as adoc_rule_file: + adoc_rule_template = Template(adoc_rule_file.read()) + +with open('../templates/adoc_supplemental.adoc') as adoc_supplemental_file: + adoc_supplemental_template = Template(adoc_supplemental_file.read()) + +with open('../templates/adoc_rule_no_setting.adoc') as adoc_rule_no_setting_file: + adoc_rule_no_setting_template = Template(adoc_rule_no_setting_file.read()) + +with open('../templates/adoc_section.adoc') as adoc_section_file: + adoc_section_template = Template(adoc_section_file.read()) + +with open('../templates/adoc_header.adoc') as adoc_header_file: + adoc_header_template = Template(adoc_header_file.read()) + +with open('../templates/adoc_footer.adoc') as adoc_footer_file: + adoc_footer_template = Template(adoc_footer_file.read()) + +# Create header +header_adoc = adoc_header_template.substitute( + profile_title = profile_yaml['title'], + description = profile_yaml['description'] +) + +# Output header +output_file.write(header_adoc) + +# Create sections and rules +for sections in profile_yaml['profile']: + section_yaml_file=sections['section'].lower() + '.yaml' + #check for custom section + if section_yaml_file in glob.glob1('../custom/sections/', '*.yaml'): + print(f"Custom settings found for section: {sections['section']}") + override_section = os.path.join('../custom/sections', sections['section'] + '.yaml') + with open(override_section) as r: + section_yaml = yaml.load(r, Loader=yaml.SafeLoader) + else: + with open('../sections/' + sections['section'] + '.yaml') as s: + section_yaml = yaml.load(s, Loader=yaml.SafeLoader) + + # Read section info and output it + + + section_adoc = adoc_section_template.substitute( + section_name = section_yaml['name'], + description = section_yaml['description'] + ) + + output_file.write(section_adoc) + + + # Read all rules in the section and output them + + for rule in sections['rules']: + print(rule) + rule_path = glob.glob('../rules/*/{}.yaml'.format(rule)) + rule_file = (os.path.basename(rule_path[0])) + + #check for custom rule + if rule_file in glob.glob1('../custom/rules/', '*.yaml'): + print(f"Custom settings found for rule: {rule_file}") + override_rule = os.path.join('../custom/rules', rule_file) + with open(override_rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + else: + with open(rule_path[0]) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + + + + # Determine if the references exist and set accordingly + try: + rule_yaml['references']['cci'] + except KeyError: + cci = 'N/A' + else: + cci = ulify(rule_yaml['references']['cci']) + + try: + rule_yaml['references']['cce'] + except KeyError: + cce = 'N/A' + else: + cce = ulify(rule_yaml['references']['cce']) + + try: + rule_yaml['references']['800-53r4'] + except KeyError: + nist_80053r4 = 'N/A' + else: + #nist_80053r4 = ulify(rule_yaml['references']['800-53r4']) + nist_80053r4 = rule_yaml['references']['800-53r4'] + + try: + rule_yaml['references']['disa_stig'] + except KeyError: + disa_stig = 'N/A' + else: + disa_stig = ulify(rule_yaml['references']['disa_stig']) + + try: + rule_yaml['references']['srg'] + except KeyError: + srg = 'N/A' + else: + srg = ulify(rule_yaml['references']['srg']) + + try: + rule_yaml['fix'] + except KeyError: + rulefix = "No fix Found" + else: + rulefix = rule_yaml['fix']#.replace('|', '\|') + + try: + rule_yaml['tags'] + except KeyError: + tags = 'none' + else: + tags = rule_yaml['tags'] + + try: + result = rule_yaml['result'] + except KeyError: + result = 'N/A' + + if "integer" in result: + result_value=result['integer'] + elif "boolean" in result: + result_value=result['boolean'] + elif "string" in result: + result_value=result['string'] + else: + result_value = 'N/A' + + # process nist controls for grouping + nist_80053r4.sort() + res = [list(i) for j, i in groupby(nist_80053r4, lambda a: a.split('(')[0])] + nist_controls = '' + for i in res: + nist_controls += group_ulify(i) + + if 'supplemental' in tags: + rule_adoc = adoc_supplemental_template.substitute( + rule_title=rule_yaml['title'].replace('|', '\|'), + rule_id=rule_yaml['id'].replace('|', '\|'), + rule_discussion=rule_yaml['discussion'], + ) + # elif ('permanent' in tags) or ('inherent' in tags) or ('n_a' in tags): + # rule_adoc = adoc_rule_no_setting_template.substitute( + # rule_title=rule_yaml['title'].replace('|', '\|'), + # rule_id=rule_yaml['id'].replace('|', '\|'), + # rule_discussion=rule_yaml['discussion'].replace('|', '\|'), + # rule_check=rule_yaml['check'], # .replace('|', '\|'), + # rule_fix=rulefix, + # rule_80053r4=nist_controls, + # rule_disa_stig=disa_stig, + # rule_srg=srg + # ) + else: + rule_adoc = adoc_rule_template.substitute( + rule_title = rule_yaml['title'].replace('|', '\|'), + rule_id = rule_yaml['id'].replace('|', '\|'), + rule_discussion = rule_yaml['discussion'].replace('|', '\|'), + rule_check = rule_yaml['check'],#.replace('|', '\|'), + rule_fix = rulefix, + rule_cci = cci, + rule_80053r4 = nist_controls, + rule_cce = cce, + rule_srg = srg, + rule_result = result_value + ) + + output_file.write(rule_adoc) + +# Create footer +footer_adoc = adoc_footer_template.substitute( +) + +# Output footer +output_file.write(footer_adoc) diff --git a/scripts/profile_generator.py b/scripts/profile_generator.py new file mode 100755 index 00000000..d03ac69a --- /dev/null +++ b/scripts/profile_generator.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python3 +# filename: profile_generator.py +# description: Creates .mobileconfig files for payloads from yaml rules + +import glob +import yaml +import types +import sys +import os +import os.path +import collections +import argparse +import plistlib +from uuid import uuid4 + +class PayloadDict: + """Class to create and manipulate Configuration Profiles. + The actual plist content can be accessed as a dictionary via the 'data' attribute. + """ + def __init__(self, identifier, uuid=False, removal_allowed=False, description='',organization='', displayname=''): + self.data = {} + self.data['PayloadVersion'] = 1 + self.data['PayloadOrganization'] = organization + if uuid: + self.data['PayloadUUID'] = uuid + else: + self.data['PayloadUUID'] = makeNewUUID() + if removal_allowed: + self.data['PayloadRemovalDisallowed'] = False + else: + self.data['PayloadRemovalDisallowed'] = True + self.data['PayloadType'] = 'Configuration' + self.data['PayloadScope'] = 'System' + self.data['PayloadDescription'] = description + self.data['PayloadDisplayName'] = displayname + self.data['PayloadIdentifier'] = identifier + self.data['ConsentText'] = { "default" : "THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER."} + + # An empty list for 'sub payloads' that we'll fill later + self.data['PayloadContent'] = [] + + + def _updatePayload(self, payload_content_dict): + """Update the profile with the payload settings. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + # Boilerplate + payload_dict['PayloadVersion'] = 1 + payload_dict['PayloadUUID'] = makeNewUUID() + payload_dict['PayloadEnabled'] = True + payload_dict['PayloadType'] = payload_content_dict['PayloadType'] + payload_dict['PayloadIdentifier'] = f"alacarte.macOS.{baseline_name}.{payload_dict['PayloadUUID']}" + + + payload_dict['PayloadContent'] = payload_content_dict + # Add the payload to the profile + self.data.update(payload_dict) + + def _addPayload(self, payload_content_dict): + """Add a payload to the profile. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + # Boilerplate + payload_dict['PayloadVersion'] = 1 + payload_dict['PayloadUUID'] = makeNewUUID() + payload_dict['PayloadEnabled'] = True + payload_dict['PayloadType'] = payload_content_dict['PayloadType'] + payload_dict['PayloadIdentifier'] = f"alacarte.macOS.{baseline_name}.{payload_dict['PayloadUUID']}" + + + payload_dict['PayloadContent'] = payload_content_dict + # Add the payload to the profile + #print payload_dict + del payload_dict['PayloadContent']['PayloadType'] + self.data['PayloadContent'].append(payload_dict) + + + def addNewPayload(self, payload_type, settings): + """Add a payload to the profile. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + # Boilerplate + payload_dict['PayloadVersion'] = 1 + payload_dict['PayloadUUID'] = makeNewUUID() + payload_dict['PayloadEnabled'] = True + payload_dict['PayloadType'] = payload_type + payload_dict['PayloadIdentifier'] = f"alacarte.macOS.{baseline_name}.{payload_dict['PayloadUUID']}" + + + # Add the settings to the payload + for setting in settings: + for k,v in setting.items(): + payload_dict[k] = v + + + # Add the payload to the profile + # + self.data['PayloadContent'].append(payload_dict) + + + def addMCXPayload(self, settings): + """Add a payload to the profile. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + keys = settings[1] + plist_dict = {} + for key in keys.split(): + plist_dict[key] = settings[2] + + + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + state = "Forced" + domain = settings[0] + + # Boilerplate + payload_dict[domain] = {} + payload_dict[domain][state] = [] + payload_dict[domain][state].append({}) + payload_dict[domain][state][0]['mcx_preference_settings'] = plist_dict + payload_dict['PayloadType'] = "com.apple.ManagedClient.preferences" + + + self._addPayload(payload_dict) + + + def finalizeAndSave(self, output_path): + """Perform last modifications and save to an output plist. + """ + + plistlib.dump(self.data, output_path) + +def makeNewUUID(): + return str(uuid4()) + +def concatenate_payload_settings(settings): + """Takes a list of dictionaries, removed duplicate entries and concatenates an array of settings for the same key + """ + settings_list = [] + settings_dict = {} + for item in settings: + for key, value in item.items(): + if isinstance(value, list): + settings_dict.setdefault(key, []).append(value[0]) + else: + settings_dict.setdefault(key, value) + if item not in settings_list: + settings_list.append(item) + + return [settings_dict] + + + +def main(): + global baseline_name + + # parse the arguments + parser = argparse.ArgumentParser( + description='Given a baseline, create mobileconfig files for a given baseline.') + parser.add_argument("baseline", default=None, + help="Baseline YAML file used to create the guide.", type=argparse.FileType('rt')) + + try: + results = parser.parse_args() + print('Profile YAML:', results.baseline.name) + except IOError as msg: + parser.error(str(msg)) + + # get the name of the baseline being used + baseline_basename = os.path.basename(results.baseline.name) + baseline_name = os.path.splitext(baseline_basename)[0].capitalize() + + # default values + organization = "macOS Security Compliance Project" + displayname = f"macOS {baseline_name} Baseline settings" + + # File path setup + file_dir = os.path.dirname(os.path.abspath(__file__)) + parent_dir = os.path.dirname(file_dir) + + # import profile_manifests.plist + manifests_file = os.path.join(parent_dir, 'includes', 'supported_payloads.yaml') + with open(manifests_file) as r: + manifests = yaml.load(r, Loader=yaml.SafeLoader) + + # Output folder + mobileconfig_output_path = os.path.join(parent_dir, 'build', 'mobileconfigs') + if not (os.path.isdir(mobileconfig_output_path)): + try: + os.mkdir(mobileconfig_output_path) + except OSError: + print ("Creation of the directory %s failed" % mobileconfig_output_path) + + # setup lists and dictionaries + profile_errors = [] + profile_types = {} + + # load the baseline.yaml file to process + profile_yaml = yaml.load(results.baseline, Loader=yaml.SafeLoader) + + # Read all rules in the section and output them + for sections in profile_yaml['profile']: + for profile_rule in sections['rules']: + for rule in glob.glob('../rules/*/{}.yaml'.format(profile_rule)): + rule_file=(os.path.basename(rule)) + + #check for custom rule + if rule_file in glob.glob1('../custom/rules/', '*.yaml'): + print(f"Custom settings found for rule: {rule_file}") + override_rule=os.path.join('../custom/rules', rule_file) + with open(override_rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + else: + with open(rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + + if rule_yaml['mobileconfig']: + for payload_type, info in rule_yaml['mobileconfig_info'].items(): + try: + if payload_type not in manifests['payloads_types']: + profile_errors.append(rule) + raise ValueError("{}: Payload Type is not supported".format(payload_type)) + else: + pass + except (KeyError, ValueError) as e: + profile_errors.append(rule) + print(e) + pass + + try: + if isinstance(info, list): + raise ValueError("Payload key is non-conforming") + else: + pass + except (KeyError, ValueError) as e: + profile_errors.append(rule) + print(e) + pass + + + if payload_type == "com.apple.ManagedClient.preferences": + for payload_domain, settings in info.items(): + for key, value in settings.items(): + payload_settings = (payload_domain, key, value) + profile_types.setdefault(payload_type,[]).append(payload_settings) + else: + for profile_key, key_value in info.items(): + payload_settings = {profile_key : key_value} + profile_types.setdefault(payload_type,[]).append(payload_settings) + + if len(profile_errors) > 0: + print("There are errors in the following files, please correct the .yaml file(s)!") + for error in profile_errors: + print(error) + # process the payloads from the yaml file and generate new config profile for each type + for payload,settings in profile_types.items(): + mobileconfig_file_path=os.path.join(mobileconfig_output_path,payload + '.mobileconfig') + identifier = payload + f".{baseline_name}" + description = "Configuration settings for the {} preference domain.".format(payload) + + newProfile = PayloadDict(identifier=identifier, + uuid=False, + removal_allowed=False, + organization=organization, + displayname=displayname, + description=description) + + config_file = open(mobileconfig_file_path, "wb") + + if payload == "com.apple.ManagedClient.preferences": + for item in settings: + newProfile.addMCXPayload(item) + elif (payload == "com.apple.applicationaccess.new") or (payload == 'com.apple.systempreferences'): #handle these payloads for array settings + newProfile.addNewPayload(payload, concatenate_payload_settings(settings)) + else: + newProfile.addNewPayload(payload, settings) + + newProfile.finalizeAndSave(config_file) + config_file.close() + +if __name__ == "__main__": + main() diff --git a/scripts/script_generator.py b/scripts/script_generator.py new file mode 100755 index 00000000..308178ff --- /dev/null +++ b/scripts/script_generator.py @@ -0,0 +1,411 @@ +#!/usr/bin/env python3 +# filename: script_generator.py +# description: Create a zsh script to apply the "fix" commands for every rule + +import io +import glob +import os +import yaml +import re +import plistlib +import argparse +from string import Template +from itertools import groupby + +# Convert a list to AsciiDoc +def group_ulify(elements): + string = "\n## " + for s in elements: + string += str(s) + ", " + return string[:-2] + +def get_check_code(check_yaml): + try: + check_string = check_yaml.split("[source,bash]")[1] + except: + return check_yaml + #print check_string + check_code = re.search('(?:----((?:.*?\r?\n?)*)----)+',check_string) + print(check_code.group(1).rstrip()) + return(check_code.group(1).strip()) + +def quotify(fix_code): + string = fix_code.replace("'", "\'\"\'\"\'") + string = string.replace("%", "%%") + + return string + +def get_fix_code(fix_yaml): + fix_string = fix_yaml.split("[source,bash]")[1] + fix_code = re.search('(?:----((?:.*?\r?\n?)*)----)+', fix_string) + return(fix_code.group(1)) + +# File path setup +file_dir = os.path.dirname(os.path.abspath(__file__)) +parent_dir = os.path.dirname(file_dir) + + +parser = argparse.ArgumentParser(description='Given a baseline, create a compliance script.') +parser.add_argument("baseline", default=None, help="Basline YAML file used to generate the script.", type=argparse.FileType('rt')) + + + +try: + results = parser.parse_args() + print ('Profile YAML:', results.baseline.name) +except IOError as msg: + parser.error(str(msg)) + +profile_yaml = yaml.load(results.baseline, Loader=yaml.SafeLoader) +profile_name = results.baseline.name.replace(".yaml","") +profile_name = profile_name.replace("../baselines/","") + +# Output files +sp80053_output_file = open(parent_dir + '/build/'+profile_name+'_controls.txt', 'w') +compliance_script_file = open(parent_dir + '/build/'+profile_name+'_compliance.sh', 'w') +sp80053_controls = [] + + + +# create header of fix zsh script +check_zsh_header=f"""#!/bin/zsh + +## This script will attempt to audit all of the settings based on the installed profile. + +## This script is provided as-is and should be fully tested on a system that is not in a production environment. + +################### COMMANDS START BELOW THIS LINE ################### + +## Must be run as root +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +# get the currently logged in user +CURRENT_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ {{ print $3 }}') + +# configure colors for text +RED='\e[31m' +STD='\033[0;0;39m' +GREEN='\e[32m' +YELLOW='\e[33m' + +# setup files +audit_plist="/Library/Preferences/org.{profile_name}.audit.plist" +audit_log="/Library/Logs/{profile_name}_baseline.log" + +lastComplianceScan=$(defaults read /Library/Preferences/org.{profile_name}.audit.plist lastComplianceCheck) + +if [[ $lastComplianceScan == "" ]];then + lastComplianceScan="No scans have been run" +fi + +# pause function +pause(){{ + vared -p "Press [Enter] key to continue..." -c fackEnterKey +}} + +ask() {{ + while true; do + + if [ "${{2:-}}" = "Y" ]; then + prompt="Y/n" + default=Y + elif [ "${{2:-}}" = "N" ]; then + prompt="y/N" + default=N + else + prompt="y/n" + default= + fi + + # Ask the question - use /dev/tty in case stdin is redirected from somewhere else + printf "${{YELLOW}} $1 [$prompt] ${{STD}}" + read REPLY + + # Default? + if [ -z "$REPLY" ]; then + REPLY=$default + fi + + # Check if the reply is valid + case "$REPLY" in + Y*|y*) return 0 ;; + N*|n*) return 1 ;; + esac + + done +}} + +# function to display menus +show_menus() {{ + clear + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo " M A I N - M E N U" + echo " macOS Security Compliance Tool" + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + echo "Last compliance scan: $lastComplianceScan\n" + echo "1. View Last Compliance Report" + echo "2. Run New Compliance Scan" + echo "3. Run Commands to remediate non-compliant settings" + echo "4. Exit" +}} + +# function to read options +read_options(){{ + local choice + vared -p "Enter choice [ 1 - 4 ] " -c choice + case $choice in + 1) view_report ;; + 2) run_scan ;; + 3) run_fix ;; + 4) exit 0;; + *) echo -e "${{RED}}Error: please choose an option 1-4...${{STD}}" && sleep 1 + esac +}} + +generate_report(){{ + non_compliant=0 + compliant=0 + + results=$(/usr/libexec/PlistBuddy -c "Print" /Library/Preferences/org.{profile_name}.audit.plist) + + while IFS= read -r line; do + if [[ "$line" =~ "true" ]]; then + non_compliant=$((non_compliant+1)) + fi + if [[ "$line" =~ "false" ]]; then + compliant=$((compliant+1)) + fi + + done <<< "$results" + total=$((non_compliant + compliant)) + percentage=$(printf %.2f $(( compliant * 100. / total )) ) + echo + echo "Number of tests passed: ${{GREEN}}$compliant${{STD}}" + echo "Number of test FAILED: ${{RED}}$non_compliant${{STD}}" + echo "You are ${{YELLOW}}$percentage%${{STD}} percent compliant!" + pause +}} + +view_report(){{ + + if [[ $lastComplianceScan == "" ]];then + echo "no report to run, please run new scan" + pause + else + generate_report + fi +}} + +run_scan(){{ +# append to existing logfile +echo "$(date -u) Beginning {profile_name} baseline scan" >> "$audit_log" + +# write timestamp of last compliance check +defaults write "$audit_plist" lastComplianceCheck "$(date)" +""" + +compliance_script_file.write(check_zsh_header) + +# Read all rules in the section and output the check functions +for sections in profile_yaml['profile']: + for profile_rule in sections['rules']: + for rule in glob.glob('../rules/*/{}.yaml'.format(profile_rule)): + rule_file = (os.path.basename(rule)) + + #check for custom rule + if rule_file in glob.glob1('../custom/rules/', '*.yaml'): + print(f"Custom settings found for rule: {rule_file}") + override_rule = os.path.join('../custom/rules', rule_file) + with open(override_rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + else: + with open(rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + + + if rule_yaml['id'].startswith("supplemental"): + #print "supplemental" + continue + + + # grab the 800-53 controls + try: + rule_yaml['references']['800-53r4'] + except KeyError: + nist_80053r4 = 'N/A' + else: + nist_80053r4 = rule_yaml['references']['800-53r4'] + sp80053_controls.extend(rule_yaml['references']['800-53r4']) + + + # group the controls + nist_80053r4.sort() + res = [list(i) for j, i in groupby(nist_80053r4, lambda a: a.split('(')[0])] + nist_controls = '' + for i in res: + nist_controls += group_ulify(i) + + + # print checks and result + try: + check=rule_yaml['check'] + except KeyError: + print("no check found for {}".format(rule_yaml['id'])) + continue + try: + result=rule_yaml['result'] + except KeyError: + #print("no result found for {}".format(rule_yaml['id'])) + continue + + + if "integer" in result: + result_value=result['integer'] + elif "boolean" in result: + result_value=result['boolean'] + elif "string" in result: + result_value=result['string'] + else: + continue + + + # write the checks + zsh_check_text=""" +#####----- Rule: {0} -----##### +## Addresses the following NIST 800-53 controls: {1} +echo 'Running the command to check the settings for: {0} ...' | tee -a "$audit_log" +result_value=$({2}) +# expected result {3} + +if [[ $result_value == "{4}" ]]; then + echo "{0} passed..." | tee -a "$audit_log" + defaults write "$audit_plist" {0} -bool NO +else + echo "{0} FAILED..." | tee -a "$audit_log" + defaults write "$audit_plist" {0} -bool YES +fi +""".format(rule_yaml['id'], nist_controls, check.strip(), result, result_value) + + compliance_script_file.write(zsh_check_text) + +# write the footer for the check functions +zsh_check_footer = """ +lastComplianceScan=$(defaults read "$audit_plist" lastComplianceCheck) + +pause +} + +run_fix(){ + +if [[ ! -e "$audit_plist" ]]; then + echo "Audit plist doesn't exist, please run Audit Check First" >> "$audit_log" + echo "Audit plist doesn't exist, please run Audit Check First" + pause + show_menus + read_options +fi + + +ask 'THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.' N + +if [[ $? != 0 ]]; then + show_menus + read_options +fi + +# append to existing logfile +echo "$(date -u) Beginning FISMA fixes" >> "$audit_log" + + +""" +compliance_script_file.write(zsh_check_footer) + +# Read all rules in the section and output the fix functions +for sections in profile_yaml['profile']: + for profile_rule in sections['rules']: + for rule in glob.glob('../rules/*/{}.yaml'.format(profile_rule)): + rule_file = (os.path.basename(rule)) + + #check for custom rule + if rule_file in glob.glob1('../custom/rules/', '*.yaml'): + print(f"Custom settings found for rule: {rule_file}") + override_rule = os.path.join('../custom/rules', rule_file) + with open(override_rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + else: + with open(rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + + if rule_yaml['id'].startswith("supplemental"): + #print "supplemental" + continue + + # grab the 800-53 controls + try: + rule_yaml['references']['800-53r4'] + except KeyError: + nist_80053r4 = 'N/A' + else: + nist_80053r4 = rule_yaml['references']['800-53r4'] + sp80053_controls.extend(rule_yaml['references']['800-53r4']) + + # group the controls + nist_80053r4.sort() + res = [list(i) for j, i in groupby( + nist_80053r4, lambda a: a.split('(')[0])] + nist_controls = '' + for i in res: + nist_controls += group_ulify(i) + + # print fix and result + try: + rule_yaml['fix'] + except KeyError: + fix_text = 'N/A' + else: + fix_text = rule_yaml['fix'] or ["n/a"] + + # write the fixes + if "[source,bash]" in fix_text: + zsh_fix_text = f""" +#####----- Rule: {rule_yaml['id']} -----##### +## Addresses the following NIST 800-53 controls: {nist_controls} + +{rule_yaml['id']}_audit_score=$(defaults read $audit_plist {rule_yaml['id']}) +if [[ ${rule_yaml['id']}_audit_score == 1 ]]; then + ask '{rule_yaml['id']} - Run the command(s)-> {quotify(get_fix_code(rule_yaml['fix']).strip())} ' N + if [[ $? == 0 ]]; then + echo 'Running the command to configure the settings for: {rule_yaml['id']} ...' | tee -a "$audit_log" + {get_fix_code(rule_yaml['fix']).strip()} + fi +else + echo 'Settings for: {rule_yaml['id']} already configured, continuing...' | tee -a "$audit_log" +fi +""" + + compliance_script_file.write(zsh_fix_text) + +# write the footer for the check functions +zsh_fix_footer=""" +} +while true; do + show_menus + read_options +done +""" +compliance_script_file.write(zsh_fix_footer) + +sp80053_controls = list( dict.fromkeys(sp80053_controls)) +sp80053_controls.sort() + +sp80053_output_file.writelines("%s\n" % control for control in sp80053_controls) + +# make the compliance script executable +os.chmod(compliance_script_file.name, 0o755) + +#fix_script_file.close() +compliance_script_file.close() +sp80053_output_file.close() \ No newline at end of file diff --git a/scripts/yaml-to-xls.py b/scripts/yaml-to-xls.py new file mode 100755 index 00000000..a829c1dd --- /dev/null +++ b/scripts/yaml-to-xls.py @@ -0,0 +1,404 @@ +#!/usr/bin/env python3 +# filename: yaml-to-xls.py +# Document baseline in Microsoft Excel format +import io +import glob +import os +import yaml +import xlwt +import types +import collections +import plistlib +import argparse + +from xlwt import Workbook +from string import Template +from itertools import groupby +from uuid import uuid4 + +# File path setup +file_dir = os.path.dirname(os.path.abspath(__file__)) +parent_dir = os.path.dirname(file_dir) +# CCEs + +def listToString(s): + + # initialize an empty string + str1 = "" + + # traverse in the string + for ele in s: + str1 += ele + + # return string + return str1 + + +class PayloadDict: + """Class to create and manipulate Configuration Profiles. + The actual plist content can be accessed as a dictionary via the 'data' attribute. + """ + def __init__(self, identifier, uuid=False, removal_allowed=False, description='',organization='', displayname=''): + self.data = {} + self.data['PayloadVersion'] = 1 + self.data['PayloadOrganization'] = organization + if uuid: + self.data['PayloadUUID'] = uuid + else: + self.data['PayloadUUID'] = makeNewUUID() + if removal_allowed: + self.data['PayloadRemovalDisallowed'] = False + else: + self.data['PayloadRemovalDisallowed'] = True + self.data['PayloadType'] = 'Configuration' + self.data['PayloadScope'] = 'System' + self.data['PayloadDescription'] = description + self.data['PayloadDisplayName'] = displayname + self.data['PayloadIdentifier'] = identifier + + # An empty list for 'sub payloads' that we'll fill later + self.data['PayloadContent'] = [] + + + def _updatePayload(self, payload_content_dict): + """Update the profile with the payload settings. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + # Boilerplate + payload_dict['PayloadVersion'] = 1 + payload_dict['PayloadUUID'] = makeNewUUID() + payload_dict['PayloadEnabled'] = True + payload_dict['PayloadType'] = payload_content_dict['PayloadType'] + payload_dict['PayloadIdentifier'] = "alacarte.macOS.FISMA.%s" % ( + payload_dict['PayloadUUID']) + + + payload_dict['PayloadContent'] = payload_content_dict + # Add the payload to the profile + #print payload_dict + self.data.update(payload_dict) + + def _addPayload(self, payload_content_dict): + """Add a payload to the profile. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + # Boilerplate + payload_dict['PayloadVersion'] = 1 + payload_dict['PayloadUUID'] = makeNewUUID() + payload_dict['PayloadEnabled'] = True + payload_dict['PayloadType'] = payload_content_dict['PayloadType'] + payload_dict['PayloadIdentifier'] = "alacarte.macOS.FISMA.%s" % ( + payload_dict['PayloadUUID']) + + + payload_dict['PayloadContent'] = payload_content_dict + # Add the payload to the profile + #print payload_dict + del payload_dict['PayloadContent']['PayloadType'] + self.data['PayloadContent'].append(payload_dict) + + + def addNewPayload(self, payload_type, settings): + """Add a payload to the profile. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + #description = "Configuration settings for the {} preference domain.".format(payload_type) + payload_dict = {} + + # Boilerplate + payload_dict['PayloadVersion'] = 1 + payload_dict['PayloadUUID'] = makeNewUUID() + payload_dict['PayloadEnabled'] = True + payload_dict['PayloadType'] = payload_type + payload_dict['PayloadIdentifier'] = "alacarte.macOS.FISMA.%s" % ( + payload_dict['PayloadUUID']) + + + # Add the settings to the payload + for setting in settings: + for k,v in setting.items(): + payload_dict[k] = v + + + # Add the payload to the profile + # + self.data['PayloadContent'].append(payload_dict) + + + def addMCXPayload(self, settings): + """Add a payload to the profile. Takes the settings dictionary which will be the + PayloadContent dict within the payload. Handles the boilerplate, naming and descriptive + elements. + """ + keys = settings[1] + plist_dict = {} + for key in keys.split(): + plist_dict[key] = settings[2] + + + + payload_dict = {} + + state = "Forced" + domain = settings[0] + + # Boilerplate + payload_dict[domain] = {} + payload_dict[domain][state] = [] + payload_dict[domain][state].append({}) + payload_dict[domain][state][0]['mcx_preference_settings'] = plist_dict + payload_dict['PayloadType'] = "com.apple.ManagedClient.preferences" + + + self._addPayload(payload_dict) + + + def finalizeAndSave(self, output_path): + """Perform last modifications and save to an output plist. + """ + writePlist(self.data, output_path) + + +def makeNewUUID(): + return str(uuid4()) + +def configProfile(rule): + # default values + organization = "macOS Security Compliance Project Working Group" + displayname = "macOS FISMA Baseline settings" + + # File path setup + file_dir = os.path.dirname(os.path.abspath(__file__)) + parent_dir = os.path.dirname(file_dir) + + # import profile_manifests.plist + manifests_file = os.path.join(parent_dir, 'includes', 'supported_payloads.yaml') + with open(manifests_file) as r: + manifests = yaml.load(r, Loader=yaml.SafeLoader) + + # Output folder + mobileconfig_output_path = os.path.join(parent_dir, 'build', 'mobileconfigs') + + + profile_errors = [] + profile_types = {} + + + + # Read all rules in the section and output them + + + payload_type = '' + with open(rule) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + if rule_yaml['mobileconfig']: + + for payload_type, info in rule_yaml['mobileconfig_info'].items(): + try: + if payload_type not in manifests['payloads_types']: + profile_errors.append(rule) + raise ValueError("{}: Payload Type is not supported".format(payload_type)) + else: + pass + except (KeyError, ValueError) as e: + profile_errors.append(rule) + print(e) + pass + + try: + if isinstance(info, list): + raise ValueError("Payload key is non-conforming") + else: + pass + except (KeyError, ValueError) as e: + profile_errors.append(rule) + print(e) + pass + + + if payload_type == "com.apple.ManagedClient.preferences": + for payload_domain, settings in info.items(): + for key, value in settings.items(): + payload_settings = (payload_domain, key, value) + profile_types.setdefault(payload_type,[]).append(payload_settings) + else: + for profile_key, key_value in info.items(): + payload_settings = {profile_key : key_value} + profile_types.setdefault(payload_type,[]).append(payload_settings) + + if len(profile_errors) > 0: + print("There are errors in the following files, please correct the .yaml file(s)!") + for error in profile_errors: + print(error) + + # process the payloads from the yaml file and generate new config profile for each type + for payload,settings in profile_types.items(): + mobileconfig_file_path=os.path.join(mobileconfig_output_path,payload + '.mobileconfig') + identifier = payload + ".FISMA" + description = "Configuration settings for the {} preference domain.".format(payload) + + newProfile = PayloadDict(identifier=identifier, + uuid=False, + removal_allowed=False, + organization=organization, + displayname=displayname, + description=description) + + + if payload == "com.apple.ManagedClient.preferences": + for item in settings: + newProfile.addMCXPayload(item) + else: + newProfile.addNewPayload(payload, settings) + + data = plistlib.dumps(newProfile.data).decode("utf-8") + + return data + + + +parser = argparse.ArgumentParser(description='Given a profile, create an Excel Spreadsheet for documentation.') +parser.add_argument("baseline", default=None, help="Baseline YAML file used to create the guide.", type=argparse.FileType('rt')) +parser.add_argument("-o", "--output", default=None, help="Output file", type=argparse.FileType('wt')) + +try: + results = parser.parse_args() + output_basename = os.path.basename(results.baseline.name) + output_filename = os.path.splitext(output_basename)[0] + output_file = "../build/{}.xls".format(output_filename) + print ('Profile YAML:', results.baseline.name) + print ('Output file:', output_file) + +except IOError as msg: + parser.error(str(msg)) + +profile_yaml = yaml.load(results.baseline, Loader=yaml.SafeLoader) + +wb = Workbook() + +sheet1 = wb.add_sheet('Sheet 1') +topWrap = xlwt.easyxf("align: vert top; alignment: wrap True") +top = xlwt.easyxf("align: vert top") +headers = xlwt.easyxf("font: bold on") +counter = 1 +sheet1.write(0,0, "CCE",headers) +sheet1.write(0,1, "Rule ID",headers) +sheet1.write(0,2, "Title",headers) +sheet1.write(0,3, "Discussion",headers) +sheet1.write(0,4, "Mechanism",headers) +sheet1.write(0,5, "Check",headers) +sheet1.write(0,6, "Check Result",headers) +sheet1.write(0,7, "Fix",headers) +sheet1.write(0,8, "800-53r4",headers) +sheet1.write(0,9, "SRG",headers) +sheet1.write(0,10, "DISA STIG",headers) +sheet1.write(0,11, "CCI",headers) +sheet1.set_panes_frozen(True) +sheet1.set_horz_split_pos(1) +sheet1.set_vert_split_pos(2) + + +for sections in profile_yaml['profile']: + for profile_rule in sections['rules']: + for rule_file in glob.glob('../rules/*/{}.yaml'.format(profile_rule)): + + if "srg" in rule_file or "supplemental" in rule_file: + continue + + with open(rule_file) as r: + rule_yaml = yaml.load(r, Loader=yaml.SafeLoader) + + check = rule_yaml['check'] + + + result = " " + try: + result = str(rule_yaml['result']) + except KeyError: + result = "" + + cce = "" + try: + cce = rule_yaml['references']['cce'] + except KeyError: + cce = "" + + sheet1.write(counter,0, cce,top) + sheet1.col(0).width = 256 * 15 + sheet1.write(counter,1, rule_yaml['id'],top) + sheet1.col(1).width = 512 * 25 + sheet1.write(counter,2, rule_yaml['title'],top) + sheet1.col(2).width = 600 * 30 + sheet1.write(counter,3, str(rule_yaml['discussion']),topWrap) + sheet1.col(3).width = 700 * 35 + mechanism = "Manual" + if "[source,bash]" in rule_yaml['fix']: + mechanism = "Scipt" + if "This is implemented by a Configuration Profile." in rule_yaml['fix']: + mechanism = "Configuration Profile" + if "inherent" in rule_file: + mechanism = "The control cannot be configured out of compliance." + if "permanent" in rule_file: + mechanism = "The control is not able to be configure to meet the requirement. It is recommended to implement a third-party solution to meet the control." + if "not_applicable" in rule_file: + mechanism = " The control is not applicable when configuring a macOS system." + + + sheet1.write(counter,4,mechanism,top) + sheet1.col(4).width = 256 * 25 + + sheet1.write(counter,5, check,topWrap) + sheet1.col(5).width = 750 * 50 + + sheet1.write(counter,6,result,topWrap) + sheet1.col(6).width = 256 * 25 + + if rule_yaml['mobileconfig']: + + + sheet1.write(counter,7,str(configProfile(rule_file)),topWrap) + else: + + sheet1.write(counter,7, str(rule_yaml['fix']),topWrap) + + sheet1.col(7).width = 1000 * 50 + + baseline_refs = (str(rule_yaml['references']['800-53r4'])).strip('[]\'') + baseline_refs = baseline_refs.replace(", ","\n").replace("\'","") + + sheet1.write(counter,8, baseline_refs,topWrap) + sheet1.col(8).width = 256 * 15 + + srg_refs = (str(rule_yaml['references']['srg'])).strip('[]\'') + srg_refs = srg_refs.replace(", ","\n").replace("\'","") + + sheet1.write(counter,9, srg_refs,topWrap) + sheet1.col(9).width = 500 * 15 + + disa_refs = (str(rule_yaml['references']['disa_stig'])).strip('[]\'') + disa_refs = srg_refs.replace(", ","\n").replace("\'","") + + sheet1.write(counter,10, disa_refs,topWrap) + sheet1.col(10).width = 500 * 15 + + cci = (str(rule_yaml['references']['cci'])).strip('[]\'') + cci = cci.replace(", ","\n").replace("\'","") + + sheet1.write(counter,11, cci,topWrap) + sheet1.col(11).width = 400 * 15 + + tall_style = xlwt.easyxf('font:height 640;') # 36pt + + sheet1.row(counter).set_style(tall_style) + counter = counter + 1 + +wb.save(output_file) diff --git a/sections/auditing.yaml b/sections/auditing.yaml new file mode 100644 index 00000000..6a0d7605 --- /dev/null +++ b/sections/auditing.yaml @@ -0,0 +1,3 @@ + name: "Auditing" + description: | + This section reviews the configuration and enforcement of the OpenBSM settings. \ No newline at end of file diff --git a/sections/authentication.yaml b/sections/authentication.yaml new file mode 100644 index 00000000..0996bec0 --- /dev/null +++ b/sections/authentication.yaml @@ -0,0 +1,3 @@ + name: "Authentication" + description: | + This section reviews the configuration and enforcement of smartcard authentication. \ No newline at end of file diff --git a/sections/icloud.yaml b/sections/icloud.yaml new file mode 100644 index 00000000..c583b3ee --- /dev/null +++ b/sections/icloud.yaml @@ -0,0 +1,3 @@ + name: "iCloud" + description: | + This section reviews the configuration and enforcement of iCloud and the Apple ID service. \ No newline at end of file diff --git a/sections/inherent.yaml b/sections/inherent.yaml new file mode 100644 index 00000000..508b96b5 --- /dev/null +++ b/sections/inherent.yaml @@ -0,0 +1,3 @@ + name: "Inherent" + description: | + This section reviews the controls that are built-in to macOS, and cannot be configured out of compliance. \ No newline at end of file diff --git a/sections/macos.yaml b/sections/macos.yaml new file mode 100644 index 00000000..73f0ef0a --- /dev/null +++ b/sections/macos.yaml @@ -0,0 +1,3 @@ + name: "macOS" + description: | + This section reviews the configuration and enforcement of operating system level settings. \ No newline at end of file diff --git a/sections/not_applicable.yaml b/sections/not_applicable.yaml new file mode 100644 index 00000000..6aac7319 --- /dev/null +++ b/sections/not_applicable.yaml @@ -0,0 +1,3 @@ + name: "Not Applicable" + description: | + This section reviews the controls that are defined in the NIST 800-53 revision 4, but are not applicable when configuring a macOS system. \ No newline at end of file diff --git a/sections/passwordpolicy.yaml b/sections/passwordpolicy.yaml new file mode 100644 index 00000000..6d6fe432 --- /dev/null +++ b/sections/passwordpolicy.yaml @@ -0,0 +1,10 @@ + name: "Password Policy" + description: | + This section reviews the configuration and enforcement of password policies in macOS. + + NOTE: The settings outlined in this section follows recommendations for system that utilize passwords for accounts local to the system. If directory services is being utilized, password policies should come from the domain. + + [IMPORTANT] + ==== + Until 800-53 revision 5 is officially published, the password policy recommendations within fall under 800-53 rev4. 800-53 rev4 was released with the guidance published in 800-63 at the time, however, 800-63 has been revised a number of times since then. At this time the recommendation is for organizations to adopt the newer published guidance within 800-63. + ==== \ No newline at end of file diff --git a/sections/permanent.yaml b/sections/permanent.yaml new file mode 100644 index 00000000..8c5f9b62 --- /dev/null +++ b/sections/permanent.yaml @@ -0,0 +1,3 @@ + name: "Permanent Findings" + description: | + This section reviews the controls that are defined in the NIST 800-53 revision 4, but are unable to be configured natively within macOS. It is recommended to implement a third-party solution to meet the control. \ No newline at end of file diff --git a/sections/supplemental.yaml b/sections/supplemental.yaml new file mode 100644 index 00000000..98060c81 --- /dev/null +++ b/sections/supplemental.yaml @@ -0,0 +1,3 @@ + name: "Supplemental" + description: | + This sections provides additional information to support the guidance provided by the baselines. \ No newline at end of file diff --git a/sections/systempreferences.yaml b/sections/systempreferences.yaml new file mode 100644 index 00000000..0da2930b --- /dev/null +++ b/sections/systempreferences.yaml @@ -0,0 +1,3 @@ + name: "System Preferences" + description: | + This section reviews the configuration and enforcement of the settings within the macOS System Preferences application. \ No newline at end of file diff --git a/templates/adoc_acronyms.adoc b/templates/adoc_acronyms.adoc new file mode 100644 index 00000000..67e802e7 --- /dev/null +++ b/templates/adoc_acronyms.adoc @@ -0,0 +1,25 @@ +== Acronyms and Definitions +.Acronyms and Abbreviations +[width="100%",cols="1,3"] +|==== +|ABM|Apple Business Manager +|AFP|Apple Filing Protocol +|API|Application Programming Interface +|ARD|Apple Remote Desktop +|CA|Certificate Authority +|DISA|Defense Information Systems Agency +|FISMA|Federal Information Security Modernization Act +|FPKI|Federal Public Key Infrastructure +|MDM|Mobile Device Management +|NASA|National Aeronautics and Space Administration +|NIST|National Institute of Standards and Technology +|NSA|National Security Agency +|PIV|Personal Identity Verification +|PIV-M|Personal Identity Verification Mandatory +|PKI|Public Key Infrastructure +|SIP|System Integrity Protection +|SMB|Server Message Block +|SSH|Secure Shell +|STIG|Security Technical Implementation Guide +|UAMDM|User Approved MDM +|==== \ No newline at end of file diff --git a/templates/adoc_additional_docs.adoc b/templates/adoc_additional_docs.adoc new file mode 100644 index 00000000..11604d68 --- /dev/null +++ b/templates/adoc_additional_docs.adoc @@ -0,0 +1,55 @@ +== Applicable Documents +=== Government Documents +//// +ASSOCIATED DOCUMENTS + Add Government and Non-Government documents related to this handbook in this section. + Add to the tables between the |==== tags, below the header line + Example: + [%header, cols=2*a] <-- table format block + |==== <-- table opening tag + |Document Number|Document Title <-- header line + <-- empty line for readability (optional) + |NPR 2810.1|Security of Information Technology <-- + |NASA-SPEC-0000|Super Special NASA Doc <-- + <-- empty line for readability (optional) + |==== <-- table closing tag +//// +[%header, cols=2*a] +.National Institute of Standards and Technology (NIST) +|=== +|Document Number +|Document Title +|link:https://nvd.nist.gov/800-53[NIST Special Publication 800-53 Rev 4]|_NIST Special Publication 800-53 Rev 4_ +|=== + +[%header, cols=2*a] +.National Institute of Standards and Technology (NIST) +|=== +|Document Number +|Document Title +|link:https://www.nist.gov/itl/tig/projects/special-publication-800-63[NIST Special Publication 800-63]|_NIST Special Publication 800-63_ +|=== + +[%header, cols=2*a] +.Defense Information Systems Agency (DISA) +|=== +|Document Number +|Document Title +|link:https://www.stigviewer.com/stig/apple_os_x_10.14_mojave/[STIG Ver 1, Rel 1]|_Apple OS X 10.14(Mojave) STIG_ +|=== +=== Non-Government Documents +[%header, cols=2*a] +.Apple +|=== +|Document Number +|Document Title +|link:https://support.apple.com/guide/mdm/welcome/web[Mobile Device Management Settings]|_Mobile Device Management Settings_ +|=== + +[%header, cols=2*a] +.Apple +|=== +|Document Number +|Document Title +|link:https://developer.apple.com/documentation/devicemanagement/profile-specific_payload_keys[Apple Developer]|_Profile-Specific Payload Keys_ +|=== diff --git a/templates/adoc_footer.adoc b/templates/adoc_footer.adoc new file mode 100644 index 00000000..e69de29b diff --git a/templates/adoc_header.adoc b/templates/adoc_header.adoc new file mode 100644 index 00000000..96ae86b3 --- /dev/null +++ b/templates/adoc_header.adoc @@ -0,0 +1,76 @@ += $profile_title +:doctype: book +// Document Setup +// :pdf-fontsdir: ../templates/fonts/ +:pdf-stylesdir: ../templates/ +:stylesdir: ../templates/ +:pdf-style: asciidoctor-pdf.yml +:stylesheet: asciidoctor.css +:notitle: +:numbered: +:data-uri: +:allow-uri-read: +:icons: font +:chapter-label: +:source-highlighter: rouge +// Table of Contents +:toc: macro +:toc-title: TABLE OF CONTENTS +:toclevels: 4 +:sectnumlevels: 4 +:toc-placement!: +// Title Page Variables +:document-type: +:document-identifier: +:document-title: $profile_title +:document-subtitle: SECURITY COMPLIANCE +:approved-date: 2020-XX-XX +// document process versions: "Initial Draft", "Informal Draft", "Formal Draft", "Final Draft", "Baseline" +:version: Baseline +:revision-date: 2019-12-16 + + +// xrefstyle full shows the section number and title +:xrefstyle: full + +// Do not show the footer for HTML +ifdef::backend-html5[] +:nofooter: +endif::[] + +// An additional title is needed for PDF output +ifdef::backend-pdf[] +[colophon] += {nbsp} +endif::[] + +// Title Page +include::../templates/title_page.adoc[] + +toc::[] + +== Foreword + +The macOS security compliance project is an open source effort to provide a programmatic approach to generating security guidance. This project can be used to create customized security baselines of technical security controls by leveraging a library of atomic actions which are mapped to compliance requirements in existing security guides or used to develop customized guidance. Through the use of a library of atomic actions that enhance security, and mapping them back to existing guides and policies, a single project can support multiple security guides and regulated industry policies while also allowing for documentation and QA to be uniformly managed through a single effort. This approach simplifies, and radically accelerates, the updating of annual security guidance through a unification and standardization of effort. + + +// Authors +== Authors +[width="100%",cols="1,3"] +|=== +|Bob Gendler|National Institute of Standards and Technology +|Allen Golbig|National Aeronautics and Space Administration +|Dan Brodjieski|Defense Information Systems Agency +|Jason Blake|National Institute of Standards and Technology +|Blair Heiserman|National Institute of Standards and Technology +|Joshua Glemza|National Aeronautics and Space Administration +|Elyse Anderson|National Aeronautics and Space Administration +|Paige Ramsey|Los Alamos National Laboratory +|=== + +// Acronyms +include::../templates/adoc_acronyms.adoc[] + +// References +include::../templates/adoc_additional_docs.adoc[] + diff --git a/templates/adoc_rule.adoc b/templates/adoc_rule.adoc new file mode 100644 index 00000000..83f209a1 --- /dev/null +++ b/templates/adoc_rule.adoc @@ -0,0 +1,40 @@ +=== $rule_title + +$rule_discussion + +To check the state of the system, run the following command(s): +[source,bash] +---- +$rule_check +---- + +If the result is not *$rule_result*, this is a finding. + +Perform the following to configure the system to meet the requirments: + +$rule_fix + +[cols="15%h, 85%a"] +|=== + +|ID +|$rule_id + +|References +| + +[cols="20%h,80%a"] +[frame="none"] +[grid="cols"] +!=== + +!800-53r4 +!$rule_80053r4 + +!CCE +!$rule_cce + +!=== + +| +|=== diff --git a/templates/adoc_rule.orig b/templates/adoc_rule.orig new file mode 100644 index 00000000..01dbf8fd --- /dev/null +++ b/templates/adoc_rule.orig @@ -0,0 +1,37 @@ +### $rule_title + +[cols="15%h, 85%a"] +|=== + +|ID +|$rule_id + +|Severity +|$rule_severity + +|Discussion +|$rule_discussion + +|Check +|[source,bash] +---- +$rule_check +---- + +|Fix +|$rule_fix + +|CCI +|$rule_cci + +|NIST SP 800-53 Rev 4 +|$rule_80053r4 + +|DISA STIG +|$rule_disa_stig + +|SRG +|$rule_srg + +|=== + diff --git a/templates/adoc_rule_no_setting.adoc b/templates/adoc_rule_no_setting.adoc new file mode 100644 index 00000000..77645948 --- /dev/null +++ b/templates/adoc_rule_no_setting.adoc @@ -0,0 +1,27 @@ +=== $rule_title + +$rule_discussion + +$rule_check + +[cols="15%h, 85%a"] +|=== + +|ID +|$rule_id + +|References +| + +[cols="20%h,80%a"] +[frame="none"] +[grid="cols"] +!=== + +!800-53r4 +!$rule_80053r4 + +!=== + +| +|=== diff --git a/templates/adoc_rules_table_footer.adoc b/templates/adoc_rules_table_footer.adoc new file mode 100644 index 00000000..feaabada --- /dev/null +++ b/templates/adoc_rules_table_footer.adoc @@ -0,0 +1 @@ +|=== \ No newline at end of file diff --git a/templates/adoc_rules_table_header.adoc b/templates/adoc_rules_table_header.adoc new file mode 100644 index 00000000..525c9ee4 --- /dev/null +++ b/templates/adoc_rules_table_header.adoc @@ -0,0 +1,9 @@ += macOS Rules +:stylesheet: + +[%header,width="100%",cols="10%,25%,65%a",opts="wrap"] +|=== + +|ID +|Title +|Discussion \ No newline at end of file diff --git a/templates/adoc_rules_table_row.adoc b/templates/adoc_rules_table_row.adoc new file mode 100644 index 00000000..f167071b --- /dev/null +++ b/templates/adoc_rules_table_row.adoc @@ -0,0 +1,3 @@ +|**$rule_id** +|$rule_title +|$rule_discussion diff --git a/templates/adoc_section.adoc b/templates/adoc_section.adoc new file mode 100644 index 00000000..33f9caaf --- /dev/null +++ b/templates/adoc_section.adoc @@ -0,0 +1,4 @@ +== $section_name + +$description + diff --git a/templates/adoc_supplemental.adoc b/templates/adoc_supplemental.adoc new file mode 100644 index 00000000..6b3ad18b --- /dev/null +++ b/templates/adoc_supplemental.adoc @@ -0,0 +1,4 @@ +=== $rule_title + +$rule_discussion + diff --git a/templates/asciidoctor-pdf.yml b/templates/asciidoctor-pdf.yml new file mode 100644 index 00000000..5f757f8d --- /dev/null +++ b/templates/asciidoctor-pdf.yml @@ -0,0 +1,325 @@ +font: + # catalog: + # # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols + # Noto Serif: + # normal: notoserif-regular-subset.ttf + # bold: notoserif-bold-subset.ttf + # italic: notoserif-italic-subset.ttf + # bold_italic: notoserif-bold_italic-subset.ttf + # # Arial supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols + # # Arial: + # # normal: Arial.TTF + # # bold: Arialbd.TTF + # # italic: Ariali.TTF + # # bold_italic: Arialbi.TTF + # # # M+ 1mn supports ASCII and the circled numbers used for conums + # M+ 1mn: + # normal: mplus1mn-regular-ascii-conums.ttf + # bold: mplus1mn-bold-ascii.ttf + # italic: mplus1mn-italic-ascii.ttf + # bold_italic: mplus1mn-bold_italic-ascii.ttf + # # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols + # # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font + # M+ 1p Fallback: + # normal: mplus1p-regular-fallback.ttf + # bold: mplus1p-regular-fallback.ttf + # italic: mplus1p-regular-fallback.ttf + # bold_italic: mplus1p-regular-fallback.ttf + # fallbacks: + # - M+ 1p Fallback +page: + background_color: ffffff + layout: portrait + margin: [0.5in, 0.67in, 0.67in, 0.67in] + # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress + margin_inner: 0.75in + margin_outer: 0.59in + size: LETTER + #size: A4 +base: + align: justify + # color as hex string (leading # is optional) + font_color: 333333 + # color as RGB array + #font_color: [51, 51, 51] + # color as CMYK array (approximated) + #font_color: [0, 0, 0, 0.92] + #font_color: [0, 0, 0, 92%] + #font_family: Noto Serif + #font_family: Arial + #font_family: Courier + # choose one of these font_size/line_height_length combinations + #font_size: 14 + #line_height_length: 20 + #font_size: 11.25 + #line_height_length: 18 + #font_size: 11.2 + #line_height_length: 16 + #font_size: 10.5 + font_size: 10.0 + #line_height_length: 15 + # correct line height for Noto Serif metrics + line_height_length: 12 + #font_size: 11.25 + #line_height_length: 18 + line_height: $base_line_height_length / $base_font_size + font_size_large: round($base_font_size * 1.25) + font_size_small: round($base_font_size * 0.85) + font_size_min: $base_font_size * 0.75 + font_style: normal + border_color: eeeeee + border_radius: 4 + border_width: 0.5 +# FIXME vertical_rhythm is weird; we should think in terms of ems +#vertical_rhythm: $base_line_height_length * 2 / 3 +# correct line height for Noto Serif metrics (comes with built-in line height) +vertical_rhythm: $base_line_height_length +horizontal_rhythm: $base_line_height_length +# QUESTION should vertical_spacing be block_spacing instead? +vertical_spacing: $vertical_rhythm +link: + font_color: 428bca +# literal is currently used for inline monospaced in prose and table cells +literal: + font_color: b12146 + #font_family: M+ 1mn +menu_caret_content: " \u203a " +heading: + align: left + #font_color: 181818 + #font_color: ba3925 + font_color: $base_font_color + #font_family: $base_font_family + font_style: bold + # h1 is used for part titles (book doctype only) + h1_font_size: floor($base_font_size * 2.6) + h1_text_transform: uppercase + # h2 is used for chapter titles (book doctype only) + h2_font_size: floor($base_font_size * 2.15) + h2_text_transform: uppercase + h3_font_size: round($base_font_size * 1.7) + h4_font_size: $base_font_size_large + h5_font_size: $base_font_size + h6_font_size: $base_font_size_small + #line_height: 1.4 + # correct line height for Noto Serif metrics (comes with built-in line height) + line_height: 1 + margin_top: $vertical_rhythm * 0.4 + margin_bottom: $vertical_rhythm * 0.9 +title_page: + align: right + logo: + top: 10% + title: + top: 55% + font_size: $heading_h1_font_size + font_color: 999999 + line_height: 0.9 + subtitle: + font_size: $heading_h3_font_size + font_style: bold_italic + line_height: 1 + authors: + margin_top: $base_font_size * 1.25 + font_size: $base_font_size_large + font_color: 181818 + revision: + margin_top: $base_font_size * 1.25 +block: + margin_top: 0 + margin_bottom: $vertical_rhythm +caption: + align: left + #align: right + font_size: $base_font_size * 0.95 + font_style: italic + # FIXME perhaps set line_height instead of / in addition to margins? + margin_inside: $vertical_rhythm / 3 + #margin_inside: $vertical_rhythm / 4 + margin_outside: 0 +lead: + font_size: $base_font_size_large + line_height: 1.4 +abstract: + font_color: 5c6266 + font_size: $lead_font_size + line_height: $lead_line_height + font_style: italic + first_line_font_style: bold + title: + align: center + font_color: $heading_font_color + #font_family: $heading_font_family + font_size: $heading_h4_font_size + font_style: $heading_font_style +admonition: + column_rule_color: $base_border_color + column_rule_width: $base_border_width + padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] + #icon: + # tip: + # name: fa-lightbulb-o + # stroke_color: 111111 + # size: 24 + label: + text_transform: uppercase + font_style: bold +blockquote: + font_color: $base_font_color + font_size: $base_font_size_large + border_color: $base_border_color + border_width: 5 + # FIXME disable negative padding bottom once margin collapsing is implemented + padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] + cite_font_size: $base_font_size_small + cite_font_color: 999999 +# code is used for source blocks (perhaps change to source or listing?) +code: + font_color: $base_font_color + #font_family: $literal_font_family + font_size: ceil($base_font_size) + padding: $code_font_size + line_height: 1.25 + # line_gap is an experimental property to control how a background color is applied to an inline block element + line_gap: 3.8 + background_color: f5f5f5 + border_color: cccccc + border_radius: $base_border_radius + border_width: 0.75 +conum: + #font_family: M+ 1mn + font_color: $literal_font_color + font_size: $base_font_size + line_height: 4 / 3 +example: + border_color: $base_border_color + border_radius: $base_border_radius + border_width: 0.75 + background_color: ffffff + # FIXME reenable padding bottom once margin collapsing is implemented + padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] +image: + align: left +prose: + margin_top: $block_margin_top + margin_bottom: $block_margin_bottom +sidebar: + background_color: eeeeee + border_color: e1e1e1 + border_radius: $base_border_radius + border_width: $base_border_width + # FIXME reenable padding bottom once margin collapsing is implemented + padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] + title: + align: center + font_color: $heading_font_color + #font_family: $heading_font_family + font_size: $heading_h4_font_size + font_style: $heading_font_style +thematic_break: + border_color: $base_border_color + border_style: solid + border_width: $base_border_width + margin_top: $vertical_rhythm * 0.5 + margin_bottom: $vertical_rhythm * 1.5 +description_list: + term_font_style: bold + term_spacing: $vertical_rhythm / 4 + description_indent: $horizontal_rhythm * 1.25 +outline_list: + indent: $horizontal_rhythm * 1.5 + #marker_font_color: 404040 + # NOTE outline_list_item_spacing applies to list items that do not have complex content + item_spacing: $vertical_rhythm / 2 +table: + background_color: $page_background_color + #font_family: Arial + #font_size: 9.5 + #head_background_color: + #head_font_color: $base_font_color + head: + font_style: bold + #font_size: 9.5 + background_color: f9f9f9 + #body_background_color: + body_stripe_background_color: f9f9f9 + foot_background_color: f0f0f0 + border_color: dddddd + border_width: $base_border_width + cell_padding: 3 +toc: + indent: $horizontal_rhythm + line_height: 1.4 + dot_leader: + #content: ". " + font_color: a9a9a9 + #levels: 2 3 +# NOTE in addition to footer, header is also supported +header: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + border_color: dddddd + border_width: 0.25 + height: $base_line_height_length * 2.5 + line_height: 1 + padding: [$base_line_height_length / 2, 1, 0, 1] + vertical_align: top + #image_vertical_align: or + # additional attributes for content: + # * {page-count} + # * {page-number} + # * {document-title} + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + #columns: "<50% =0% >50%" + #right: + #content: '{page-number}' + #content: '{section-or-chapter-title} | {page-number}' + #content: '{document-title} | {page-number}' + center: + #content: '{version} -- {document-title} -- {revision-date}' + content: '{document-title}' + verso: + #columns: $footer_recto_columns + #left: + #content: $footer_recto_right_content + #content: '{page-number} | {chapter-title}' + center: + #content: '{version} -- {document-title} -- {revision-date}' + content: '{document-title}' +footer: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + border_color: dddddd + border_width: 0.25 + height: $base_line_height_length * 2.5 + line_height: 1 + padding: [$base_line_height_length / 2, 1, 0, 1] + vertical_align: top + #image_vertical_align: or + # additional attributes for content: + # * {page-count} + # * {page-number} + # * {document-title} + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + #columns: "<50% =0% >50%" + #right: + #content: '{page-number}' + #content: '{section-or-chapter-title} | {page-number}' + #content: '{document-title} | {page-number}' + center: + content: '{page-number} of {page-count}' + verso: + #columns: $footer_recto_columns + #left: + #content: $footer_recto_right_content + #content: '{page-number} | {chapter-title}' + center: + content: '{page-number} of {page-count}' \ No newline at end of file diff --git a/templates/asciidoctor.css b/templates/asciidoctor.css new file mode 100644 index 00000000..3856dd62 --- /dev/null +++ b/templates/asciidoctor.css @@ -0,0 +1,430 @@ +/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */ +/* Uncomment @import statement below to use as custom stylesheet */ +/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block} +audio,canvas,video{display:inline-block} +audio:not([controls]){display:none;height:0} +script{display:none!important} +html{font-family:"sans-serif",Arial;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} +a{background:transparent} +a:focus{outline:thin dotted} +a:active,a:hover{outline:0} +h1{font-size:2em;margin:.67em 0} +abbr[title]{border-bottom:1px dotted} +b,strong{font-weight:bold} +dfn{font-style:italic} +hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} +mark{background:#ff0;color:#000} +code,kbd,pre,samp{font-family:monospace;font-size:1em} +pre{white-space:pre-wrap} +q{quotes:"\201C" "\201D" "\2018" "\2019"} +small{font-size:80%} +sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} +sup{top:-.5em} +sub{bottom:-.25em} +img{border:0} +svg:not(:root){overflow:hidden} +figure{margin:0} +fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} +legend{border:0;padding:0} +button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} +button,input{line-height:normal} +button,select{text-transform:none} +button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} +button[disabled],html input[disabled]{cursor:default} +input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} +button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} +textarea{overflow:auto;vertical-align:top} +table{border-collapse:collapse;border-spacing:0} +*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} +html,body{font-size:100%} +body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",Arial,"serif","Open Sans";font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} +a:hover{cursor:pointer} +img,object,embed{max-width:100%;height:auto} +object,embed{height:100%} +img{-ms-interpolation-mode:bicubic} +.left{float:left!important} +.right{float:right!important} +.text-left{text-align:left!important} +.text-right{text-align:right!important} +.text-center{text-align:center!important} +.text-justify{text-align:justify!important} +.hide{display:none} +img,object,svg{display:inline-block;vertical-align:middle} +textarea{height:auto;min-height:50px} +select{width:100%} +.center{margin-left:auto;margin-right:auto} +.spread{width:100%} +.stretch{width:100%} +/*.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}*/ +.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#333333;font-weight:400;margin-top:0;margin-bottom:.25em} +div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr} +a{color:#2156a5;text-decoration:underline;line-height:inherit} +a:hover,a:focus{color:#1d4b8f} +a img{border:none} +p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} +p aside{font-size:.875em;line-height:1.35;font-style:italic} +/*h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",Arial,"sans-serif";font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} +h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}*/ +h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",Arial,"sans-serif";font-weight:300;font-style:normal;color:#333333;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} +h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#333333;line-height:0}*/ +h1{font-size:2.125em; text-transform:uppercase;} +h2{font-size:1.6875em; text-transform:uppercase;} +h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} +h4,h5{font-size:1.125em} +h6{font-size:1em} +hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} +em,i{font-style:italic;line-height:inherit} +strong,b{font-weight:bold;line-height:inherit} +small{font-size:60%;line-height:inherit} +code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} +ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} +ul,ol{margin-left:1.5em} +ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} +ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} +ul.square{list-style-type:square} +ul.circle{list-style-type:circle} +ul.disc{list-style-type:disc} +ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} +dl dt{margin-bottom:.3125em;font-weight:bold} +dl dd{margin-bottom:1.25em} +abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} +abbr{text-transform:none} +blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} +blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)} +blockquote cite::before{content:"\2014 \0020"} +blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)} +blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} +@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} +h1{font-size:2.75em;text-transform:uppercase;} +h2{font-size:2.3125em;text-transform:uppercase;} +h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} +h4{font-size:1.4375em}} +table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede} +table thead,table tfoot{background:#f7f8f7} +table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} +table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} +table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7} +table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6} +h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} +h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} +.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} +.clearfix::after,.float-group::after{clear:both} +*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word} +*:not(pre)>code.nobreak{word-wrap:normal} +*:not(pre)>code.nowrap{white-space:nowrap} +pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed} +em em{font-style:normal} +strong strong{font-weight:400} +.keyseq{color:rgba(51,51,51,.8)} +kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} +.keyseq kbd:first-child{margin-left:0} +.keyseq kbd:last-child{margin-right:0} +.menuseq,.menuref{color:#000} +.menuseq b:not(.caret),.menuref{font-weight:inherit} +.menuseq{word-spacing:-.02em} +.menuseq b.caret{font-size:1.25em;line-height:.8} +.menuseq i.caret{font-weight:bold;text-align:center;width:.45em} +b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} +b.button::before{content:"[";padding:0 3px 0 2px} +b.button::after{content:"]";padding:0 2px 0 3px} +p a>code:hover{color:rgba(0,0,0,.9)} +#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} +#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} +#header::after,#content::after,#footnotes::after,#footer::after{clear:both} +#content{margin-top:1.25em} +#content::before{content:none} +#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} +#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8} +#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px} +#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} +#header .details span:first-child{margin-left:-.125em} +#header .details span.email a{color:rgba(0,0,0,.85)} +#header .details br{display:none} +#header .details br+span::before{content:"\00a0\2013\00a0"} +#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} +#header .details br+span#revremark::before{content:"\00a0|\00a0"} +#header #revnumber{text-transform:capitalize} +#header #revnumber::after{content:"\00a0"} +#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} +#toc{border-bottom:1px solid #efefed;padding-bottom:.5em} +#toc>ul{margin-left:.125em} +#toc ul.sectlevel0>li>a{font-style:italic} +#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} +#toc ul{font-family:"Open Sans","DejaVu Sans",Arial,"sans-serif";list-style-type:none} +#toc li{line-height:1.3334;margin-top:.3334em} +#toc a{text-decoration:none} +#toc a:active{text-decoration:underline} +/*#toctitle{color:#7a2518;font-size:1.2em}*/ +#toctitle{color:#333333;font-size:1.2em} +@media screen and (min-width:768px){#toctitle{font-size:1.375em} +body.toc2{padding-left:15em;padding-right:0} +#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} +#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} +#toc.toc2>ul{font-size:.9em;margin-bottom:0} +#toc.toc2 ul ul{margin-left:0;padding-left:1em} +#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} +body.toc2.toc-right{padding-left:0;padding-right:15em} +body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}} +@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} +#toc.toc2{width:20em} +#toc.toc2 #toctitle{font-size:1.375em} +#toc.toc2>ul{font-size:.95em} +#toc.toc2 ul ul{padding-left:1.25em} +body.toc2.toc-right{padding-left:0;padding-right:20em}} +#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} +#content #toc>:first-child{margin-top:0} +#content #toc>:last-child{margin-bottom:0} +#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em} +#footer-text{color:rgba(255,255,255,.8);line-height:1.44} +#content{margin-bottom:.625em} +.sect1{padding-bottom:.625em} +@media screen and (min-width:768px){#content{margin-bottom:1.25em} +.sect1{padding-bottom:1.25em}} +.sect1:last-child{padding-bottom:0} +.sect1+.sect1{border-top:1px solid #efefed} +#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} +#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} +#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} +/*#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} +#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}*/ +#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#333333;text-decoration:none} +#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#333333} +.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} +.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",Arial,"serif";font-size:1rem;font-style:italic} +table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} +.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)} +table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit} +.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} +.admonitionblock>table td.icon{text-align:center;width:80px} +.admonitionblock>table td.icon img{max-width:none} +.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} +.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)} +.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} +.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} +.exampleblock>.content>:first-child{margin-top:0} +.exampleblock>.content>:last-child{margin-bottom:0} +.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} +.sidebarblock>:first-child{margin-top:0} +.sidebarblock>:last-child{margin-bottom:0} +/*.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}*/ +.sidebarblock>.content>.title{color:#333333;margin-top:0;text-align:center} +.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8} +.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1} +.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em} +.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal} +@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}} +@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}} +.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)} +.listingblock pre.highlightjs{padding:0} +.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} +.listingblock pre.prettyprint{border-width:0} +.listingblock>.content{position:relative} +.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999} +.listingblock:hover code[data-lang]::before{display:block} +.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999} +.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} +table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none} +table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45} +table.pyhltable td.code{padding-left:.75em;padding-right:0} +pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8} +pre.pygments .lineno{display:inline-block;margin-right:.25em} +table.pyhltable .linenodiv{background:none!important;padding-right:0!important} +.quoteblock{margin:0 1em 1.25em 1.5em;display:table} +.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em} +.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} +.quoteblock blockquote{margin:0;padding:0;border:0} +/*.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}*/ +.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#333333;text-shadow:0 1px 2px rgba(0,0,0,.1)} +.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} +.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right} +.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)} +.quoteblock .quoteblock blockquote{padding:0 0 0 .75em} +.quoteblock .quoteblock blockquote::before{display:none} +.verseblock{margin:0 1em 1.25em} +.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} +.verseblock pre strong{font-weight:400} +.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} +.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} +.quoteblock .attribution br,.verseblock .attribution br{display:none} +.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} +.quoteblock.abstract{margin:0 1em 1.25em;display:block} +.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} +.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{word-spacing:0;line-height:1.6} +.quoteblock.abstract blockquote::before,.quoteblock.abstract p::before{display:none} +table.tableblock{max-width:100%;border-collapse:separate} +p.tableblock:last-child{margin-bottom:0} +td.tableblock>.content{margin-bottom:-1.25em} +table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} +table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0} +table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0} +table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0} +table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px} +table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0} +/*table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}*/ +table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0} +table.frame-all{border-width:1px} +table.frame-sides{border-width:0 1px} +table.frame-topbot,table.frame-ends{border-width:1px 0} +table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7} +table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none} +th.halign-left,td.halign-left{text-align:left} +th.halign-right,td.halign-right{text-align:right} +th.halign-center,td.halign-center{text-align:center} +th.valign-top,td.valign-top{vertical-align:top} +th.valign-bottom,td.valign-bottom{vertical-align:bottom} +th.valign-middle,td.valign-middle{vertical-align:middle} +table thead th,table tfoot th{font-weight:bold} +tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7} +tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} +p.tableblock>code:only-child{background:none;padding:0} +p.tableblock{font-size:1em} +td>div.verse{white-space:pre} +ol{margin-left:1.75em} +ul li ol{margin-left:1.5em} +dl dd{margin-left:1.125em} +dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} +ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} +ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} +ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} +ul.unstyled,ol.unstyled{margin-left:0} +ul.checklist{margin-left:.625em} +ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em} +ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em} +ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} +ul.inline>li{margin-left:1.25em} +.unstyled dl dt{font-weight:400;font-style:normal} +ol.arabic{list-style-type:decimal} +ol.decimal{list-style-type:decimal-leading-zero} +ol.loweralpha{list-style-type:lower-alpha} +ol.upperalpha{list-style-type:upper-alpha} +ol.lowerroman{list-style-type:lower-roman} +ol.upperroman{list-style-type:upper-roman} +ol.lowergreek{list-style-type:lower-greek} +.hdlist>table,.colist>table{border:0;background:none} +.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} +td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} +td.hdlist1{font-weight:bold;padding-bottom:1.25em} +.literalblock+.colist,.listingblock+.colist{margin-top:-.5em} +.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} +.colist td:not([class]):first-child img{max-width:none} +.colist td:not([class]):last-child{padding:.25em 0} +.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} +.imageblock.left{margin:.25em .625em 1.25em 0} +.imageblock.right{margin:.25em 0 1.25em .625em} +.imageblock>.title{margin-bottom:0} +.imageblock.thumb,.imageblock.th{border-width:6px} +.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} +.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} +.image.left{margin-right:.625em} +.image.right{margin-left:.625em} +a.image{text-decoration:none;display:inline-block} +a.image object{pointer-events:none} +sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} +sup.footnote a,sup.footnoteref a{text-decoration:none} +sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} +#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} +#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} +#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} +#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} +#footnotes .footnote:last-of-type{margin-bottom:0} +#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} +.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} +.gist .file-data>table td.line-data{width:99%} +div.unbreakable{page-break-inside:avoid} +.big{font-size:larger} +.small{font-size:smaller} +.underline{text-decoration:underline} +.overline{text-decoration:overline} +.line-through{text-decoration:line-through} +.aqua{color:#00bfbf} +.aqua-background{background-color:#00fafa} +.black{color:#000} +.black-background{background-color:#000} +.blue{color:#0000bf} +.blue-background{background-color:#0000fa} +.fuchsia{color:#bf00bf} +.fuchsia-background{background-color:#fa00fa} +.gray{color:#606060} +.gray-background{background-color:#7d7d7d} +.green{color:#006000} +.green-background{background-color:#007d00} +.lime{color:#00bf00} +.lime-background{background-color:#00fa00} +.maroon{color:#600000} +.maroon-background{background-color:#7d0000} +.navy{color:#000060} +.navy-background{background-color:#00007d} +.olive{color:#606000} +.olive-background{background-color:#7d7d00} +.purple{color:#600060} +.purple-background{background-color:#7d007d} +.red{color:#bf0000} +.red-background{background-color:#fa0000} +.silver{color:#909090} +.silver-background{background-color:#bcbcbc} +.teal{color:#006060} +.teal-background{background-color:#007d7d} +.white{color:#bfbfbf} +.white-background{background-color:#fafafa} +.yellow{color:#bfbf00} +.yellow-background{background-color:#fafa00} +span.icon>.fa{cursor:default} +a span.icon>.fa{cursor:inherit} +.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} +.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} +.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} +.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} +.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} +.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} +.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",Arial,"sans-serif";font-style:normal;font-weight:bold} +.conum[data-value] *{color:#fff!important} +.conum[data-value]+b{display:none} +.conum[data-value]::after{content:attr(data-value)} +pre .conum[data-value]{position:relative;top:-.125em} +b.conum *{color:inherit!important} +.conum:not([data-value]):empty{display:none} +dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} +h1,h2,p,td.content,span.alt{letter-spacing:-.01em} +p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} +p,blockquote,dt,td.content,span.alt{font-size:1.0625rem} +p{margin-bottom:1.25rem} +.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} +.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} +.print-only{display:none!important} +@page{margin:1.25cm .75cm} +@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} +html{font-size:80%} +a{color:inherit!important;text-decoration:underline!important} +a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} +a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} +abbr[title]::after{content:" (" attr(title) ")"} +pre,blockquote,tr,img,object,svg{page-break-inside:avoid} +thead{display:table-header-group} +svg{max-width:100%} +p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} +h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} +#toc,.sidebarblock,.exampleblock>.content{background:none!important} +#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important} +body.book #header{text-align:center} +body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} +body.book #header .details{border:0!important;display:block;padding:0!important} +body.book #header .details span:first-child{margin-left:0!important} +body.book #header .details br{display:block} +body.book #header .details br+span::before{content:none!important} +body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} +body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} +.listingblock code[data-lang]::before{display:block} +#footer{padding:0 .9375em} +.hide-on-print{display:none!important} +.print-only{display:block!important} +.hide-for-print{display:none!important} +.show-for-print{display:inherit!important}} +@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem} +.sect1{padding:0!important} +.sect1+.sect1{border:0} +#footer{background:none} +#footer-text{color:rgba(0,0,0,.6);font-size:.9em}} +@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} +table.grid-all {border-collapse: collapse;} \ No newline at end of file diff --git a/templates/asciidoctor2.css b/templates/asciidoctor2.css new file mode 100644 index 00000000..90c48075 --- /dev/null +++ b/templates/asciidoctor2.css @@ -0,0 +1,2092 @@ +/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */ +/* Uncomment @import statement below to use as custom stylesheet */ +/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/ +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block +} + +audio, canvas, video { + display: inline-block +} + +audio:not([controls]) { + display: none; + height: 0 +} + +script { + display: none !important +} + +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} + +a { + background: transparent +} + +a:focus { + outline: thin dotted +} + +a:active, a:hover { + outline: 0 +} + +h1 { + font-size: 2em; + margin: .67em 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, strong { + font-weight: bold +} + +dfn { + font-style: italic +} + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0 +} + +mark { + background: #ff0; + color: #000 +} + +code, kbd, pre, samp { + font-family: monospace; + font-size: 1em +} + +pre { + white-space: pre-wrap +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019" +} + +small { + font-size: 80% +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -.5em +} + +sub { + bottom: -.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 0 +} + +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: .35em .625em .75em +} + +legend { + border: 0; + padding: 0 +} + +button, input, select, textarea { + font-family: inherit; + font-size: 100%; + margin: 0 +} + +button, input { + line-height: normal +} + +button, select { + text-transform: none +} + +button, html input[type="button"], input[type="reset"], input[type="submit"] { + -webkit-appearance: button; + cursor: pointer +} + +button[disabled], html input[disabled] { + cursor: default +} + +input[type="checkbox"], input[type="radio"] { + box-sizing: border-box; + padding: 0 +} + +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0 +} + +textarea { + overflow: auto; + vertical-align: top +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +*, * ::before, * ::after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box +} + +html, body { + font-size: 100% +} + +body { + background: #fff; + color: rgba(0, 0, 0, .8); + padding: 0; + margin: 0; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-weight: 400; + font-style: normal; + line-height: 1; + position: relative; + cursor: auto; + tab-size: 4; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased +} + +a:hover { + cursor: pointer +} + +img, object, embed { + max-width: 100%; + height: auto +} + +object, embed { + height: 100% +} + +img { + -ms-interpolation-mode: bicubic +} + +.left { + float: left !important +} + +.right { + float: right !important +} + +.text-left { + text-align: left !important +} + +.text-right { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +.text-justify { + text-align: justify !important +} + +.hide { + display: none +} + +img, object, svg { + display: inline-block; + vertical-align: middle +} + +textarea { + height: auto; + min-height: 50px +} + +select { + width: 100% +} + +.center { + margin-left: auto; + margin-right: auto +} + +.stretch { + width: 100% +} + +.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { + line-height: 1.45; + color: #7a2518; + font-weight: 400; + margin-top: 0; + margin-bottom: .25em +} + +div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { + margin: 0; + padding: 0; + direction: ltr +} + +a { + color: #2156a5; + text-decoration: underline; + line-height: inherit +} + +a:hover, a:focus { + color: #1d4b8f +} + +a img { + border: none +} + +p { + font-family: inherit; + font-weight: 400; + font-size: 1em; + line-height: 1.6; + margin-bottom: 1.25em; + text-rendering: optimizeLegibility +} + +p aside { + font-size: .875em; + line-height: 1.35; + font-style: italic +} + +h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-weight: 300; + font-style: normal; + color: #ba3925; + text-rendering: optimizeLegibility; + margin-top: 1em; + margin-bottom: .5em; + line-height: 1.0125em +} + +h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { + font-size: 60%; + color: #e99b8f; + line-height: 0 +} + +h1 { + font-size: 2.125em +} + +h2 { + font-size: 1.6875em +} + +h3, #toctitle, .sidebarblock > .content > .title { + font-size: 1.375em +} + +h4, h5 { + font-size: 1.125em +} + +h6 { + font-size: 1em +} + +hr { + border: solid #ddddd8; + border-width: 1px 0 0; + clear: both; + margin: 1.25em 0 1.1875em; + height: 0 +} + +em, i { + font-style: italic; + line-height: inherit +} + +strong, b { + font-weight: bold; + line-height: inherit +} + +small { + font-size: 60%; + line-height: inherit +} + +code { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + color: rgba(0, 0, 0, .9) +} + +ul, ol, dl { + font-size: 1em; + line-height: 1.6; + margin-bottom: 1.25em; + list-style-position: outside; + font-family: inherit +} + +ul, ol { + margin-left: 1.5em +} + +ul li ul, ul li ol { + margin-left: 1.25em; + margin-bottom: 0; + font-size: 1em +} + +ul.square li ul, ul.circle li ul, ul.disc li ul { + list-style: inherit +} + +ul.square { + list-style-type: square +} + +ul.circle { + list-style-type: circle +} + +ul.disc { + list-style-type: disc +} + +ol li ul, ol li ol { + margin-left: 1.25em; + margin-bottom: 0 +} + +dl dt { + margin-bottom: .3125em; + font-weight: bold +} + +dl dd { + margin-bottom: 1.25em +} + +abbr, acronym { + text-transform: uppercase; + font-size: 90%; + color: rgba(0, 0, 0, .8); + border-bottom: 1px dotted #ddd; + cursor: help +} + +abbr { + text-transform: none +} + +blockquote { + margin: 0 0 1.25em; + padding: .5625em 1.25em 0 1.1875em; + border-left: 1px solid #ddd +} + +blockquote cite { + display: block; + font-size: .9375em; + color: rgba(0, 0, 0, .6) +} + +blockquote cite::before { + content: "\2014 \0020" +} + +blockquote cite a, blockquote cite a:visited { + color: rgba(0, 0, 0, .6) +} + +blockquote, blockquote p { + line-height: 1.6; + color: rgba(0, 0, 0, .85) +} + +@media screen and (min-width: 768px) { + h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + line-height: 1.2 + } + + h1 { + font-size: 2.75em + } + + h2 { + font-size: 2.3125em + } + + h3, #toctitle, .sidebarblock > .content > .title { + font-size: 1.6875em + } + + h4 { + font-size: 1.4375em + } +} + +table { + background: #fff; + margin-bottom: 1.25em; + border: solid 1px #dedede +} + +table thead, table tfoot { + background: #f7f8f7 +} + +table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { + padding: .5em .625em .625em; + font-size: inherit; + color: rgba(0, 0, 0, .8); + text-align: left +} + +table tr th, table tr td { + padding: .5625em .625em; + font-size: inherit; + color: rgba(0, 0, 0, .8) +} + +table tr.even, table tr.alt, table tr:nth-of-type(even) { + background: #f8f8f7 +} + +table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { + display: table-cell; + line-height: 1.6 +} + +h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + line-height: 1.2; + word-spacing: -.05em +} + +h1 strong, h2 strong, h3 strong, #toctitle strong, .sidebarblock > .content > .title strong, h4 strong, h5 strong, h6 strong { + font-weight: 400 +} + +.clearfix::before, .clearfix::after, .float-group::before, .float-group::after { + content: " "; + display: table +} + +.clearfix::after, .float-group::after { + clear: both +} + +* :not(pre) > code { + font-size: .9375em; + font-style: normal !important; + letter-spacing: 0; + padding: .1em .5ex; + word-spacing: -.15em; + background-color: #f7f7f8; + -webkit-border-radius: 4px; + border-radius: 4px; + line-height: 1.45; + text-rendering: optimizeSpeed; + word-wrap: break-word +} + +* :not(pre) > code.nobreak { + word-wrap: normal +} + +* :not(pre) > code.nowrap { + white-space: nowrap +} + +pre, pre > code { + line-height: 1.45; + color: rgba(0, 0, 0, .9); + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + text-rendering: optimizeSpeed +} + +em em { + font-style: normal +} + +strong strong { + font-weight: 400 +} + +.keyseq { + color: rgba(51, 51, 51, .8) +} + +kbd { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + display: inline-block; + color: rgba(0, 0, 0, .8); + font-size: .65em; + line-height: 1.45; + background-color: #f7f7f7; + border: 1px solid #ccc; + -webkit-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 0 0 .1em white inset; + box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 0 0 .1em #fff inset; + margin: 0 .15em; + padding: .2em .5em; + vertical-align: middle; + position: relative; + top: -.1em; + white-space: nowrap +} + +.keyseq kbd:first-child { + margin-left: 0 +} + +.keyseq kbd:last-child { + margin-right: 0 +} + +.menuseq, .menuref { + color: #000 +} + +.menuseq b:not(.caret), .menuref { + font-weight: inherit +} + +.menuseq { + word-spacing: -.02em +} + +.menuseq b.caret { + font-size: 1.25em; + line-height: .8 +} + +.menuseq i.caret { + font-weight: bold; + text-align: center; + width: .45em +} + +b.button::before, b.button::after { + position: relative; + top: -1px; + font-weight: 400 +} + +b.button::before { + content: "["; + padding: 0 3px 0 2px +} + +b.button::after { + content: "]"; + padding: 0 2px 0 3px +} + +p a > code:hover { + color: rgba(0, 0, 0, .9) +} + +#header, #content, #footnotes, #footer { + width: 100%; + margin-left: auto; + margin-right: auto; + margin-top: 0; + margin-bottom: 0; + max-width: 62.5em; + * zoom:1; + position: relative; + padding-left: .9375em; + padding-right: .9375em +} + +#header::before, #header::after, #content::before, #content::after, #footnotes::before, #footnotes::after, #footer::before, #footer::after { + content: " "; + display: table +} + +#header::after, #content::after, #footnotes::after, #footer::after { + clear: both +} + +#content { + margin-top: 1.25em +} + +#content::before { + content: none +} + +#header > h1:first-child { + color: rgba(0, 0, 0, .85); + margin-top: 2.25rem; + margin-bottom: 0 +} + +#header > h1:first-child + #toc { + margin-top: 8px; + border-top: 1px solid #ddddd8 +} + +#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { + border-bottom: 1px solid #ddddd8; + padding-bottom: 8px +} + +#header .details { + border-bottom: 1px solid #ddddd8; + line-height: 1.45; + padding-top: .25em; + padding-bottom: .25em; + padding-left: .25em; + color: rgba(0, 0, 0, .6); + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-flow: row wrap; + -webkit-flex-flow: row wrap; + flex-flow: row wrap +} + +#header .details span:first-child { + margin-left: -.125em +} + +#header .details span.email a { + color: rgba(0, 0, 0, .85) +} + +#header .details br { + display: none +} + +#header .details br + span::before { + content: "\00a0\2013\00a0" +} + +#header .details br + span.author::before { + content: "\00a0\22c5\00a0"; + color: rgba(0, 0, 0, .85) +} + +#header .details br + span#revremark::before { + content: "\00a0|\00a0" +} + +#header #revnumber { + text-transform: capitalize +} + +#header #revnumber::after { + content: "\00a0" +} + +#content > h1:first-child:not([class]) { + color: rgba(0, 0, 0, .85); + border-bottom: 1px solid #ddddd8; + padding-bottom: 8px; + margin-top: 0; + padding-top: 1rem; + margin-bottom: 1.25rem +} + +#toc { + border-bottom: 1px solid #efefed; + padding-bottom: .5em +} + +#toc > ul { + margin-left: .125em +} + +#toc ul.sectlevel0 > li > a { + font-style: italic +} + +#toc ul.sectlevel0 ul.sectlevel1 { + margin: .5em 0 +} + +#toc ul { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + list-style-type: none +} + +#toc li { + line-height: 1.3334; + margin-top: .3334em +} + +#toc a { + text-decoration: none +} + +#toc a:active { + text-decoration: underline +} + +#toctitle { + color: #7a2518; + font-size: 1.2em +} + +@media screen and (min-width: 768px) { + #toctitle { + font-size: 1.375em + } + + body.toc2 { + padding-left: 15em; + padding-right: 0 + } + + #toc.toc2 { + margin-top: 0 !important; + background-color: #f8f8f7; + position: fixed; + width: 15em; + left: 0; + top: 0; + border-right: 1px solid #efefed; + border-top-width: 0 !important; + border-bottom-width: 0 !important; + z-index: 1000; + padding: 1.25em 1em; + height: 100%; + overflow: auto + } + + #toc.toc2 #toctitle { + margin-top: 0; + margin-bottom: .8rem; + font-size: 1.2em + } + + #toc.toc2 > ul { + font-size: .9em; + margin-bottom: 0 + } + + #toc.toc2 ul ul { + margin-left: 0; + padding-left: 1em + } + + #toc.toc2 ul.sectlevel0 ul.sectlevel1 { + padding-left: 0; + margin-top: .5em; + margin-bottom: .5em + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 15em + } + + body.toc2.toc-right #toc.toc2 { + border-right-width: 0; + border-left: 1px solid #efefed; + left: auto; + right: 0 + } +} + +@media screen and (min-width: 1280px) { + body.toc2 { + padding-left: 20em; + padding-right: 0 + } + + #toc.toc2 { + width: 25em + } + + #toc.toc2 #toctitle { + font-size: 1.375em + } + + #toc.toc2 > ul { + font-size: .95em + } + + #toc.toc2 ul ul { + padding-left: 1.25em + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 20em + } +} + +#content #toc { + border-style: solid; + border-width: 1px; + border-color: #e0e0dc; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f8f8f7; + -webkit-border-radius: 4px; + border-radius: 4px +} + +#content #toc > :first-child { + margin-top: 0 +} + +#content #toc > :last-child { + margin-bottom: 0 +} + +#footer { + max-width: 100%; + background-color: rgba(0, 0, 0, .8); + padding: 1.25em +} + +#footer-text { + color: rgba(255, 255, 255, .8); + line-height: 1.44 +} + +#content { + margin-bottom: .625em +} + +.sect1 { + padding-bottom: .625em +} + +@media screen and (min-width: 768px) { + #content { + margin-bottom: 1.25em + } + + .sect1 { + padding-bottom: 1.25em + } +} + +.sect1:last-child { + padding-bottom: 0 +} + +.sect1 + .sect1 { + border-top: 1px solid #efefed +} + +#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { + position: absolute; + z-index: 1001; + width: 1.5ex; + margin-left: -1.5ex; + display: block; + text-decoration: none !important; + visibility: hidden; + text-align: center; + font-weight: 400 +} + +#content h1 > a.anchor::before, h2 > a.anchor::before, h3 > a.anchor::before, #toctitle > a.anchor::before, .sidebarblock > .content > .title > a.anchor::before, h4 > a.anchor::before, h5 > a.anchor::before, h6 > a.anchor::before { + content: "\00A7"; + font-size: .85em; + display: block; + padding-top: .1em +} + +#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { + visibility: visible +} + +#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { + color: #ba3925; + text-decoration: none +} + +#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { + color: #a53221 +} + +.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { + margin-bottom: 1.25em +} + +.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { + text-rendering: optimizeLegibility; + text-align: left; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-size: 1rem; + font-style: italic +} + +table.tableblock.fit-content > caption.title { + white-space: nowrap; + width: 0 +} + +.paragraph.lead > p, #preamble > .sectionbody > [class="paragraph"]:first-of-type p { + font-size: 1.21875em; + line-height: 1.6; + color: rgba(0, 0, 0, .85) +} + +table.tableblock #preamble > .sectionbody > [class="paragraph"]:first-of-type p { + font-size: inherit +} + +.admonitionblock > table { + border-collapse: separate; + border: 0; + background: none; + width: 100% +} + +.admonitionblock > table td.icon { + text-align: center; + width: 80px +} + +.admonitionblock > table td.icon img { + max-width: none +} + +.admonitionblock > table td.icon .title { + font-weight: bold; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + text-transform: uppercase +} + +.admonitionblock > table td.content { + padding-left: 1.125em; + padding-right: 1.25em; + border-left: 1px solid #ddddd8; + color: rgba(0, 0, 0, .6) +} + +.admonitionblock > table td.content > :last-child > :last-child { + margin-bottom: 0 +} + +.exampleblock > .content { + border-style: solid; + border-width: 1px; + border-color: #e6e6e6; + margin-bottom: 1.25em; + padding: 1.25em; + background: #fff; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.exampleblock > .content > :first-child { + margin-top: 0 +} + +.exampleblock > .content > :last-child { + margin-bottom: 0 +} + +.sidebarblock { + border-style: solid; + border-width: 1px; + border-color: #e0e0dc; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f8f8f7; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.sidebarblock > :first-child { + margin-top: 0 +} + +.sidebarblock > :last-child { + margin-bottom: 0 +} + +.sidebarblock > .content > .title { + color: #7a2518; + margin-top: 0; + text-align: center +} + +.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { + margin-bottom: 0 +} + +.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { + background: #f7f7f8 +} + +.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { + background: #f2f1f1 +} + +.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { + -webkit-border-radius: 4px; + border-radius: 4px; + word-wrap: break-word; + padding: 1em; + font-size: .8125em +} + +.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { + overflow-x: auto; + white-space: pre; + word-wrap: normal +} + +@media screen and (min-width: 768px) { + .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { + font-size: .90625em + } +} + +@media screen and (min-width: 1280px) { + .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { + font-size: 1em + } +} + +.literalblock.output pre { + color: #f7f7f8; + background-color: rgba(0, 0, 0, .9) +} + +.listingblock pre.highlightjs { + padding: 0 +} + +.listingblock pre.highlightjs > code { + padding: 1em; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.listingblock pre.prettyprint { + border-width: 0 +} + +.listingblock > .content { + position: relative +} + +.listingblock code[data-lang]::before { + display: none; + content: attr(data-lang); + position: absolute; + font-size: .75em; + top: .425rem; + right: .5rem; + line-height: 1; + text-transform: uppercase; + color: #999 +} + +.listingblock:hover code[data-lang]::before { + display: block +} + +.listingblock.terminal pre .command::before { + content: attr(data-prompt); + padding-right: .5em; + color: #999 +} + +.listingblock.terminal pre .command:not([data-prompt])::before { + content: "$" +} + +table.pyhltable { + border-collapse: separate; + border: 0; + margin-bottom: 0; + background: none +} + +table.pyhltable td { + vertical-align: top; + padding-top: 0; + padding-bottom: 0; + line-height: 1.45 +} + +table.pyhltable td.code { + padding-left: .75em; + padding-right: 0 +} + +pre.pygments .lineno, table.pyhltable td:not(.code) { + color: #999; + padding-left: 0; + padding-right: .5em; + border-right: 1px solid #ddddd8 +} + +pre.pygments .lineno { + display: inline-block; + margin-right: .25em +} + +table.pyhltable .linenodiv { + background: none !important; + padding-right: 0 !important +} + +.quoteblock { + margin: 0 1em 1.25em 1.5em; + display: table +} + +.quoteblock > .title { + margin-left: -1.5em; + margin-bottom: .75em +} + +.quoteblock blockquote, .quoteblock blockquote p { + color: rgba(0, 0, 0, .85); + font-size: 1.15rem; + line-height: 1.75; + word-spacing: .1em; + letter-spacing: 0; + font-style: italic; + text-align: justify +} + +.quoteblock blockquote { + margin: 0; + padding: 0; + border: 0 +} + +.quoteblock blockquote::before { + content: "\201c"; + float: left; + font-size: 2.75em; + font-weight: bold; + line-height: .6em; + margin-left: -.6em; + color: #7a2518; + text-shadow: 0 1px 2px rgba(0, 0, 0, .1) +} + +.quoteblock blockquote > .paragraph:last-child p { + margin-bottom: 0 +} + +.quoteblock .attribution { + margin-top: .5em; + margin-right: .5ex; + text-align: right +} + +.quoteblock .quoteblock { + margin-left: 0; + margin-right: 0; + padding: .5em 0; + border-left: 3px solid rgba(0, 0, 0, .6) +} + +.quoteblock .quoteblock blockquote { + padding: 0 0 0 .75em +} + +.quoteblock .quoteblock blockquote::before { + display: none +} + +.verseblock { + margin: 0 1em 1.25em +} + +.verseblock pre { + font-family: "Open Sans", "DejaVu Sans", sans; + font-size: 1.15rem; + color: rgba(0, 0, 0, .85); + font-weight: 300; + text-rendering: optimizeLegibility +} + +.verseblock pre strong { + font-weight: 400 +} + +.verseblock .attribution { + margin-top: 1.25rem; + margin-left: .5ex +} + +.quoteblock .attribution, .verseblock .attribution { + font-size: .9375em; + line-height: 1.45; + font-style: italic +} + +.quoteblock .attribution br, .verseblock .attribution br { + display: none +} + +.quoteblock .attribution cite, .verseblock .attribution cite { + display: block; + letter-spacing: -.025em; + color: rgba(0, 0, 0, .6) +} + +.quoteblock.abstract { + margin: 0 1em 1.25em; + display: block +} + +.quoteblock.abstract > .title { + margin: 0 0 .375em; + font-size: 1.15em; + text-align: center +} + +.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { + word-spacing: 0; + line-height: 1.6 +} + +.quoteblock.abstract blockquote::before, .quoteblock.abstract p::before { + display: none +} + +table.tableblock { + max-width: 100%; + border-collapse: separate +} + +p.tableblock:last-child { + margin-bottom: 0 +} + +td.tableblock > .content { + margin-bottom: -1.25em +} + +table.tableblock, th.tableblock, td.tableblock { + border: 0 solid #dedede +} + +table.grid-all > thead > tr > .tableblock, table.grid-all > tbody > tr > .tableblock { + border-width: 0 1px 1px 0 +} + +table.grid-all > tfoot > tr > .tableblock { + border-width: 1px 1px 0 0 +} + +table.grid-cols > * > tr > .tableblock { + border-width: 0 1px 0 0 +} + +table.grid-rows > thead > tr > .tableblock, table.grid-rows > tbody > tr > .tableblock { + border-width: 0 0 1px +} + +table.grid-rows > tfoot > tr > .tableblock { + border-width: 1px 0 0 +} + +table.grid-all > * > tr > .tableblock:last-child, table.grid-cols > * > tr > .tableblock:last-child { + border-right-width: 0 +} + +table.grid-all > tbody > tr:last-child > .tableblock, table.grid-all > thead:last-child > tr > .tableblock, table.grid-rows > tbody > tr:last-child > .tableblock, table.grid-rows > thead:last-child > tr > .tableblock { + border-bottom-width: 0 +} + +table.frame-all { + border-width: 1px +} + +table.frame-sides { + border-width: 0 1px +} + +table.frame-topbot, table.frame-ends { + border-width: 1px 0 +} + +table.stripes-all tr, table.stripes-odd tr:nth-of-type(odd) { + background: #f8f8f7 +} + +table.stripes-none tr, table.stripes-odd tr:nth-of-type(even) { + background: none +} + +th.halign-left, td.halign-left { + text-align: left +} + +th.halign-right, td.halign-right { + text-align: right +} + +th.halign-center, td.halign-center { + text-align: center +} + +th.valign-top, td.valign-top { + vertical-align: top +} + +th.valign-bottom, td.valign-bottom { + vertical-align: bottom +} + +th.valign-middle, td.valign-middle { + vertical-align: middle +} + +table thead th, table tfoot th { + font-weight: bold +} + +tbody tr th { + display: table-cell; + line-height: 1.6; + background: #f7f8f7 +} + +tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { + color: rgba(0, 0, 0, .8); + font-weight: bold +} + +p.tableblock > code:only-child { + background: none; + padding: 0 +} + +p.tableblock { + font-size: 1em +} + +td > div.verse { + white-space: pre +} + +ol { + margin-left: 1.75em +} + +ul li ol { + margin-left: 1.5em +} + +dl dd { + margin-left: 1.125em +} + +dl dd:last-child, dl dd:last-child > :last-child { + margin-bottom: 0 +} + +ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { + margin-bottom: .625em +} + +ul.checklist, ul.none, ol.none, ul.no-bullet, ol.no-bullet, ol.unnumbered, ul.unstyled, ol.unstyled { + list-style-type: none +} + +ul.no-bullet, ol.no-bullet, ol.unnumbered { + margin-left: .625em +} + +ul.unstyled, ol.unstyled { + margin-left: 0 +} + +ul.checklist { + margin-left: .625em +} + +ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { + width: 1.25em; + font-size: .8em; + position: relative; + bottom: .125em +} + +ul.checklist li > p:first-child > input[type="checkbox"]:first-child { + margin-right: .25em +} + +ul.inline { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-flow: row wrap; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + list-style: none; + margin: 0 0 .625em -1.25em +} + +ul.inline > li { + margin-left: 1.25em +} + +.unstyled dl dt { + font-weight: 400; + font-style: normal +} + +ol.arabic { + list-style-type: decimal +} + +ol.decimal { + list-style-type: decimal-leading-zero +} + +ol.loweralpha { + list-style-type: lower-alpha +} + +ol.upperalpha { + list-style-type: upper-alpha +} + +ol.lowerroman { + list-style-type: lower-roman +} + +ol.upperroman { + list-style-type: upper-roman +} + +ol.lowergreek { + list-style-type: lower-greek +} + +.hdlist > table, .colist > table { + border: 0; + background: none +} + +.hdlist > table > tbody > tr, .colist > table > tbody > tr { + background: none +} + +td.hdlist1, td.hdlist2 { + vertical-align: top; + padding: 0 .625em +} + +td.hdlist1 { + font-weight: bold; + padding-bottom: 1.25em +} + +.literalblock + .colist, .listingblock + .colist { + margin-top: -.5em +} + +.colist td:not([class]):first-child { + padding: .4em .75em 0; + line-height: 1; + vertical-align: top +} + +.colist td:not([class]):first-child img { + max-width: none +} + +.colist td:not([class]):last-child { + padding: .25em 0 +} + +.thumb, .th { + line-height: 0; + display: inline-block; + border: solid 4px #fff; + -webkit-box-shadow: 0 0 0 1px #ddd; + box-shadow: 0 0 0 1px #ddd +} + +.imageblock.left, .imageblock[style * ="float: left"] { + margin: .25em .625em 1.25em 0 +} + +.imageblock.right, .imageblock[style * ="float: right"] { + margin: .25em 0 1.25em .625em +} + +.imageblock > .title { + margin-bottom: 0 +} + +.imageblock.thumb, .imageblock.th { + border-width: 6px +} + +.imageblock.thumb > .title, .imageblock.th > .title { + padding: 0 .125em +} + +.image.left, .image.right { + margin-top: .25em; + margin-bottom: .25em; + display: inline-block; + line-height: 0 +} + +.image.left { + margin-right: .625em +} + +.image.right { + margin-left: .625em +} + +a.image { + text-decoration: none; + display: inline-block +} + +a.image object { + pointer-events: none +} + +sup.footnote, sup.footnoteref { + font-size: .875em; + position: static; + vertical-align: super +} + +sup.footnote a, sup.footnoteref a { + text-decoration: none +} + +sup.footnote a:active, sup.footnoteref a:active { + text-decoration: underline +} + +#footnotes { + padding-top: .75em; + padding-bottom: .75em; + margin-bottom: .625em +} + +#footnotes hr { + width: 20%; + min-width: 6.25em; + margin: -.25em 0 .75em; + border-width: 1px 0 0 +} + +#footnotes .footnote { + padding: 0 .375em 0 .225em; + line-height: 1.3334; + font-size: .875em; + margin-left: 1.2em; + margin-bottom: .2em +} + +#footnotes .footnote a:first-of-type { + font-weight: bold; + text-decoration: none; + margin-left: -1.05em +} + +#footnotes .footnote:last-of-type { + margin-bottom: 0 +} + +#content #footnotes { + margin-top: -.625em; + margin-bottom: 0; + padding: .75em 0 +} + +.gist .file-data > table { + border: 0; + background: #fff; + width: 100%; + margin-bottom: 0 +} + +.gist .file-data > table td.line-data { + width: 99% +} + +div.unbreakable { + page-break-inside: avoid +} + +.big { + font-size: larger +} + +.small { + font-size: smaller +} + +.underline { + text-decoration: underline +} + +.overline { + text-decoration: overline +} + +.line-through { + text-decoration: line-through +} + +.aqua { + color: #00bfbf +} + +.aqua-background { + background-color: #00fafa +} + +.black { + color: #000 +} + +.black-background { + background-color: #000 +} + +.blue { + color: #0000bf +} + +.blue-background { + background-color: #0000fa +} + +.fuchsia { + color: #bf00bf +} + +.fuchsia-background { + background-color: #fa00fa +} + +.gray { + color: #606060 +} + +.gray-background { + background-color: #7d7d7d +} + +.green { + color: #006000 +} + +.green-background { + background-color: #007d00 +} + +.lime { + color: #00bf00 +} + +.lime-background { + background-color: #00fa00 +} + +.maroon { + color: #600000 +} + +.maroon-background { + background-color: #7d0000 +} + +.navy { + color: #000060 +} + +.navy-background { + background-color: #00007d +} + +.olive { + color: #606000 +} + +.olive-background { + background-color: #7d7d00 +} + +.purple { + color: #600060 +} + +.purple-background { + background-color: #7d007d +} + +.red { + color: #bf0000 +} + +.red-background { + background-color: #fa0000 +} + +.silver { + color: #909090 +} + +.silver-background { + background-color: #bcbcbc +} + +.teal { + color: #006060 +} + +.teal-background { + background-color: #007d7d +} + +.white { + color: #bfbfbf +} + +.white-background { + background-color: #fafafa +} + +.yellow { + color: #bfbf00 +} + +.yellow-background { + background-color: #fafa00 +} + +span.icon > .fa { + cursor: default +} + +a span.icon > .fa { + cursor: inherit +} + +.admonitionblock td.icon [class^="fa icon-"] { + font-size: 2.5em; + text-shadow: 1px 1px 2px rgba(0, 0, 0, .5); + cursor: default +} + +.admonitionblock td.icon .icon-note::before { + content: "\f05a"; + color: #19407c +} + +.admonitionblock td.icon .icon-tip::before { + content: "\f0eb"; + text-shadow: 1px 1px 2px rgba(155, 155, 0, .8); + color: #111 +} + +.admonitionblock td.icon .icon-warning::before { + content: "\f071"; + color: #bf6900 +} + +.admonitionblock td.icon .icon-caution::before { + content: "\f06d"; + color: #bf3400 +} + +.admonitionblock td.icon .icon-important::before { + content: "\f06a"; + color: #bf0000 +} + +.conum[data-value] { + display: inline-block; + color: #fff !important; + background-color: rgba(0, 0, 0, .8); + -webkit-border-radius: 100px; + border-radius: 100px; + text-align: center; + font-size: .75em; + width: 1.67em; + height: 1.67em; + line-height: 1.67em; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-style: normal; + font-weight: bold +} + +.conum[data-value] * { + color: #fff !important +} + +.conum[data-value] + b { + display: none +} + +.conum[data-value]::after { + content: attr(data-value) +} + +pre .conum[data-value] { + position: relative; + top: -.125em +} + +b.conum * { + color: inherit !important +} + +.conum:not([data-value]):empty { + display: none +} + +dt, th.tableblock, td.content, div.footnote { + text-rendering: optimizeLegibility +} + +h1, h2, p, td.content, span.alt { + letter-spacing: -.01em +} + +p strong, td.content strong, div.footnote strong { + letter-spacing: -.005em +} + +p, blockquote, dt, td.content, span.alt { + font-size: 1.0625rem +} + +p { + margin-bottom: 1.25rem +} + +.sidebarblock p, .sidebarblock dt, .sidebarblock td.content, p.tableblock { + font-size: 1em +} + +.exampleblock > .content { + background-color: #fffef7; + border-color: #e0e0dc; + -webkit-box-shadow: 0 1px 4px #e0e0dc; + box-shadow: 0 1px 4px #e0e0dc +} + +.print-only { + display: none !important +} + +@page { + margin: 1.25cm .75cm +} + +@media print { + * { + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important + } + + html { + font-size: 80% + } + + a { + color: inherit !important; + text-decoration: underline !important + } + + a.bare, a[href^="#"], a[href^="mailto:"] { + text-decoration: none !important + } + + a[href^="http:"]: not(.bare):: after, a[href^="https:"]:not(.bare)::after { + content: "(" attr(href) ")"; + display: inline-block; + font-size: .875em; + padding-left: .25em + } + + abbr[title]::after { + content: " (" attr(title) ")" + } + + pre, blockquote, tr, img, object, svg { + page-break-inside: avoid + } + + thead { + display: table-header-group + } + + svg { + max-width: 100% + } + + p, blockquote, dt, td.content { + font-size: 1em; + orphans: 3; + widows: 3 + } + + h2, h3, #toctitle, .sidebarblock > .content > .title { + page-break-after: avoid + } + + #toc, .sidebarblock, .exampleblock > .content { + background: none !important + } + + #toc { + border-bottom: 1px solid #ddddd8 !important; + padding-bottom: 0 !important + } + + body.book #header { + text-align: center + } + + body.book #header > h1:first-child { + border: 0 !important; + margin: 2.5em 0 1em + } + + body.book #header .details { + border: 0 !important; + display: block; + padding: 0 !important + } + + body.book #header .details span:first-child { + margin-left: 0 !important + } + + body.book #header .details br { + display: block + } + + body.book #header .details br + span::before { + content: none !important + } + + body.book #toc { + border: 0 !important; + text-align: left !important; + padding: 0 !important; + margin: 0 !important + } + + body.book #toc, body.book #preamble, body.book h1.sect0, body.book .sect1 > h2 { + page-break-before: always + } + + .listingblock code[data-lang]::before { + display: block + } + + #footer { + padding: 0 .9375em + } + + .hide-on-print { + display: none !important + } + + .print-only { + display: block !important + } + + .hide-for-print { + display: none !important + } + + .show-for-print { + display: inherit !important + } +} + +@media print, amzn-kf8 { + #header > h1:first-child { + margin-top: 1.25rem + } + + .sect1 { + padding: 0 !important + } + + .sect1 + .sect1 { + border: 0 + } + + #footer { + background: none + } + + #footer-text { + color: rgba(0, 0, 0, .6); + font-size: .9em + } +} + +@media amzn-kf8 { + #header, #content, #footnotes, #footer { + padding: 0 + } +} + diff --git a/templates/docinfo.html b/templates/docinfo.html new file mode 100644 index 00000000..cbc4b3c8 --- /dev/null +++ b/templates/docinfo.html @@ -0,0 +1,75 @@ + + + + + + + + + \ No newline at end of file diff --git a/templates/images/nist.png b/templates/images/nist.png new file mode 100644 index 00000000..23dd1a0c Binary files /dev/null and b/templates/images/nist.png differ diff --git a/templates/scripts/asciidoctor-pdf-extensions.rb b/templates/scripts/asciidoctor-pdf-extensions.rb new file mode 100644 index 00000000..8995e11f --- /dev/null +++ b/templates/scripts/asciidoctor-pdf-extensions.rb @@ -0,0 +1,111 @@ +require 'asciidoctor-pdf' unless defined? ::Asciidoctor::Pdf + +module AsciidoctorPdfExtensions + # Override the built-in layout_toc to move colophon before front of table of contents + # NOTE we assume that the colophon fits on a single page + def layout_toc doc, num_levels = 2, toc_page_number = 2, num_front_matter_pages = 0, toc_start + go_to_page toc_page_number unless (page_number == toc_page_number) || scratch? + if scratch? + colophon = doc.find_by(context: :section) {|sect| sect.sectname == 'colophon' } + if (colophon = colophon.first) + doc.instance_variable_set :@colophon, colophon + colophon.parent.blocks.delete colophon + end + else + if (colophon = doc.instance_variable_get :@colophon) + # if prepress book, consume blank page before table of contents + go_to_page(page_number - 1) if @ppbook + convert_section colophon + go_to_page(page_number + 1) + end + end + offset = colophon && !@ppbook ? 1 : 0 + toc_page_numbers = super doc, num_levels, (toc_page_number + offset), num_front_matter_pages + scratch? ? ((toc_page_numbers.begin - offset)..toc_page_numbers.end) : toc_page_numbers + end + + # force chapters to start on new page; + # force select chapters to start on the recto (odd-numbered, right-hand) page + def start_new_chapter chapter + start_new_page unless at_page_top? + if @ppbook && verso_page? && !(chapter.option? 'nonfacing') + update_colors # prevents Ghostscript from reporting a warning when running content is written to blank page + start_new_page + end + end + + def layout_chapter_title node, title, opts = {} + if (sect_id = node.id) == 'dedication' || sect_id == 'acknowledgements' + layout_heading_custom title, align: :center + elsif sect_id == 'colophon' + #puts 'Processing ' + node.sectname + '...' + if node.document.attr? 'media', 'prepress' + move_down 325 + else + move_down 460 + end + layout_heading title, size: @theme.base_font_size + elsif sect_id.include? 'chapter' # chapters + #puts 'Processing ' + sect_id + '...' + # use Akkurat font for all custom headings + font 'Akkurat' do + if node.document.attr? 'media', 'prepress' + move_down 120 + else + move_down 180 + end + if @ppbook + layout_heading 'PART', align: :right, size: 100, style: :normal + else + layout_heading 'PART', align: :right, size: 100, color: [91, 54, 8, 13], style: :normal + end + move_up 40 + + part_number = 'ONE' + if sect_id.include? 'chapter-2' + part_number = 'TWO' + elsif sect_id.include? 'chapter-3' + part_number = 'THREE' + end + if @ppbook + layout_heading part_number, align: :right, size: 100, style: :bold + layout_heading title, align: :right, style: :normal, size: 30 + else + layout_heading part_number, align: :right, size: 100, color: [42, 1, 83, 1], style: :bold + layout_heading title, align: :right, color: [42, 1, 83, 1], style: :normal, size: 30 + end + end + + bounds.move_past_bottom + else + super # delegate to default implementation + end + end + + def layout_heading_custom string, opts = {} + move_down 100 + typeset_text string, calc_line_metrics((opts.delete :line_height) || @theme.heading_line_height), { + inline_format: true + }.merge(opts) + move_up 5 + i = 0 + underline = '' + while i < string.length do + if string == 'Dedication' + underline += '/////' + else + underline += '//////' + end + i += 1 + end + if string == 'Dedication' + underline += '////' + end + typeset_text underline, calc_line_metrics((opts.delete :line_height) || @theme.heading_line_height), { + inline_format: true, color: 'B0B0B0', size: 8, style: :italic + }.merge(opts) + move_down 20 + end +end + +Asciidoctor::Pdf::Converter.prepend AsciidoctorPdfExtensions diff --git a/templates/title_page.adoc b/templates/title_page.adoc new file mode 100644 index 00000000..66d61841 --- /dev/null +++ b/templates/title_page.adoc @@ -0,0 +1,11 @@ +image:../templates/images/nist.png[NIST Logo,height=90,width=500] + + ++++














+++{document-title}+++












+ifdef::version[] +ifeval::["{version}" != "Baseline"] ++++{version} - {revision-date}+++ +endif::[] +endif::version[] +











+++ +