Skip to main content

Active Directory Collection

The Active Directory(AD) collection enables you to test the effective group policy settings applied to domain controllers(DC) and member servers(MS) for one or more domains.

The collection queries all DC and MS servers starting from the root domain for group policy settings. And instead of depending on the effective policies at the domain level, the collection gets the effective settings at the server level to ensure the most accurate data on these settings. The tests in the colleciton then verify these settings, comparing them to a policy(reference values).

The reference values themselves are a representation of policies defined through a configuration file. The collection supports out-of-the-box policy based on the Center for Internet Security(CIS) recommendations for Windows servers.

The results of these tests capture details of group policy settings violations compared to the prescribed policy.

Concepts

Tests

Each setting in a group policy is represented & verified using a single test case. Individual test cases capture the nuances of the setting for accurate verification. Example -

The user rights assignment setting SeAuditPrivilege represents the ability to generate security audits on a Windows server. This setting is tested through testSeAuditPrivilege test case.

As per the CIS recommendation, this setting is considered sensitive. They recommended that these permissions be allowed only for the NT AUTHORITY\LOCAL SERVICE, and NT AUTHORITY\NETWORK SERVICE accounts. Further -

  1. When Internet Information Services (IIS) role is installed on an MS, the accounts IIS APPPOOL\OCSPISAPIAppPool, and IIS APPPOOL\DefaultAppPool also require this permission.
  2. When Federation Service role is installed on MS, the accounts NT SERVICE\adfssrv, and NT SERVICE\DRS would require this permission.
  3. Additionally, if the setting is not configured through a group policy, Windows enforces the permissions with only NT AUTHORITY\LOCAL SERVICE, and NT AUTHORITY\NETWORK SERVICE accounts being granted the permission.

The test case understands all these details with their context. At every test run, the collection calculates the environment context and then enables the test to compare the appropriate policy to the actual values set on the server. The expected and actual values are logged in the test report when the verification fails. E.g.

Error

AssertionError: SeAuditPrivilege not in accordance with policy: expected [ 'NT AUTHORITY\LOCAL SERVICE', 'NT AUTHORITY\NETWORK SERVICE' ] to be a superset of [ 'corp\testAccount', 'NT AUTHORITY\NETWORK SERVICE', 'NT AUTHORITY\LOCAL SERVICE' ]

In the above error message, the policy allows only NT AUTHORITY\LOCAL SERVICE, NT AUTHORITY\NETWORK SERVICE accounts to have permission granted. However, the permission is granted to corp\testAccount, NT AUTHORITY\NETWORK SERVICE, NT AUTHORITY\LOCAL SERVICE, on this server; hence, the test fails.

Test Groups

Test cases are organized in groups. Each group represents an aspect of settings in Active Directory and the corresponding tests, for example.

Password

testPasswordHistorySize, testMaximumPasswordAge, testMinimumPasswordAge, testMinimumPasswordLength,
testPasswordComplexity, testClearTextPassword, testRelaxMinimumPasswordLengthLimits

AccountLockout

testLockoutDuration, testLockoutBadCount, testResetLockoutCount

These groupings mimic Windows group policy settings. The individual test groups categorize tests under three sections -

  1. Common - Tests that apply to both domain controllers and member servers.
  2. DomainController - Tests that apply to domain controllers only.
  3. MemberServer - Tests that apply to member servers only.

A comprehensive list of test cases is available in the tests.toml file present in the collection.

note

Some groups may only contain Common test cases, whereas others have a subset or all three categories. This depends on the individual setting groups and corresponding tests.

note

Please note the continuity of keywords, e.g., AccountLockout, DomainController, MemberServer. These keywords don't have space by design.

Test Filters

We recommend that you test all applicable settings on all servers in your environment. However, we appreciate the realities of our complex world 🤷. This is where the test filters enable you to control the list of tests to be run on individual servers.

The filters can be defined in the actor configuration file under the actor confparams section. Example -

[win.confparams]
filter_list = ['f1', 'f2']
f1.servers = ['srv2.corp.bazc.com']
f1.include.UserRightsAssignment = ['testSeIncreaseQuotaPrivilege']
f1.include.Password = []
f1.exclude.AccountLockout = ['testLockoutBadCount']
f2.servers = ['srv1.corp.bazc.com', 'srv3.corp.bazc.com']
f2.include.Password = []
f2.include.AccountLockout = []
f2.exclude.UserRightsAssignment = ['testSeImpersonatePrivilege', 'testSeDenyRemoteInteractiveLogonRight']

Filter Fields

filter_list

List of filter name keywords that are configured. The names themselves are user-defined. e.g., in the above filter list, we could use filter_1 and filter_2 instead of f1 & f2.

Each filter defines three fields: list of servers and a combination of include & exclude filters. Any number of filters can be defined to select a set of test cases to be executed for a set of servers.

<filter_name>.servers

The list of server DNS names for which this filter is applied. In the above example, filter f1 is applicable for server srv2.corp.bazc.com.

<filter_name>.include.<Test_Group_Name>

Include filter lists for the selected test group and tests. In the above example, f1.include.UserRightsAssignment, the filter lists the test case from the UserRightsAssignment group that should be executed for srv2.corp.bazc.com. The include filter can be defined for one or more test groups.

caution

Specifying an empty list for an include test group filter excludes all tests from execution on the filter servers. Example f1.include.Password = [] - Here, no tests from the Password test group would be executed on the server srv2.corp.bazc.com.

<filter_name>.exclude.<Test_Group_Name>

Exclude filter list for the selected test group and tests. In the above example, f1.exclude.AccountLockout, the filter lists the test case from the AccountLockout test group that will not be executed on server srv2.corp.bazc.com. Like the include filter, the exclude filter can be defined for one or more test groups.

Note - A filter for a test group can either have an include list or an exclude list. Specifying both lists for the same test group would result in an error. Example - configuration error.

Configuration Error

f1.include.Password = ['testClearTextPassword']
f1.exclude.Password = ['testLockoutBadCount']

Policy

A policy is a representation of a desired state of settings. They are a yardstick for measuring the deviation in settings from the desired state. They help you quantify what's wrong in your environment.

Each setting is a section in the policy file (TOML format). Like filters, policies support Common, DomainController & MemberServer grouping where each applies to either one or both. A policy control can be a primitive - Number, Boolean, String, a list, or a map of primitives. An empty list is a valid control. Example - UserRightsAssignment.SeTrustedCredManAccessPrivilege.Common.Control specifies an empty list. Here the setting means that permission should not be granted to anyone.

Additionally, some settings incorporate additional fields -for example UserRightsAssignment.SeIncreaseQuotaPrivilege.MemberServer.Roles. Here the role applies to SeIncreaseQuotaPrivilege setting on MS. Further, each role is for a specific condition. The MS-SQL role defined is only applied as policy if the member server has an MS-SQL server installed.

We have incorporated the policy based on the recommendation from CIS for Windows Servers. The recommendation for Windows servers is available on the CIS website. A comprehensive policy file policy.toml is available in the collection. Below is a snapshot of the policy file.

[AccountLockout.LockoutBadCount.Common]
Control = 5

[AccountLockout.ResetLockoutCount.Common]
Control = 15

[UserRightsAssignment.SeTrustedCredManAccessPrivilege.Common]
Control = []

[UserRightsAssignment.SeNetworkLogonRight.DomainController]
Control = [
'Administrators',
'NT AUTHORITY\Authenticated Users',
'NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS',
]

[UserRightsAssignment.SeNetworkLogonRight.MemberServer]
Control = ['Administrators', 'NT AUTHORITY\Authenticated Users']

[UserRightsAssignment.SeTcbPrivilege.Common]
Control = []

[UserRightsAssignment.SeMachineAccountPrivilege.DomainController]
Control = ['Administrators']

[UserRightsAssignment.SeIncreaseQuotaPrivilege.Common]
Control = [
'Administrators',
'NT AUTHORITY\LOCAL SERVICE',
'NT AUTHORITY\NETWORK SERVICE',
]

[UserRightsAssignment.SeIncreaseQuotaPrivilege.MemberServer.Roles]
Web-Server-WSRole = [
'IIS APPPOOL\OCSPISAPIAppPool',
'IIS APPPOOL\DefaultAppPool',
] # (IIS)Web server with web server role.
MS-SQL = ['NT Service\SQLSERVERAGENT', 'NT Service\MSSQLSERVER']

[UserRightsAssignment.SeInteractiveLogonRight.Common]
Control = ['Administrators', 'Backup Operators']

[UserRightsAssignment.SeRemoteInteractiveLogonRight.DomainController]
Control = ['Administrator'] #Optional 'Remote Desktop Users'

[UserRightsAssignment.SeRemoteInteractiveLogonRight.MemberServer]
Control = ['Administrator', 'Remote Desktop Users']

[UserRightsAssignment.SeRemoteInteractiveLogonRight.MemberServer.Roles]
RDS-RDSCB = [
'NT AUTHORITY\Authenticated Users',
] #Both Remote-Desktop-Services & RDS-Connection-Broker roles present on MS

Pre-requisite

The collection uses the Windows plugin of the Baz system. This plugin is used to query data from both Active Directory and individual servers. Please see the plugin configuration section for details on configuring the plugin.

Execution

By default, the collection runs all applicable tests for each server type (DC & MS) for the root and all trusted child domains.

✅ Make sure the actor configuration file is configured with your environmental values. For a reference configuration, please see the Windows plugin documentation.

✅ Optional step - Set the test filters if there is a need to control the test execution on one or more servers.

✅ Start the test on the CLI -

Format - /opt/bazc/bazcli/bin/bazcli test --actors <actor_conf_file> --name=<test_run_name> --output=<result_report_name> test_directory

/opt/bazc/bazcli/bin/bazcli test --actors baz-test-collection/active_directory/config/win.toml --name="CIS Windows Server 2022" --output=report.csv baz-test-collection/active_directory/

Result

The result of each test is detailed in the CSV report file - report.csv in the above example.

Fields

run_id - A unique identifier for a test case.

report_name - The name of the report specified by you on the CLI.

run_name - The type of server being tested - DomainController or MemberServer along with server DNS name.

test_name - The name of the test case. The test case name combines the keyword test and the setting supported by the test case.

time - The date & time when the test case was executed.

pass - The test case result - with true for successful verification & false for failures and skip for skipped test cases.

error_message - The detailed message for failed test cases.

description - The description of the setting being verified.

severity - The severity of the test case based on CIS's recommendation.

group - The test case group for the test.

domain - The domain for which this test case was executed.

target - The DNS name of the target server on which this test case was executed.