├── .ansible-lint ├── .gitattributes ├── .github └── workflows │ ├── devel_pipeline_validation.yml │ ├── main_pipeline_validation.yml │ └── update_galaxy.yml ├── .gitignore ├── .yamllint ├── CONTRIBUTING.rst ├── ChangeLog.md ├── LICENSE ├── README.md ├── collections └── requirements.yml ├── defaults └── main.yml ├── handlers └── main.yml ├── meta └── main.yml ├── site.yml ├── tasks ├── cat1.yml ├── cat2.yml ├── cat2_cloud_lockout_order.yml ├── cat3.yml ├── main.yml ├── post.yml ├── prelim.yml └── warning_facts.yml ├── templates └── banner.txt └── vars └── main.yml /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | parseable: true 4 | quiet: true 5 | skip_list: 6 | - 'package-latest' 7 | - 'risky-shell-pipe' 8 | use_default_rules: true 9 | verbosity: 0 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # adding github settings to show correct language 2 | *.sh linguist-detectable=true 3 | *.yml linguist-detectable=true 4 | *.ps1 linguist-detectable=true 5 | *.j2 linguist-detectable=true 6 | *.md linguist-documentation 7 | -------------------------------------------------------------------------------- /.github/workflows/devel_pipeline_validation.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # This is a basic workflow to help you get started with Actions 4 | 5 | name: Ansible Remediate Devel Pipeline Validation 6 | 7 | # Controls when the action will run. 8 | # Triggers the workflow on push or pull request 9 | # events but only for the devel branch 10 | on: # yamllint disable-line rule:truthy 11 | pull_request_target: 12 | types: [opened, reopened, synchronize] 13 | branches: 14 | - devel 15 | paths: 16 | - '**.yml' 17 | - '**.sh' 18 | - '**.j2' 19 | - '**.ps1' 20 | - '**.cfg' 21 | 22 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 23 | # This section contains all the jobs below that are running in the workflow. 24 | jobs: 25 | # This will create messages for the first time contributors and direct them to the Discord server 26 | welcome: 27 | # The type of runner that the job will run on. 28 | runs-on: ubuntu-latest 29 | steps: 30 | - uses: actions/first-interaction@main 31 | with: 32 | repo-token: ${{ secrets.GITHUB_TOKEN }} 33 | pr-message: |- 34 | Congrats on opening your first pull request and thank you for taking the time to help improve Ansible-Lockdown! 35 | Please join in the conversation happening on the [Discord Server](https://www.lockdownenterprise.com/discord) as well. 36 | 37 | build-azure-windows: 38 | # Use the AWS self-hosted runner 39 | runs-on: self-hosted 40 | env: 41 | # Imported as a variable by OpenTofu. 42 | ARM_CLIENT_ID: ${{ secrets.AZURE_AD_CLIENT_ID }} 43 | ARM_CLIENT_SECRET: ${{ secrets.AZURE_AD_CLIENT_SECRET }} 44 | ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 45 | ARM_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }} 46 | WIN_USERNAME: ${{ secrets.WIN_USERNAME }} 47 | WIN_PASSWORD: ${{ secrets.WIN_PASSWORD }} 48 | OSVAR: ${{ vars.OSVAR }} 49 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 50 | TF_VAR_repository: ${{ github.event.repository.name }} 51 | ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} 52 | ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} 53 | 54 | defaults: 55 | run: 56 | shell: bash 57 | working-directory: .github/workflows/github_windows_IaC 58 | 59 | steps: 60 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it. 61 | - name: Clone ${{ github.event.repository.name }} 62 | uses: actions/checkout@v4 63 | with: 64 | ref: ${{ github.event.pull_request.head.sha }} 65 | 66 | - name: If a variable for IAC_BRANCH is set use that branch 67 | working-directory: .github/workflows 68 | run: | 69 | if [ ${{ vars.IAC_BRANCH }} != '' ]; then 70 | echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV 71 | echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" 72 | else 73 | echo IAC_BRANCH=main >> $GITHUB_ENV 74 | fi 75 | 76 | # Pull In OpenTofu Code For Windows Azure 77 | - name: Clone IaC Repository 78 | uses: actions/checkout@v4 79 | with: 80 | repository: ansible-lockdown/github_windows_IaC 81 | path: .github/workflows/github_windows_IaC 82 | ref: ${{ env.IAC_BRANCH }} 83 | 84 | # Sensitive Data Stored And Passed To OpenTofu 85 | # Default Working Dir Defined In Defaults Above. 86 | - name: Save Sensitive Info 87 | run: echo "{\"username\":\"${WIN_USERNAME}\",\"password\":\"${WIN_PASSWORD}\"}" >> sensitive_info.json 88 | 89 | # Show the Os Var and Benchmark Type And Load 90 | - name: DEBUG - Show IaC files 91 | if: env.ENABLE_DEBUG == 'true' 92 | run: | 93 | echo "OSVAR = $OSVAR" 94 | echo "benchmark_type = $benchmark_type" 95 | pwd 96 | ls 97 | env: 98 | # Imported from github variables this is used to load the relevant OS.tfvars file 99 | OSVAR: ${{ vars.OSVAR }} 100 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 101 | 102 | # Initialize The OpenTofu Working Directory 103 | - name: Tofu init 104 | id: init 105 | run: tofu init 106 | env: 107 | # Imported from GitHub variables this is used to load the relevant OS.tfvars file 108 | OSVAR: ${{ vars.OSVAR }} 109 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 110 | 111 | # Validate The Syntax Of OpenTofu Files 112 | - name: Tofu validate 113 | id: validate 114 | run: tofu validate 115 | env: 116 | # Imported from GitHub variables this is used to load the relevant OS.tfvars file 117 | OSVAR: ${{ vars.OSVAR }} 118 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 119 | 120 | # Execute The Actions And Build Azure Server 121 | - name: Tofo Apply 122 | id: apply 123 | env: 124 | # Imported from github variables this is used to load the relevant OS.tfvars file 125 | WIN_USERNAME: ${{ secrets.WIN_USERNAME }} 126 | WIN_PASSWORD: ${{ secrets.WIN_PASSWORD }} 127 | OSVAR: ${{ vars.OSVAR }} 128 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 129 | run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false 130 | 131 | # Debug Section 132 | - name: DEBUG - Show Ansible Hostfile 133 | if: env.ENABLE_DEBUG == 'true' 134 | run: cat hosts.yml 135 | 136 | # Run the Ansible Playbook 137 | - name: Run_Ansible_Playbook 138 | env: 139 | ANSIBLE_HOST_KEY_CHECKING: "false" 140 | ANSIBLE_DEPRECATION_WARNINGS: "false" 141 | run: | 142 | /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml ../../../site.yml 143 | 144 | # Destroy The Azure Test System 145 | - name: Tofu Destroy 146 | if: always() && env.ENABLE_DEBUG == 'false' 147 | env: 148 | # Imported from GitHub variables this is used to load the relevant OS.tfvars file 149 | OSVAR: ${{ vars.OSVAR }} 150 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 151 | run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve 152 | -------------------------------------------------------------------------------- /.github/workflows/main_pipeline_validation.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # This is a basic workflow to help you get started with Actions 4 | 5 | name: Ansible Remediate Main Pipeline Validation 6 | 7 | # Controls when the action will run. 8 | # Triggers the workflow on push or pull request 9 | # events but only for the devel branch 10 | on: # yamllint disable-line rule:truthy 11 | pull_request_target: 12 | types: [opened, reopened, synchronize] 13 | branches: 14 | - main 15 | - latest 16 | paths: 17 | - '**.yml' 18 | - '**.sh' 19 | - '**.j2' 20 | - '**.ps1' 21 | - '**.cfg' 22 | 23 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 24 | # This section contains all the jobs below that are running in the workflow. 25 | jobs: 26 | # This workflow will run OpenTofu to load an instance in Azure to test the playbook against a live cloud-based instance. 27 | build-azure-windows: 28 | # Use the AWS self-hosted runner 29 | runs-on: self-hosted 30 | env: 31 | # Imported as a variable by OpenTofu. 32 | ARM_CLIENT_ID: ${{ secrets.AZURE_AD_CLIENT_ID }} 33 | ARM_CLIENT_SECRET: ${{ secrets.AZURE_AD_CLIENT_SECRET }} 34 | ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 35 | ARM_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }} 36 | WIN_USERNAME: ${{ secrets.WIN_USERNAME }} 37 | WIN_PASSWORD: ${{ secrets.WIN_PASSWORD }} 38 | OSVAR: ${{ vars.OSVAR }} 39 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 40 | TF_VAR_repository: ${{ github.event.repository.name }} 41 | ANSIBLE_VERSION: ${{ vars.ANSIBLE_RUNNER_VERSION }} 42 | ENABLE_DEBUG: ${{ vars.ENABLE_DEBUG }} 43 | 44 | defaults: 45 | run: 46 | shell: bash 47 | working-directory: .github/workflows/github_windows_IaC 48 | 49 | steps: 50 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it. 51 | - name: Clone ${{ github.event.repository.name }} 52 | uses: actions/checkout@v4 53 | with: 54 | ref: ${{ github.event.pull_request.head.sha }} 55 | 56 | - name: If a variable for IAC_BRANCH is set use that branch 57 | working-directory: .github/workflows 58 | run: | 59 | if [ ${{ vars.IAC_BRANCH }} != '' ]; then 60 | echo "IAC_BRANCH=${{ vars.IAC_BRANCH }}" >> $GITHUB_ENV 61 | echo "Pipeline using the following IAC branch ${{ vars.IAC_BRANCH }}" 62 | else 63 | echo IAC_BRANCH=main >> $GITHUB_ENV 64 | fi 65 | 66 | # Pull In OpenTofu Code For Windows Azure 67 | - name: Clone IaC Repository 68 | uses: actions/checkout@v4 69 | with: 70 | repository: ansible-lockdown/github_windows_IaC 71 | path: .github/workflows/github_windows_IaC 72 | ref: ${{ env.IAC_BRANCH }} 73 | 74 | # Sensitive Data Stored And Passed To OpenTofu 75 | # Default Working Dir Defined In Defaults Above. 76 | - name: Save Sensitive Info 77 | run: echo "{\"username\":\"${WIN_USERNAME}\",\"password\":\"${WIN_PASSWORD}\"}" >> sensitive_info.json 78 | 79 | # Show the Os Var and Benchmark Type And Load 80 | - name: DEBUG - Show IaC files 81 | if: env.ENABLE_DEBUG == 'true' 82 | run: | 83 | echo "OSVAR = $OSVAR" 84 | echo "benchmark_type = $benchmark_type" 85 | pwd 86 | ls 87 | env: 88 | # Imported from github variables this is used to load the relevant OS.tfvars file 89 | OSVAR: ${{ vars.OSVAR }} 90 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 91 | 92 | # Initialize The OpenTofu Working Directory 93 | - name: Tofu init 94 | id: init 95 | run: tofu init 96 | env: 97 | # Imported from GitHub variables this is used to load the relevant OS.tfvars file 98 | OSVAR: ${{ vars.OSVAR }} 99 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 100 | 101 | # Validate The Syntax Of OpenTofu Files 102 | - name: Tofu validate 103 | id: validate 104 | run: tofu validate 105 | env: 106 | # Imported from GitHub variables this is used to load the relevant OS.tfvars file 107 | OSVAR: ${{ vars.OSVAR }} 108 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 109 | 110 | # Execute The Actions And Build Azure Server 111 | - name: Tofo Apply 112 | id: apply 113 | env: 114 | # Imported from github variables this is used to load the relevant OS.tfvars file 115 | WIN_USERNAME: ${{ secrets.WIN_USERNAME }} 116 | WIN_PASSWORD: ${{ secrets.WIN_PASSWORD }} 117 | OSVAR: ${{ vars.OSVAR }} 118 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 119 | run: tofu apply -var-file "${OSVAR}.tfvars" --auto-approve -input=false 120 | 121 | # Debug Section 122 | - name: DEBUG - Show Ansible Hostfile 123 | if: env.ENABLE_DEBUG == 'true' 124 | run: cat hosts.yml 125 | 126 | # Run the Ansible Playbook 127 | - name: Run_Ansible_Playbook 128 | env: 129 | ANSIBLE_HOST_KEY_CHECKING: "false" 130 | ANSIBLE_DEPRECATION_WARNINGS: "false" 131 | run: | 132 | /opt/ansible_${{ env.ANSIBLE_VERSION }}_venv/bin/ansible-playbook -i hosts.yml ../../../site.yml 133 | 134 | # Destroy The Azure Test System 135 | - name: Tofu Destroy 136 | if: always() && env.ENABLE_DEBUG == 'false' 137 | env: 138 | # Imported from GitHub variables this is used to load the relevant OS.tfvars file 139 | OSVAR: ${{ vars.OSVAR }} 140 | TF_VAR_benchmark_type: ${{ vars.BENCHMARK_TYPE }} 141 | run: tofu destroy -var-file "${OSVAR}.tfvars" --auto-approve 142 | -------------------------------------------------------------------------------- /.github/workflows/update_galaxy.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Update Galaxy 4 | 5 | # Controls when the action will run. 6 | # Triggers the workflow on push or pull request 7 | # events but only for the devel branch 8 | on: 9 | push: 10 | branches: 11 | - main 12 | 13 | jobs: 14 | update_role: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout V4 19 | uses: actions/checkout@v4 20 | 21 | - name: Update Galaxy 22 | uses: ansible-actions/ansible-galaxy-action@main 23 | with: 24 | galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} 25 | git_branch: main 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | *.log 3 | *.retry 4 | .vagrant 5 | tests/*redhat-subscription 6 | tests/Dockerfile 7 | *.iso 8 | *.box 9 | packer_cache 10 | delete* 11 | ignore* 12 | # VSCode 13 | .vscode 14 | vagrant 15 | 16 | # Byte-compiled / optimized / DLL files 17 | __pycache__/ 18 | *.py[cod] 19 | *$py.class 20 | 21 | # DS_Store 22 | .DS_Store 23 | ._* 24 | 25 | # Linux Editors 26 | *~ 27 | \#*\# 28 | /.emacs.desktop 29 | /.emacs.desktop.lock 30 | .elc 31 | auto-save-list 32 | tramp 33 | .\#* 34 | *.swp 35 | *.swo 36 | rh-creds.env 37 | travis.env 38 | 39 | # Lockdown-specific 40 | benchparse/ 41 | *xccdf.xml 42 | *.retry 43 | 44 | # GitHub Action/Workflow files 45 | .github/ 46 | .github/.ansible/.lock 47 | .ansible/ 48 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | extends: default 4 | locale: en_US.UTF-8 5 | ignore: | 6 | tests/ 7 | molecule/ 8 | .github/ 9 | .gitlab-ci.yml 10 | *molecule.yml 11 | rules: 12 | braces: 13 | max-spaces-inside: 1 14 | level: error 15 | brackets: 16 | max-spaces-inside: 1 17 | level: error 18 | comments: 19 | ignore-shebangs: true 20 | min-spaces-from-content: 1 # prettier compatibility 21 | comments-indentation: enable 22 | empty-lines: 23 | max: 1 24 | indentation: 25 | # Requiring 2 space indentation 26 | spaces: 2 27 | # Requiring consistent indentation within a file, either indented or not 28 | indent-sequences: consistent 29 | key-duplicates: enable 30 | line-length: disable 31 | new-line-at-end-of-file: enable 32 | new-lines: 33 | type: unix 34 | octal-values: 35 | forbid-implicit-octal: true # yamllint defaults to false 36 | forbid-explicit-octal: true 37 | trailing-spaces: enable 38 | truthy: 39 | allowed-values: ['true', 'false'] 40 | check-keys: true 41 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | Contributing to MindPoint Group Projects 2 | ======================================== 3 | 4 | Rules 5 | ----- 6 | 1) All commits must be GPG signed (details in Signing section) 7 | 2) All commits must have Signed-off-by (Signed-off-by: Joan Doe ) in the commit message (details in Signing section) 8 | 3) All work is done in your own branch 9 | 4) All pull requests go into the devel branch. There are automated checks for signed commits, signoff in commit message, and functional testing) 10 | 5) Be open and nice to each other 11 | 12 | Workflow 13 | -------- 14 | - Your work is done in your own individual branch. Make sure to to Signed-off and GPG sign all commits you intend to merge 15 | - All community Pull Requests are into the devel branch. There are automated checks for GPG signed, Signed-off in commits, and functional tests before being approved. If your pull request comes in from outside of our repo, the pull request will go into a staging branch. There is info needed from our repo for our CI/CD testing. 16 | - Once your changes are merged and a more detailed review is complete, an authorized member will merge your changes into the main branch for a new release 17 | 18 | Signing your contribution 19 | ------------------------- 20 | 21 | We've chosen to use the Developer's Certificate of Origin (DCO) method 22 | that is employed by the Linux Kernel Project, which provides a simple 23 | way to contribute to MindPoint Group projects. 24 | 25 | The process is to certify the below DCO 1.1 text 26 | :: 27 | 28 | Developer's Certificate of Origin 1.1 29 | 30 | By making a contribution to this project, I certify that: 31 | 32 | (a) The contribution was created in whole or in part by me and I 33 | have the right to submit it under the open source license 34 | indicated in the file; or 35 | 36 | (b) The contribution is based upon previous work that, to the best 37 | of my knowledge, is covered under an appropriate open source 38 | license and I have the right under that license to submit that 39 | work with modifications, whether created in whole or in part 40 | by me, under the same open source license (unless I am 41 | permitted to submit under a different license), as indicated 42 | in the file; or 43 | 44 | (c) The contribution was provided directly to me by some other 45 | person who certified (a), (b) or (c) and I have not modified 46 | it. 47 | 48 | (d) I understand and agree that this project and the contribution 49 | are public and that a record of the contribution (including all 50 | personal information I submit with it, including my sign-off) is 51 | maintained indefinitely and may be redistributed consistent with 52 | this project or the open source license(s) involved. 53 | :: 54 | 55 | Then, when it comes time to submit a contribution, include the 56 | following text in your contribution commit message: 57 | 58 | :: 59 | 60 | Signed-off-by: Joan Doe 61 | 62 | :: 63 | 64 | 65 | This message can be entered manually, or if you have configured git 66 | with the correct `user.name` and `user.email`, you can use the `-s` 67 | option to `git commit` to automatically include the sign-off message. 68 | -------------------------------------------------------------------------------- /ChangeLog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Release 2.0.0 4 | 5 | #### March 2025 6 | General Updates 7 | - First Release for V3R3 STIG 8 | - Removed state: present from all win_regedit modules. 9 | - Added NIST Tagging 10 | - Added New Workflows 11 | 12 | ## Release 1.1.0 13 | 14 | #### August 2023 15 | - Updated Workflows To Central Repo 16 | - Renamed them to better run across all repos. 17 | - Removed Templates & PR Template from repo and adjusted to Org level. 18 | - Updated Readme Layout to add new pipeline badges. 19 | - Cat2_Cloud moved from tasks/main and renamed to cat2_cloud_lockout_order and in cat2.yml workflow. 20 | - Updated Tags in tasks/main. 21 | 22 | #### May 2023 23 | - Updated Pipelines For Testing 24 | - Added Banner 25 | - Added Skip For Testing to controls that will break in cloud. 26 | - Added Support for Azure for Controls that break. 27 | 28 | ## Release 1.0.0 29 | 30 | #### December 2022 31 | - Updated Readme 32 | - Added Changelog.md and updated. 33 | - Added Version 2 Release 3 changes during this update. 34 | - Added Version 2 Release 4 changes during this update. 35 | - Added Version 2 Release 5 changes during this update. 36 | - WN10-00-000030, WN10-00-000031, WN10-00-000032 - Changed Check text from 37 | “WVD” to “AVD” for Azure Virtual Desktop. 38 | - WN10-00-000040 - Updated Check and Fix: Windows servicing levels need to be updated. 39 | - WN10-AU-000550 - Removed requirement. 40 | - WN10-AU-000570 - Updated Fix text: Object Access >> “Audit Detailed File 41 | Share” with “Failure” selected. 42 | - WN10-CC-000007 - Updated Check and Fix registry label and settings with 43 | Value Name: Value; Value Data: Deny. 44 | - WN10-CC-000050, WN10-SO-000280 - Rule ID changed in data management system. 45 | - WN10-CC-000080 - Added requirement back to STIG per government and SHB. 46 | - WN10-CC-000327 - Rule ID changed due to reparenting SRG ID. 47 | - WN10-PK-000005, WN10-PK-000015 - Removed all deprecated DoD Root CA 2 references. 48 | - WN10-SO-000251 - Changed Check text: If the system is “not” a member of a domain, this 49 | is Not Applicable. 50 | - WN10-AU-000555 - Updated control because of removal of WN10-AU-000550 51 | - Update Rule ID's As Needed 52 | - Checked All Cat I, II, III Controls. 53 | - Removed WN10-EP Controls From Nov 1st 2021 Update 54 | - Added Version 2 Release 5 changes during this update. 55 | - WN10-00-000005, WN10-CC-000050 - Changed wording in the Check text from “standalone” to “standalone or nondomain-joined”. 56 | - WN10-00-000010, WN10-CC-000115, WN10-CC-000130, WN10-CC-000206, WN10-UR-000075, WN10-UR-000080 - Changed wording in the Check and Fix text 57 | from “standalone” to “standalone or nondomain-joined”. 58 | - WN10-00-000030, WN10-00-000031, WN10-00-000032, WN10-PK-000005, WN10- PK-000015 - Corrected CCIs. 59 | - WN10-00-000040 - Updated Check and Fix text regarding versioning. 60 | - WN10-CC-000055 - In Check and Fix text, set Minimize simultaneous connections to Enabled; set Minimize Policy Options to 3, Prevent Wi-Fi 61 | while on Ethernet. 62 | - Some Rule IDs and CCIs updated due to minor changes in content management system. 63 | - Added Warning Count For End Of Playbook 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Mindpoint Group - A Tyto Athene Company / Ansible Lockdown 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows 10 DISA STIG 2 | 3 | ## Configure a Windows 10 Enterprise system to be [DISA STIG](https://public.cyber.mil/stigs/downloads/) compliant. 4 | 5 | ### Based on [ Windows DISA STIG Version 3, Rel 3 released on January 30th, 2025 ](https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_MS_Windows_10_V3R3_STIG.zip) 6 | 7 | --- 8 | 9 | ![Org Stars](https://img.shields.io/github/stars/ansible-lockdown?label=Org%20Stars&style=social) 10 | ![Stars](https://img.shields.io/github/stars/ansible-lockdown/Windows-10-STIG?label=Repo%20Stars&style=social) 11 | ![Forks](https://img.shields.io/github/forks/ansible-lockdown/Windows-10-STIG?style=social) 12 | ![followers](https://img.shields.io/github/followers/ansible-lockdown?style=social) 13 | [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/AnsibleLockdown.svg?style=social&label=Follow%20%40AnsibleLockdown)](https://twitter.com/AnsibleLockdown) 14 | 15 | 16 | ![Discord Badge](https://img.shields.io/discord/925818806838919229?logo=discord) 17 | 18 | ![Release Branch](https://img.shields.io/badge/Release%20Branch-Main-brightgreen) 19 | ![Release Tag](https://img.shields.io/github/v/tag/ansible-lockdown/Windows-10-STIG?label=Release%20Tag&&color=success) 20 | ![Main Release Date](https://img.shields.io/github/release-date/ansible-lockdown/Windows-10-STIG?label=Release%20Date) 21 | 22 | [![Main Pipeline Validation](https://github.com/ansible-lockdown/Windows-10-STIG/actions/workflows/main_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/Windows-10-STIG/actions/workflows/main_pipeline_validation.yml) 23 | 24 | [![Devel Pipeline Validation](https://github.com/ansible-lockdown/Windows-10-STIG/actions/workflows/devel_pipeline_validation.yml/badge.svg?)](https://github.com/ansible-lockdown/Windows-10-STIG/actions/workflows/devel_pipeline_validation.yml) 25 | ![Devel Commits](https://img.shields.io/github/commit-activity/m/ansible-lockdown/Windows-10-STIG/devel?color=dark%20green&label=Devel%20Branch%20Commits) 26 | 27 | ![Issues Open](https://img.shields.io/github/issues-raw/ansible-lockdown/Windows-10-STIG?label=Open%20Issues) 28 | ![Issues Closed](https://img.shields.io/github/issues-closed-raw/ansible-lockdown/Windows-10-STIG?label=Closed%20Issues&&color=success) 29 | ![Pull Requests](https://img.shields.io/github/issues-pr/ansible-lockdown/Windows-10-STIG?label=Pull%20Requests) 30 | 31 | ![License](https://img.shields.io/github/license/ansible-lockdown/Windows-10-STIG?label=License) 32 | 33 | --- 34 | 35 | ## Looking For Support? 🤝 36 | 37 | [Lockdown Enterprise](https://www.lockdownenterprise.com#GH_AL_WINDOWS_10_stig) 38 | 39 | [Ansible Support](https://www.mindpointgroup.com/cybersecurity-products/ansible-counselor#GH_AL_WINDOWS_10_stig) 40 | 41 | ### Community 💬 42 | 43 | Join us on our [Discord Server](https://www.lockdownenterprise.com/discord) to ask questions, discuss features, or just chat with other Ansible-Lockdown users. 44 | 45 | --- 46 | 47 | ## 🚨 Caution(s) 🚨 48 | 49 | This role **will make changes to the system** which may have unintended consequences. This is not an auditing tool but rather a remediation tool to be used after an audit has been conducted. 50 | 51 | Check Mode is not supported! 🚫 The role will complete in check mode without errors, but it is not supported and should be used with caution. 52 | 53 | This role was developed against a clean install of the Windows 10. If you are implementing to an existing system please review this role for any site specific changes that are needed. 54 | 55 | To use release version please point to main branch and relevant release for the stig benchmark you wish to work with. 56 | 57 | --- 58 | 59 | ## Matching A Security Level For STIG 🔐 60 | 61 | It is possible to to only run controls that are based on a particular for security level for STIG. 62 | This is managed using tags: 63 | 64 | - CAT1 65 | - CAT2 66 | - CAT3 67 | 68 | The controls found in defaults/main also need to reflect those control numbers due to aligning every control to the audit component. 69 | 70 | ## Coming From A Previous Release ⏪ 71 | 72 | STIG releases always contain changes, it is highly recommended to review the new references and available variables. This has changed significantly since the initial release of ansible-lockdown. 73 | This is now compatible with python3 if it is found to be the default interpreter. This does come with pre-requisites which it configures the system accordingly. 74 | 75 | Further details can be seen in the [Changelog](./ChangeLog.md) 76 | 77 | ## Auditing (new) 🔍 78 | 79 | Currently this release does not have a auditing tool that is up to date. 80 | 81 | ## Documentation 📖 82 | 83 | - [Read The Docs](https://ansible-lockdown.readthedocs.io/en/latest/) 84 | - [Getting Started](https://www.lockdownenterprise.com/docs/getting-started-with-lockdown#GH_AL_WINDOWS_10_stig) 85 | - [Customizing Roles](https://www.lockdownenterprise.com/docs/customizing-lockdown-enterprise#GH_AL_WINDOWS_10_stig) 86 | - [Per-Host Configuration](https://www.lockdownenterprise.com/docs/per-host-lockdown-enterprise-configuration#GH_AL_WINDOWS_10_stig) 87 | - [Getting the Most Out of the Role](https://www.lockdownenterprise.com/docs/get-the-most-out-of-lockdown-enterprise#GH_AL_WINDOWS_10_stig) 88 | 89 | ## Requirements ✅ 90 | 91 | **General:** 92 | 93 | - Basic knowledge of Ansible, below are some links to the Ansible documentation to help get started if you are unfamiliar with Ansible 94 | 95 | - [Main Ansible documentation page](https://docs.ansible.com) 96 | - [Ansible Getting Started](https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html) 97 | - [Tower User Guide](https://docs.ansible.com/ansible-tower/latest/html/userguide/index.html) 98 | - [Ansible Community Info](https://docs.ansible.com/ansible/latest/community/index.html) 99 | - Functioning Ansible and/or Tower Installed, configured, and running. This includes all of the base Ansible/Tower configurations, needed packages installed, and infrastructure setup. 100 | - Please read through the tasks in this role to gain an understanding of what each control is doing. Some of the tasks are disruptive and can have unintended consequences in a live production system. Also familiarize yourself with the variables in the defaults/main.yml file. 101 | 102 | **Technical Dependencies:** ⚙️ 103 | 104 | - Windows 10 Enterprise 22H2 - Other versions are not supported 105 | - Running Ansible/Tower setup (this role is tested against Ansible version 2.10.1 and newer) 106 | - Python3 Ansible run environment 107 | - passlib (or python2-passlib, if using python2) 108 | - python-lxml 109 | - python-xmltodict 110 | - python-jmespath 111 | - pywinrm 112 | 113 | Package 'python-xmltodict' is required if you enable the OpenSCAP tool installation and run a report. Packages python(2)-passlib and python-jmespath are required for tasks with custom filters or modules. These are all required on the controller host that executes Ansible. 114 | 115 | ## Role Variables 📋 116 | 117 | This role is designed so that the end user should not have to edit the tasks themselves. All customizing should be done via the defaults/main.yml file or with extra vars within the project, job, workflow, etc. 118 | 119 | ## Tags 🏷️ 120 | 121 | There are many tags available for added control precision. Each control has its own set of tags noting what level, what OS element it relates to, whether it's a patch or audit, and the rule number. Additionally, NIST references follow a specific conversion format for consistency and clarity. 122 | 123 | ### Conversion Format for NIST References: 124 | 125 | 1. Standard Prefix: 126 | 127 | - All references are prefixed with "NIST SP". 128 | 129 | 2. Standard Types: 130 | 131 | - "800-53" references are formatted as NIST800-53. 132 | - "800-53A" references are formatted as NIST800-53A. 133 | - "800-53r4" references are formatted as NIST800-53R4 (with 'R' capitalized). 134 | 135 | 3. Details: 136 | 137 | - Section and subsection numbers use periods (.) for numeric separators. 138 | - Parenthetical elements are separated by underscores (_), e.g., IA-5(1)(d) becomes IA-5_1_d. 139 | - Subsection letters (e.g., "b") are appended with an underscore. 140 | 141 | ### Example of Tag Usage: 142 | Below is an example of the tag section from a control within this role. Using this example, if you set your run to skip all controls with the tag CCI-000018, this task will be skipped. Conversely, you can choose to run only controls tagged with CCI-000018. 143 | 144 | ```sh 145 | tags: 146 | - WN10-AU-000040 147 | - CAT2 148 | - CCI-000018 149 | - CCI-000172 150 | - CCI-001403 151 | - CCI-001404 152 | - CCI-001405 153 | - CCI-002130 154 | - CCI-002234 155 | - SRG-OS-000004-GPOS-00004 156 | - SV-220752r958368_rule 157 | - V-220752 158 | - NIST800-53_AC-2_4 159 | - NIST800-53_AU-12_c 160 | - NIST800-53A_AC-2_4.1_i&ii 161 | - NIST800-53A_AC-12.1_iv 162 | - NIST800-53R4_AC-2_4 163 | - NIST800-53R4_AU-12_c 164 | ``` 165 | ### Conversion Examples in Use: 166 | - NIST SP 800-53 :: AC-2 (4) → NIST800-53_AC-2_4 167 | - NIST SP 800-53A :: AC-2 (4).1 (i&ii) → NIST800-53A_AC-2_4.1_i&ii 168 | - NIST SP 800-53 Revision 4 :: AC-2 (4) → NIST800-53_AC-2_4 169 | - NIST SP 800-53 :: AU-12 c → NIST800-53_AU-12_c 170 | - NIST SP 800-53A :: AU-12.1 (iv) → NIST800-53A_AC-12.1_iv 171 | - NIST SP 800-53 Revision 4 :: AU-12 c → NIST800-53R4_AU-12_c 172 | 173 | By maintaining this consistent tagging structure, it becomes easier to filter and manage tasks based on specific controls and compliance requirements. 174 | 175 | ## Community Contribution 🧑‍🤝‍🧑 176 | 177 | We encourage you (the community) to contribute to this role. Please read the rules below. 178 | 179 | - Your work is done in your own individual branch. Make sure to Signed-off and GPG sign all commits you intend to merge. 180 | - All community Pull Requests are pulled into the devel branch. 181 | - Pull Requests into devel will confirm your commits have a GPG signature, Signed-off, and a functional test before being approved. 182 | - Once your changes are merged and a more detailed review is complete, an authorized member will merge your changes into the main branch for a new release. 183 | 184 | ## Pipeline Testing 🔄 185 | 186 | uses: 187 | 188 | - ansible-core 2.16.x 189 | - ansible collections - pulls in the latest version based on requirements file 190 | - runs the audit using the devel branch 191 | - This is an automated test that occurs on pull requests into devel 192 | - self-hosted runners using OpenTofu 193 | 194 | ## Local Testing 💻 195 | 196 | - Ansible 197 | - ansible-core 2.18.2 - python 3.13 198 | 199 | ## Credits and Thanks 🙏 200 | 201 | Massive thanks to the fantastic community and all its members. 202 | 203 | This includes a huge thanks and credit to the original authors and maintainers. 204 | 205 | -------------------------------------------------------------------------------- /collections/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | collections: 4 | - name: ansible.windows 5 | type: git 6 | source: https://github.com/ansible-collections/ansible.windows 7 | 8 | - name: community.windows 9 | type: git 10 | source: https://github.com/ansible-collections/community.windows 11 | 12 | - name: community.general 13 | type: git 14 | source: https://github.com/ansible-collections/community.general 15 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | win10stig_cat1_patch: true 4 | win10stig_cat2_patch: true 5 | win10stig_cat3_patch: true 6 | 7 | # Global Variables 8 | 9 | win10stig_min_ansible_version: "2.16" 10 | 11 | # This parameter disables controls that could have a very lengthy find. For example 12 | # removing all files of a specific file type that search the entire drive. 13 | # If there is an action tied to the lengthy search the action task will be disabled as well. 14 | # WN10-00-000130 - CAT2 15 | # Default: true 16 | win10stig_lengthy_search: true 17 | 18 | # win_skip_for_test is used in the playbook to skip over certain controls that 19 | # may cause breaking changes when running it for testing purposes. These generally consist of winrmvi host controls 20 | # that are needed to keep the ansible connection alive. 21 | # Controls that will be skipped: 22 | # WN10-CC-000330 - CAT1 - Disables WinRM Allow Client Basic Auth 23 | # WN10-CC-000345 - CAT1 - Disables WinRM Allow Service Basic Auth 24 | # WN10-CC-000335 - CAT2 - The Windows Remote Management (WinRM) client must not allow unencrypted traffic. 25 | # WN10-CC-000350 - CAT2 - The Windows Remote Management (WinRM) service must not allow unencrypted traffic. 26 | # WN10-SO-000005 - CAT2 - Disables Built-In Admin Account 27 | # WN10-SO-000230 - CAT2 - The system must be configured to use FIPS-compliant algorithms for encryption, hashing, and signing. 28 | # Default: false 29 | win_skip_for_test: false 30 | 31 | # Changes will be made that will require a system reboot. 32 | # The following option will allow whether or not to skip the reboot. 33 | # Default: true 34 | skip_reboot: true 35 | 36 | # These variables correspond with the STIG IDs defined in the STIG and allows you to enable/disable specific rules. 37 | # PLEASE NOTE: These work in coordination with the cat1, cat2, cat3 group variables. You must enable an entire group 38 | # in order for the variables below to take effect. 39 | 40 | # CAT 1 Rules 41 | wn10_00_000030: true 42 | wn10_00_000031: true 43 | wn10_00_000032: true 44 | wn10_00_000040: true 45 | wn10_00_000045: true 46 | wn10_00_000050: true 47 | wn10_00_000070: true 48 | wn10_00_000100: true 49 | wn10_00_000145: true 50 | wn10_00_000150: true 51 | wn10_00_000240: true 52 | wn10_ac_000045: true 53 | wn10_cc_000075: true 54 | wn10_cc_000155: true 55 | wn10_cc_000180: true 56 | wn10_cc_000185: true 57 | wn10_cc_000190: true 58 | wn10_cc_000315: true 59 | wn10_cc_000330: true 60 | wn10_cc_000345: true 61 | wn10_so_000140: true 62 | wn10_so_000145: true 63 | wn10_so_000150: true 64 | wn10_so_000165: true 65 | wn10_so_000195: true 66 | wn10_so_000205: true 67 | wn10_ur_000015: true 68 | wn10_ur_000045: true 69 | wn10_ur_000065: true 70 | 71 | # CAT 2 Rules 72 | wn10_00_000005: true 73 | wn10_00_000010: true 74 | wn10_00_000015: true 75 | wn10_00_000025: true 76 | wn10_00_000035: true 77 | wn10_00_000055: true 78 | wn10_00_000060: true 79 | wn10_00_000075: true 80 | wn10_00_000080: true 81 | wn10_00_000090: true 82 | wn10_00_000095: true 83 | wn10_00_000105: true 84 | wn10_00_000110: true 85 | wn10_00_000115: true 86 | wn10_00_000120: true 87 | wn10_00_000130: true 88 | wn10_00_000135: true 89 | wn10_00_000140: true 90 | wn10_00_000155: true 91 | wn10_00_000160: true 92 | wn10_00_000165: true 93 | wn10_00_000170: true 94 | wn10_00_000175: true 95 | wn10_00_000190: true 96 | wn10_00_000210: true 97 | wn10_00_000220: true 98 | wn10_00_000230: true 99 | wn10_00_000250: true 100 | wn10_ac_000005: true 101 | wn10_ac_000010: true 102 | wn10_ac_000015: true 103 | wn10_ac_000020: true 104 | wn10_ac_000025: true 105 | wn10_ac_000030: true 106 | wn10_ac_000035: true 107 | wn10_ac_000040: true 108 | wn10_au_000005: true 109 | wn10_au_000010: true 110 | wn10_au_000030: true 111 | wn10_au_000035: true 112 | wn10_au_000040: true 113 | wn10_au_000045: true 114 | wn10_au_000050: true 115 | wn10_au_000054: true 116 | wn10_au_000060: true 117 | wn10_au_000065: true 118 | wn10_au_000070: true 119 | wn10_au_000075: true 120 | wn10_au_000080: true 121 | wn10_au_000081: true 122 | wn10_au_000082: true 123 | wn10_au_000083: true 124 | wn10_au_000084: true 125 | wn10_au_000085: true 126 | wn10_au_000090: true 127 | wn10_au_000100: true 128 | wn10_au_000105: true 129 | wn10_au_000107: true 130 | wn10_au_000110: true 131 | wn10_au_000115: true 132 | wn10_au_000120: true 133 | wn10_au_000130: true 134 | wn10_au_000135: true 135 | wn10_au_000140: true 136 | wn10_au_000150: true 137 | wn10_au_000155: true 138 | wn10_au_000160: true 139 | wn10_au_000500: true 140 | wn10_au_000505: true 141 | wn10_au_000510: true 142 | wn10_au_000515: true 143 | wn10_au_000520: true 144 | wn10_au_000525: true 145 | wn10_au_000555: true 146 | wn10_au_000560: true 147 | wn10_au_000565: true 148 | wn10_au_000570: true 149 | wn10_au_000575: true 150 | wn10_au_000580: true 151 | wn10_cc_000005: true 152 | wn10_cc_000007: true 153 | wn10_cc_000010: true 154 | wn10_cc_000020: true 155 | wn10_cc_000025: true 156 | wn10_cc_000037: true 157 | wn10_cc_000038: true 158 | wn10_cc_000039: true 159 | wn10_cc_000040: true 160 | wn10_cc_000044: true 161 | wn10_cc_000052: true 162 | wn10_cc_000055: true 163 | wn10_cc_000060: true 164 | wn10_cc_000065: true 165 | wn10_cc_000066: true 166 | wn10_cc_000068: true 167 | wn10_cc_000070: true 168 | wn10_cc_000085: true 169 | wn10_cc_000090: true 170 | wn10_cc_000100: true 171 | wn10_cc_000105: true 172 | wn10_cc_000110: true 173 | wn10_cc_000115: true 174 | wn10_cc_000120: true 175 | wn10_cc_000130: true 176 | wn10_cc_000145: true 177 | wn10_cc_000150: true 178 | wn10_cc_000165: true 179 | wn10_cc_000195: true 180 | wn10_cc_000200: true 181 | wn10_cc_000204: true 182 | wn10_cc_000205: true 183 | wn10_cc_000210: true 184 | wn10_cc_000215: true 185 | wn10_cc_000225: true 186 | wn10_cc_000230: true 187 | wn10_cc_000235: true 188 | wn10_cc_000238: true 189 | wn10_cc_000245: true 190 | wn10_cc_000250: true 191 | wn10_cc_000252: true 192 | wn10_cc_000255: true 193 | wn10_cc_000260: true 194 | wn10_cc_000270: true 195 | wn10_cc_000275: true 196 | wn10_cc_000280: true 197 | wn10_cc_000285: true 198 | wn10_cc_000290: true 199 | wn10_cc_000295: true 200 | wn10_cc_000300: true 201 | wn10_cc_000305: true 202 | wn10_cc_000310: true 203 | wn10_cc_000320: true 204 | wn10_cc_000325: true 205 | wn10_cc_000326: true 206 | wn10_cc_000335: true 207 | wn10_cc_000350: true 208 | wn10_cc_000355: true 209 | wn10_cc_000360: true 210 | wn10_cc_000365: true 211 | wn10_cc_000370: true 212 | wn10_cc_000385: true 213 | wn10_ep_000310: true 214 | wn10_pk_000005: true 215 | wn10_pk_000010: true 216 | wn10_pk_000015: true 217 | wn10_pk_000020: true 218 | wn10_rg_000005: true 219 | wn10_so_000005: true 220 | wn10_so_000010: true 221 | wn10_so_000015: true 222 | wn10_so_000020: true 223 | wn10_so_000025: true 224 | wn10_so_000030: true 225 | wn10_so_000035: true 226 | wn10_so_000040: true 227 | wn10_so_000045: true 228 | wn10_so_000060: true 229 | wn10_so_000070: true 230 | wn10_so_000075: true 231 | wn10_so_000095: true 232 | wn10_so_000100: true 233 | wn10_so_000120: true 234 | wn10_so_000160: true 235 | wn10_so_000167: true 236 | wn10_so_000180: true 237 | wn10_so_000185: true 238 | wn10_so_000190: true 239 | wn10_so_000210: true 240 | wn10_so_000215: true 241 | wn10_so_000220: true 242 | wn10_so_000230: true 243 | wn10_so_000245: true 244 | wn10_so_000250: true 245 | wn10_so_000251: true 246 | wn10_so_000255: true 247 | wn10_so_000260: true 248 | wn10_so_000265: true 249 | wn10_so_000270: true 250 | wn10_so_000275: true 251 | wn10_so_000280: true 252 | wn10_uc_000020: true 253 | wn10_ur_000005: true 254 | wn10_ur_000010: true 255 | wn10_ur_000025: true 256 | wn10_ur_000030: true 257 | wn10_ur_000035: true 258 | wn10_ur_000040: true 259 | wn10_ur_000050: true 260 | wn10_ur_000055: true 261 | wn10_ur_000060: true 262 | wn10_ur_000070: true 263 | wn10_ur_000075: true 264 | wn10_ur_000080: true 265 | wn10_ur_000085: true 266 | wn10_ur_000090: true 267 | wn10_ur_000095: true 268 | wn10_ur_000100: true 269 | wn10_ur_000110: true 270 | wn10_ur_000120: true 271 | wn10_ur_000125: true 272 | wn10_ur_000130: true 273 | wn10_ur_000140: true 274 | wn10_ur_000145: true 275 | wn10_ur_000150: true 276 | wn10_ur_000160: true 277 | wn10_ur_000165: true 278 | wn10_cc_000050: true 279 | wn10_cc_000327: true 280 | wn10_cc_000391: true 281 | wn10_00_000395: true 282 | wn10_au_000585: true 283 | wn10_00_000125: true 284 | wn10_cc_000063: true 285 | 286 | # CAT 3 Rules 287 | wn10_00_000020: true 288 | wn10_00_000065: true 289 | wn10_00_000085: true 290 | wn10_cc_000030: true 291 | wn10_cc_000035: true 292 | wn10_cc_000170: true 293 | wn10_cc_000175: true 294 | wn10_cc_000197: true 295 | wn10_cc_000206: true 296 | wn10_cc_000220: true 297 | wn10_cc_000390: true 298 | wn10_so_000050: true 299 | wn10_so_000055: true 300 | wn10_so_000080: true 301 | wn10_so_000085: true 302 | wn10_so_000240: true 303 | wn10_uc_000015: true 304 | wn10_cc_000080: true 305 | 306 | # CAT1 307 | 308 | # WN10-00-000031 309 | # win10stig_bitlocker_network_unlock is the setting that will make the necessary adjustments 310 | # to the registry for bitlocker unlocking over the network. 311 | # Default: false 312 | win10stig_bitlocker_network_unlock: false 313 | 314 | # WN10-00-000032 315 | # win10stig_bitlocker_min_pin_length is the minimum length for the BitLocker PIN 316 | # This value needs to be 6 or greater 317 | # Default: 6 318 | win10stig_bitlocker_min_pin_length: 6 319 | 320 | # WN10-00-000045 321 | # win10stig_av_sftw is the service name of the AV software you are using. This is Service Name, not Display Name 322 | # Windows Defender = WinDefend 323 | # AVG Antivirus = AVG Antivirus 324 | # Total AV Antivirus = SecurityService 325 | # ESET Antivirus = ekrn 326 | # Malwarebytes = MBAMServic 327 | # Bitdefender = VSSERV 328 | # Trend Micro = Amsp 329 | # Panda = PSUAService 330 | # Avast = AvastSvc 331 | # Kaspersky = 332 | # Norton = 333 | # McAfee = 334 | # To be STIG compliant you need to have either Windows Defender AV enabled/running or a 3rd party AV running 335 | # (McAfee or Symantec for example) 336 | # Default: WinDefend 337 | win10stig_av_sftw: WinDefend 338 | 339 | # WN10-00-000100 340 | # win10stig_web_server is the variable related to what types of services should be 341 | # running on Windows 10 342 | # True means Windows 10 will be running a application that requires IIS. 343 | # Default: false 344 | win10stig_web_server: false 345 | 346 | # WN10-00-000145 347 | # wn10stig_dep_value is the value to set DEP to. To comply with STIG standards at least OptOut level needs to be set. 348 | # AlwaysOn, a more restrictive selection, is also valid but does not allow applications that do not function properly to be opted out of DEP. 349 | # Value options are AlwaysOn or OptOut. If OptOut is used you will need to manually select what applications to opt out of DEP 350 | # Default: OptOut 351 | wn10stig_dep_value: OptOut 352 | # wn10stig_dep_optout_apps is the list of apps to be opted out of DEP. Leaving blank will not configure 353 | # that list in the registry. 354 | # Example: 355 | # wn10stig_dep_included_apps: 356 | # - "C:\\Program Files\\App1\\app1.exe" 357 | # - "C:\\Users\\User\\AppData\\Local\\App2\\app2.exe" 358 | # - "C:\\Program Files (x86)\\App3\\app3.exe" 359 | # Default: [] 360 | wn10stig_dep_optout_apps: [] 361 | 362 | # WN10-00-000240 363 | # wn10stig_internet_based_apps_to_check is a list of apps that can have access to the internet that are commonly found. 364 | # This list is not all inclusive and can be added to or have items removed. 365 | # STIG states you must establish and enforce a policy that prohibits administrative accounts from using 366 | # applications that access the internet, such as web browsers, or with potential internet sources, such as email. 367 | # Define specific exceptions for local service administration. These exceptions may include HTTP(S)-based tools that are used 368 | # for the administration of the local system, services, or attached devices. 369 | wn10stig_internet_based_apps_to_check: 370 | - "chrome.exe" 371 | - "firefox.exe" 372 | - "iexplore.exe" 373 | - "edge.exe" 374 | - "opera.exe" 375 | - "brave.exe" 376 | - "vivaldi.exe" 377 | - "safari.exe" 378 | - "tor.exe" 379 | - "outlook.exe" 380 | - "thunderbird.exe" 381 | - "mail.exe" 382 | - "emclient.exe" 383 | - "postbox.exe" 384 | - "slack.exe" 385 | - "discord.exe" 386 | - "teams.exe" 387 | - "skype.exe" 388 | - "zoom.exe" 389 | - "whatsapp.exe" 390 | - "telegram.exe" 391 | - "signal.exe" 392 | - "mstsc.exe" 393 | - "teamviewer.exe" 394 | - "anydesk.exe" 395 | - "vncviewer.exe" 396 | - "citrix.exe" 397 | - "dropbox.exe" 398 | - "googledrive.exe" 399 | - "onedrive.exe" 400 | - "boxsync.exe" 401 | - "mega.exe" 402 | - "spotify.exe" 403 | - "tiktok.exe" 404 | - "youtube.exe" 405 | - "twitch.exe" 406 | - "chromedriver.exe" 407 | 408 | # CAT2 409 | 410 | # WN10-00-000025 411 | # win10stig_ess_software is the name and service that will be running on the machine that is used 412 | # for continuous network scanning and must be installed and configured to run. 413 | # NOTE: There are many possible vendors that can be placed here. Some examples are provided below. 414 | # - name: "McAfee/Trellix HBSS (ePO, ENS)" 415 | # services: ["MfeEpoAgent", "McShield", "mfefire"] 416 | # - name: "Microsoft Defender for Endpoint (MDE)" 417 | # services: ["Sense", "WdNisSvc", "WinDefend"] 418 | # - name: "Tenable ACAS (Nessus Scanner)" 419 | # services: ["Tenable Nessus"] 420 | # - name: "Ivanti Patch for Windows" 421 | # services: ["IvantiPatchService"] 422 | # - name: "BeyondTrust Endpoint Privilege Management" 423 | # services: ["BeyondTrustEPM"] 424 | # - name: "Bitdefender GravityZone" 425 | # services: ["bdservicehost"] 426 | # - name: "Carbon Black Defense" 427 | # services: ["CbDefense"] 428 | # - name: "Symantec Endpoint Protection" 429 | # services: ["SepMasterService"] 430 | # - name: "Trend Micro Apex One" 431 | # services: ["ntrtscan"] 432 | # Leave blank to disable scanning 433 | # Default: 434 | # name: "" 435 | # services: [] 436 | win10stig_ess_software: 437 | name: "" 438 | services: [] 439 | 440 | # WN10-00-000035 441 | # win10stig_applocker_output will allow end user to decide if they would like it output to XML file for audit purpose 442 | # or if the end user would like it displayed in stdout for review. 443 | # 1 - XML File (Default) 444 | # 2 - stdout 445 | # Default: 2 446 | win10stig_applocker_output: 2 447 | win10stig_applocker_xml_output: c:\temp\applocker_output.xml 448 | 449 | # WN10-00-000090 450 | # win10stig_password_expires is the setting that will automatically remediate any local accounts on the 451 | # system where passwords are set to never expire to now expire. By default this is set to false so that 452 | # can be reviewed manually first using the warning system. 453 | # Default: false 454 | win10stig_password_expires: false 455 | 456 | # WN10-00-000130 457 | # win10stig_certificate_exclusion_paths is the list of paths that will be skipped when searching for *.p12 and *.pfx files. 458 | # This does not apply to server-based applications that have a requirement for .p12 certificate files (e.g., Oracle Wallet Manager) 459 | # or Adobe PreFlight certificate files. Some applications create files with extensions of .p12 that are not certificate 460 | # installation files. Removal of non-certificate installation files from systems is not required. These must be documented with the ISSO. 461 | # Below is the default list of extensions to skip based on STIG recommended settings. This list may be expanded as well. 462 | # Default: 463 | # - "C:\\Program Files\\Oracle\\WalletManager" 464 | # - "C:\\Program Files (x86)\\Oracle\\WalletManager" 465 | # - "C:\\Program Files\\Adobe\\Preflight" 466 | # - "C:\\Program Files (x86)\\Adobe\\Preflight" 467 | win10stig_certificate_exclusion_paths: 468 | - "C:\\Program Files\\Oracle\\WalletManager" 469 | - "C:\\Program Files (x86)\\Oracle\\WalletManager" 470 | - "C:\\Program Files\\Adobe\\Preflight" 471 | - "C:\\Program Files (x86)\\Adobe\\Preflight" 472 | # win10stig_auto_remediate_files is the setting that will automatically remove '*.p12', '*.pfx' files that are not in the 473 | # exclusion list above. By default we have it set to true to remediate per the STIG standards. If set to false there 474 | # will be a warning message that gets displayed with the files that need to be removed either manually or by setting 475 | # win10stig_auto_remediate_files: true and the Ansible will have to be run again. 476 | # Default: true 477 | win10stig_auto_remediate_files: true 478 | 479 | # WN10-00-000140 480 | # win10stig_authorized_remote_management_hosts is the variable 481 | # Example of the hosts added below. 482 | # win10stig_authorized_remote_management_hosts: 483 | # - "192.168.1.10" 484 | # - "10.10.10.0/24" 485 | # Default: [] 486 | win10stig_authorized_remote_management_hosts: [] 487 | # win10stig_remove_unauthorized_hosts is the value that when set to true will remove any hosts that are not listed 488 | # above in "win10stig_authorized_remote_management_hosts. 489 | # Default: false 490 | win10stig_remove_unauthorized_hosts: false 491 | 492 | # WN10-00-000250 493 | # win10stig_non_persistent_max_session_timeout is the setting to apply so that Windows systems that are 494 | # nonpersistent VM sessions must not exceed 24 hours. Make sure you enter the time in the milliseconds. 495 | # By default we do not have this set and will give you a warning to review policies. Setting this to a value 496 | # in milliseconds will remediate the following registry values with the same values. 497 | # KLM:\SOFTWARE\Policies\Microsoft\Windows\Terminal Services 498 | # MaxDisconnectionTime 499 | # MaxIdleTime 500 | # MaxSessionTime 501 | # To convert to hours take the number wn10_00_000250_session_timeout_value / 3600000 gives you hours. 502 | # Note: 24 Hours = 86400000 503 | # Default: [] 504 | win10stig_non_persistent_max_session_timeout: [] 505 | 506 | # WN10-AC-000005 507 | # win10stig_account_lockout_duration is the policy setting determines the length of time that 508 | # must pass before a locked account is unlocked and a user can try to log on again. 509 | # NOTE: If the value for this policy setting is configured to 0, locked-out accounts will remain locked-out 510 | # until an administrator manually unlocks them. Configuring this to "0", requiring an administrator to unlock 511 | # the account, is more restrictive and is not a finding. 512 | # The recommended state for this setting is: 15 or more minute(s). 513 | # Default: 15 514 | win10stig_account_lockout_duration: 15 515 | 516 | # WN10-AC-000010 517 | # win10stig_bad_login_lockout_count is the policy setting determines the number of failed logon 518 | # attempts before the account is locked. 519 | # The recommended state for this setting is: 3 or fewer invalid logon attempt(s), but not 0. 520 | # Default: 3 521 | win10stig_bad_login_lockout_count: 3 522 | 523 | # WN10-AC-000015 524 | # win10stig_account_lockout_counter_reset is the policy setting that determines the length of time before the 525 | # Account lockout threshold resets to zero. The default value for this policy setting is Not Defined. 526 | # NOTE: If the Account lockout threshold is defined (win10stig_account_lockout_duration), this reset 527 | # time must be less than or equal to the value for the Account lockout duration setting. 528 | # The recommended state for this setting is: 15 minute(s). 529 | # Default: 15 530 | win10stig_account_lockout_counter_reset: 15 531 | 532 | # WN10-AC-000020 533 | # win10stig_max_passwords_saved is the variable used to dictate the number of unique passwords 534 | # that have to be associated with a user account before you can reuse an old password. 535 | # The recommended state for this setting is 24 Or More passwords. 536 | # NOTE: As Of the publication if this benchmark, Microsoft has a maximum limit of 24 saved passwords. 537 | # This may change at a later date but we have left it setup as a variable for that reason. 538 | # Default: 24 539 | win10stig_max_passwords_saved: 24 540 | 541 | # WN10-AC-000025 542 | # win10stig_maximum_password_age is the policy setting defines how long a user can use their 543 | # password before it expires. 544 | # The recommended state for this setting is: 60 or fewer days, but not 0 (zero). 545 | # Default: 60 546 | win10stig_maximum_password_age: 60 547 | 548 | # WN10-AC-000030 549 | # win10stig_minimum_password_age is the policy setting determines the number of days that you 550 | # must use a password before you can change it. The range of values for this policy setting is 551 | # between 1 and 999 days. 552 | # NOTE: The minimum number cannot exceed the maximum days. 553 | # The recommended state for this setting is: 1 or more day(s) 554 | # Default: 1 555 | win10stig_minimum_password_age: 1 556 | 557 | # WN10-AC-000035 558 | # win10stig_minimum_password_length is the policy setting determines the least number of characters 559 | # that make up a password for a user account. 560 | # The recommended state for this setting is: 14 or more character(s). 561 | # Default: 14 562 | win10stig_minimum_password_length: 14 563 | 564 | # WN10-AU-000500 565 | # win10stig_application_max_log_file_size is the setting that specifies the maximum size of the log file in kilobytes. 566 | # The maximum log file size can be configured between 1 megabyte (1,024 kilobytes) and 4 terabytes 567 | # (4,194,240 kilobytes) in kilobyte increments. 568 | # The recommended state for this setting is: Enabled: 32,768 or greater. 569 | # Default: 32768 570 | win10stig_application_max_log_file_size: 32768 571 | 572 | # WN10-AU-000505 573 | # win10stig_security_max_log_file_size is the setting that specifies the maximum size of the log file in kilobytes. 574 | # The maximum log file size can be configured between 1 megabyte (1,024 kilobytes) and 4 terabytes 575 | # (4,194,240 kilobytes) in kilobyte increments. 576 | # The recommended state for this setting is: Enabled: 1024000 or greater. 577 | # Default: 1024000 578 | win10stig_security_max_log_file_size: 1024000 579 | 580 | # WN10-AU-000510 581 | # win10stig_system_max_log_file_size is the setting that specifies the maximum size of the log file in kilobytes. 582 | # The maximum log file size can be configured between 1 megabyte (1,024 kilobytes) and 4 terabytes (4,194,240 kilobytes) in kilobyte increments. 583 | # The recommended state for this setting is: Enabled: 32,768 or greater. 584 | # Default: 32768 585 | win10stig_system_max_log_file_size: 32768 586 | 587 | # WN10-CC-000007 588 | # win10stig_allowed_to_use_camera variable determines whether the use of a camera on a Windows 10 589 | # system is permitted based on security compliance requirements. If a camera is installed, it 590 | # must either be disconnected, covered, or disabled in BIOS to meet security standards. 591 | # This requirement is not applicable in the following cases: 592 | # The system does not have a camera installed. 593 | # The device is a mobile device (smartphones or tablets) where camera use is locally authorized. 594 | # The system is part of a dedicated VTC suite in an approved, centrally managed location. 595 | # Scenarios: 596 | # No camera detected - Skips the requirement (No registry change needed). 597 | # win10stig_allowed_to_use_camera: false - Disables all cameras via registry (Deny). 598 | # win10stig_allowed_to_use_camera: true & Built-in Camera Found - Disables the built-in camera via registry. 599 | # win10stig_allowed_to_use_camera: true & USB Camera Found - Issues a warning (but does not disable it). 600 | # Default: false 601 | win10stig_allowed_to_use_camera: false 602 | # Set to true to skip hardening for VTC/Mobile devices or mobile devices (smartphones and tablets) 603 | # where the use of the camera is a local AO decision. 604 | # Default: false 605 | win10stig_ignore_camera_hardening: false 606 | 607 | # WN10-CC-000070 608 | # win10stig_enable_virtualization_based_security is the policy setting specifies whether Virtualization Based Security (VBS) is enabled. 609 | # VBS uses the Windows Hypervisor to provide support for security services. 610 | # The recommended state for this setting is: Secure Boot or Secure Boot and DMA Protection. 611 | # 1 - Secure Boot 612 | # 3 - Secure Boot and DMA Protection 613 | # Default: 1 614 | win10stig_enable_virtualization_based_security: 1 615 | 616 | # WN10-CC-000085 617 | # win10stig_boot_driver_init_policy is the default behavior for Early Launch Antimalware - Boot-Start Driver Initialization Policy 618 | # Options are list below, a value of 7 (All) does not conform to STIG standards 619 | # 1 - Good and unknown 620 | # 3 - Good, unknown and bad but critical (Windows default) 621 | # 8 - Good only 622 | # Default: 3 623 | win10stig_boot_driver_init_policy: 3 624 | 625 | # WN10-CC-000205 626 | # win10stig_allow_telemetry_value is the value set to Allow Telemetry registry setting 627 | # To comply with STIG requirements please use only the settings below 628 | # NOTE: Full will not be a acceptable input here. The control states that FULL should not be 629 | # set. If you need full then control WN10-CC-000204 will bring it into compliance per the 630 | # stig rules and this control should be set to false. 631 | # 0 - Security 632 | # 1 - Basic 633 | # Default: 1 634 | win10stig_allow_telemetry_value: 1 635 | 636 | # WN10-CC-000260 637 | # win10stig_min_pin_length is the minimum PIN length for setting authentication PIN's 638 | # This value needs to be 6 or greater to conform to STIG standards 639 | # Default: 6 640 | win10stig_min_pin_length: 6 641 | 642 | # WN10-SO-000020 643 | # win10stig_admin_username is the name the built-in Administrator account will be renamed to. 644 | # The built-in local administrator account is a well-known account name that attackers will target. It is 645 | # recommended to choose another name for this account, and to avoid names that denote administrative or elevated access 646 | # accounts. Be sure to also change the default description for the local administrator (through the Computer 647 | # Management console). 648 | # Default: adminchangethis 649 | win10stig_admin_username: adminchangethis 650 | 651 | # WN10-SO-000025 652 | # win10stig_guest_username is the name the built-in Guest account will be renamed to 653 | # The built-in local guest account is another well-known name to attackers. It is recommended to rename this account 654 | # to something that does not indicate its purpose. Even if you disable this account, which is recommended, ensure 655 | # that you rename it for added security. 656 | # Default: guestchangethis 657 | win10stig_guest_username: guestchangethis 658 | 659 | # WN10-SO-000070 660 | # win10stig_inactivity_timeout_seconds is the machine inactivity limit in seconds. 661 | # To conform to STIG this value needs to be 900 seconds or less, excluding 0 which disables the inactivity limit 662 | # Default: 900 663 | win10stig_inactivity_timeout_seconds: 900 664 | 665 | # WN10-SO-000075 666 | # win10stig_legal_notice is the legal banner/notice displayed prior to a logon attempt 667 | win10stig_legal_notice: | 668 | You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. 669 | 670 | By using this IS (which includes any device attached to this IS), you consent to the following conditions: 671 | 672 | -The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations. 673 | 674 | -At any time, the USG may inspect and seize data stored on this IS. 675 | 676 | -Communications using, or data stored on, this IS are not private, are subject to routine monitoring, interception, and search, and may be disclosed or used for any USG-authorized purpose. 677 | 678 | -This IS includes security measures (e.g., authentication and access controls) to protect USG interests--not for your personal benefit or privacy. 679 | 680 | -Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching or monitoring of the content of privileged communications, or work product, related to personal representation or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details. 681 | 682 | # WN10-SO-000095 683 | # win10stig_sc_remove_option is the value set to SmartCard removal actions 684 | # To conform to STIG standards please only use the two options below. 685 | # 1 - This will lock the workstation when a SmartCard is removed 686 | # 2 - This will force logoff when a SmartCard is removed 687 | # Default: 1 688 | win10stig_sc_remove_option: 1 689 | 690 | # WN10-SO-000280 691 | # Windows 10 passwords for enabled local Administrator accounts must be changed at least every 60 days. 692 | # If the PasswordLastSet date is greater than wn10stig_pass_age_administrator days old, this is a finding. 693 | # NOTE: This can be set to 60 or less. 694 | # Default: 60 695 | wn10stig_pass_age_administrator: 60 696 | 697 | # WN10-UR-000010 698 | # win10stig_additional_network_logon_users_or_groups is the option to add additional groups. 699 | # If a domain application account such as for a management tool requires this user right, this would not be a finding. 700 | # Vendor documentation must support the requirement for having the user right. 701 | # The requirement must be documented with the ISSO. 702 | # The application account, managed at the domain level, must meet requirements for application account passwords, 703 | # such as length and frequency of changes as defined in the Windows Server STIGs. 704 | # Note: Adjusting this will always cause a warning message to be displayed about the above notes. 705 | # Example: 706 | # win10stig_additional_network_logon_users_or_groups 707 | # - "CustomUser1" 708 | # - "CustomGroup1" 709 | # Default: [] 710 | win10stig_additional_network_logon_users_or_groups: [] 711 | 712 | # WN10-CC-000391 713 | # win10stig_remove_internet_explorer_11 is the variable that will allow you to remove the Remove IE11 Windows Feature. 714 | # By default STIG does not say to remove it but it is optional, but strongly recommended. 715 | # Default: false 716 | win10stig_remove_internet_explorer_11: false 717 | 718 | # WN10-00-000395 719 | # Note: If both are set to false this control is a manual audit by a Administrator. 720 | # win10stig_reset_portproxy is the variable that is set and 721 | # this removes all portproxy rules in one command — a fast, full cleanup. 722 | # Use When: 723 | # You're working with hardened systems, gold images, or systems where portproxy should never be used. 724 | # You do not need to preserve any rules. 725 | # You want simplicity and speed over rule-by-rule visibility. 726 | # Default: true 727 | win10stig_reset_portproxy: true 728 | # Use When: 729 | # You need granular control and traceability. 730 | # You want to align strictly with the STIG fix text. 731 | # You want to audit exactly what was removed. 732 | # You might be running in production where automated bulk changes are risky. 733 | # Default: false 734 | win10stig_delete_each_portproxy: false 735 | 736 | # CAT3 737 | 738 | # WN10-CC-000206 739 | # win10stig_dodownloadmode: is the DODownloadMode variable for systems that are a member of a domain or standalone. 740 | # This can be any of the below values, the only available option that is not within STIG standards is Internet value of 3 741 | # NOTE: The settings will apply one or the other based on if it is a domain member which Ansible will determine in the Prelim. 742 | # **************************************************************************************************** 743 | # Domain Based System settings are below. 744 | # HTTP Only = 0, LAN(1) = 1, Group (2) = 2, Simple (99) = 99, Bypass (100) = 100 745 | # Documentation on values: https://admx.help/?Category=Windows_11_2022&Policy=Microsoft.Policies.DeliveryOptimization::DownloadMode 746 | # **************************************************************************************************** 747 | # Standalone System settings are below. 748 | # The can be the values below 749 | # Off (0) = 0 LAN (1) = 1 750 | # **************************************************************************************************** 751 | # Default: 0 752 | win10stig_dodownloadmode: 0 753 | 754 | # WN10-SO-000055 755 | # win10stig_max_pw_age is the maximum password age set in days. 756 | # To conform to STIG standards this needs to be set to 30 or less, excluding 0 757 | # Default: 30 758 | win10stig_max_pw_age: 30 759 | 760 | # WN10-SO-000080 761 | # win10stig_legal_notice_caption is the legal banner/notice caption displayed prior to a logon attempt 762 | # NOTE: If a site-defined title is used, it can in no case contravene or modify the language of the banner text required in WN10-SO-000075. 763 | # Examples: DoD Notice and Consent Banner, US Department of Defense Warning Statement 764 | # Default: US Department of Defense Warning Statement 765 | win10stig_legal_notice_caption: US Department of Defense Warning Statement 766 | 767 | # WN10-SO-000085 768 | # win10stig_cached_logons_count is the number of logons cached 769 | # To conform to STIG standards this needs to be set to 10 or less 770 | # NOTE: This setting only applies to domain-joined systems, however, it is configured by default on all systems. 771 | # Default: 10 772 | win10stig_cached_logons_count: 10 773 | 774 | # WN10-CC-000080 775 | # win10stig_hypervisor_enforce_code_integrity is the variable setting for the registry to select which 776 | # style of Turn On Virtualization Based Security you would like to choose. 777 | # The policy settings referenced in the Fix section will configure the following registry value. However due to hardware requirements, 778 | # the registry value alone does not ensure proper function. 779 | # "Enabled with UEFI lock" is preferred as more secure; however, it cannot be turned off remotely through a group policy change if there is an issue. 780 | # These are the only two options to use to be STIG compliant. 781 | # 1 - Enabled with UEFI lock 782 | # 2 - Enabled without lock 783 | # Default: 1 784 | win10stig_hypervisor_enforce_code_integrity: 1 785 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Change_Requires_Reboot 4 | ansible.builtin.set_fact: 5 | reboot_host: true 6 | tags: 7 | - always 8 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | galaxy_info: 4 | author: "MindPoint Group" 5 | description: "Ansible Role to Apply The Windows 10 Enterprise STIG Benchmark" 6 | company: "MindPoint Group" 7 | license: MIT 8 | role_name: windows10_stig 9 | namespace: mindpointgroup 10 | min_ansible_version: "2.16" 11 | platforms: 12 | - name: Windows 13 | versions: 14 | - "all" 15 | galaxy_tags: 16 | - auditpolicy 17 | - automation 18 | - azure 19 | - benchmark 20 | - stig 21 | - stigbenchmark 22 | - stigcompliance 23 | - cloudhardening 24 | - compliance 25 | - compliancehardening 26 | - complianceascode 27 | - configurationmanagement 28 | - encryption 29 | - eventlogging 30 | - hardening 31 | - infrastructureascode 32 | - logging 33 | - microsoft 34 | - monitoring 35 | - oshardening 36 | - patchmanagement 37 | - patching 38 | - policymanagement 39 | - privilegedaccess 40 | - remediation 41 | - security 42 | - system 43 | - systemintegrity 44 | - vulnerabilitymanagement 45 | - windows 46 | - win10 47 | - windowssecurity 48 | - windowsworkstation 49 | - workstation 50 | - windows10 51 | collections: 52 | - ansible.windows 53 | - community.windows 54 | - community.general 55 | dependencies: [] 56 | -------------------------------------------------------------------------------- /site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all # noqa: name[play] 4 | gather_facts: true 5 | vars: 6 | is_container: false 7 | roles: 8 | - role: "{{ playbook_dir }}" 9 | -------------------------------------------------------------------------------- /tasks/cat1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "HIGH | WN10-00-000030 | PATCH | Windows 10 information systems must use BitLocker to encrypt all disks to protect the confidentiality and integrity of all information at rest." 4 | when: 5 | - wn10_00_000030 6 | - not (discovered_vdi_non_persistent or discovered_avd_no_data_at_rest) 7 | tags: 8 | - WN10-00-000030 9 | - CAT1 10 | - CCI-001199 11 | - CCI-002475 12 | - CCI-002476 13 | - SRG-OS-000185-GPOS-00079 14 | - SV-220702r958552_rule 15 | - V-220702 16 | - NIST800-53_SC-28 17 | - NIST800-53A_SC-28.1 18 | - NIST800-53R4_SC-28 19 | - NIST800-53R4_SC-28_1 20 | block: 21 | - name: "HIGH | WN10-00-000030 | AUDIT | Windows 10 information systems must use BitLocker to encrypt all disks to protect the confidentiality and integrity of all information at rest. | Get Current Bitlocker Status" 22 | ansible.windows.win_shell: | 23 | $drives = Get-BitLockerVolume | Where-Object { $_.MountPoint -match "^[A-Z]:" } 24 | $unencrypted = $drives | Where-Object { $_.ProtectionStatus -ne "On" } 25 | $unencrypted | Select-Object -ExpandProperty MountPoint | ConvertTo-Json -Compress 26 | changed_when: false 27 | failed_when: false 28 | register: wn10_00_000030_bitlocker_status 29 | 30 | - name: "HIGH | WN10-00-000030 | AUDIT | Windows 10 information systems must use BitLocker to encrypt all disks to protect the confidentiality and integrity of all information at rest. | Warning if BitLocker is not enabled and enforcement is off" 31 | when: (wn10_00_000030_bitlocker_status.stdout | from_json) | length > 0 32 | ansible.builtin.debug: 33 | msg: 34 | - "Warning!! The following drives are not encrypted with BitLocker:" 35 | - "{{ wn10_00_000030_bitlocker_status.stdout | from_json }}" 36 | 37 | - name: "HIGH | WN10-00-000030 | AUDIT | Windows 10 information systems must use BitLocker to encrypt all disks to protect the confidentiality and integrity of all information at rest. | Warn Count" 38 | when: (wn10_00_000030_bitlocker_status.stdout | from_json) | length > 0 39 | ansible.builtin.import_tasks: warning_facts.yml 40 | vars: 41 | warn_control_id: 'WN10-00-000030' 42 | 43 | - name: "HIGH | WN10-00-000031 | PATCH | Windows 10 systems must use a BitLocker PIN for pre-boot authentication." 44 | when: wn10_00_000031 45 | tags: 46 | - WN10-00-000031 47 | - CAT1 48 | - CCI-001199 49 | - CCI-002475 50 | - CCI-002476 51 | - SRG-OS-000185-GPOS-00079 52 | - SV-220703r958552_rule 53 | - V-220703 54 | - NIST800-53_SC-28 55 | - NIST800-53A_SC-28.1 56 | - NIST800-53R4_SC-28 57 | - NIST800-53R4_SC-28_1 58 | block: 59 | - name: "HIGH | WN10-00-000031 | PATCH | Windows 10 systems must use a BitLocker PIN for pre-boot authentication. | Set UseTPMPIN value" 60 | when: not (discovered_vdi_non_persistent or discovered_avd_no_data_at_rest) 61 | ansible.windows.win_regedit: 62 | path: HKLM:\SOFTWARE\Policies\Microsoft\FVE 63 | name: UseAdvancedStartup 64 | data: 1 65 | type: dword 66 | 67 | - name: "HIGH | WN10-00-000031 | PATCH | Windows 10 systems must use a BitLocker PIN for pre-boot authentication. | Set Advanced Startup value" 68 | when: not win10stig_bitlocker_network_unlock 69 | ansible.windows.win_regedit: 70 | path: HKLM:\SOFTWARE\Policies\Microsoft\FVE 71 | name: UseTPMPIN 72 | data: 1 73 | type: dword 74 | 75 | - name: "HIGH | WN10-00-000031 | PATCH | Windows 10 systems must use a BitLocker PIN for pre-boot authentication. | Set Advanced Startup value" 76 | when: not win10stig_bitlocker_network_unlock 77 | ansible.windows.win_regedit: 78 | path: HKLM:\SOFTWARE\Policies\Microsoft\FVE 79 | name: UseTPMKeyPIN 80 | data: 1 81 | type: dword 82 | 83 | - name: "HIGH | WN10-00-000031 | PATCH | Windows 10 systems must use a BitLocker PIN for pre-boot authentication. | Set Advanced Startup value" 84 | when: win10stig_bitlocker_network_unlock 85 | ansible.windows.win_regedit: 86 | path: HKLM:\SOFTWARE\Policies\Microsoft\FVE 87 | name: UseTPMPIN 88 | data: 2 89 | type: dword 90 | 91 | - name: "HIGH | WN10-00-000031 | PATCH | Windows 10 systems must use a BitLocker PIN for pre-boot authentication. | Set Advanced Startup value" 92 | when: win10stig_bitlocker_network_unlock 93 | ansible.windows.win_regedit: 94 | path: HKLM:\SOFTWARE\Policies\Microsoft\FVE 95 | name: UseTPMKeyPIN 96 | data: 2 97 | type: dword 98 | 99 | - name: HIGH | WN10-00-000032 | PATCH | Windows 10 systems must use a BitLocker PIN with a minimum length of 6 digits for pre-boot authentication." 100 | when: 101 | - wn10_00_000032 102 | - not (discovered_vdi_non_persistent or discovered_avd_no_data_at_rest) 103 | tags: 104 | - WN10-00-000032 105 | - CAT2 106 | - CCI-001199 107 | - CCI-002475 108 | - CCI-002476 109 | - SRG-OS-000185-GPOS-00079 110 | - SV-220704r958552_rule 111 | - V-220704 112 | - NIST800-53_SC-28 113 | - NIST800-53A_SC-28.1 114 | - NIST800-53R4_SC-28 115 | - NIST800-53R4_SC-28_1 116 | block: 117 | - name: "HIGH | WN10-00-000032 | PATCH | Windows 10 systems must use a BitLocker PIN with a minimum length of 6 digits for pre-boot authentication. | Apply Pin Length" 118 | when: win10stig_bitlocker_min_pin_length >= 6 119 | ansible.windows.win_regedit: 120 | path: HKLM:\SOFTWARE\Policies\Microsoft\FVE 121 | name: MinimumPIN 122 | data: "{{ win10stig_bitlocker_min_pin_length }}" 123 | type: dword 124 | 125 | - name: "HIGH | WN10-00-000032 | AUDIT | Windows 10 systems must use a BitLocker PIN with a minimum length of 6 digits for pre-boot authentication. | Warning Message." 126 | when: win10stig_bitlocker_min_pin_length < 6 127 | ansible.builtin.debug: 128 | msg: 129 | - "Warning!! You have an invalid setting for win10stig_bitlocker_min_pin_length. Please read" 130 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 131 | 132 | - name: "HIGH | WN10-00-000032 | AUDIT | Windows 10 systems must use a BitLocker PIN with a minimum length of 6 digits for pre-boot authentication. | Warn Count." 133 | when: win10stig_bitlocker_min_pin_length < 6 134 | ansible.builtin.import_tasks: warning_facts.yml 135 | vars: 136 | warn_control_id: 'WN10-00-000032' 137 | 138 | - name: "HIGH | WN10-00-000040 | AUDIT | Windows 10 systems must be maintained at a supported servicing level." 139 | when: 140 | - wn10_00_000040 141 | - discovered_displayversion.value is version('20H2', '<') or discovered_currentbuild.value is version('19000', '<') 142 | tags: 143 | - WN10-00-000040 144 | - CAT1 145 | - CCI-000366 146 | - SRG-OS-000480-GPOS-00227 147 | - SV-220706r1050597_rule 148 | - V-220706 149 | - NIST800-53_CM-6_b 150 | - NIST800-53A_CM-6.1_iv 151 | - NIST800-53R4_CM-6_b 152 | block: 153 | - name: "HIGH | WN10-00-000040 | AUDIT | Windows 10 systems must be maintained at a supported servicing level | Warning Message." 154 | ansible.builtin.debug: 155 | msg: 156 | - "Warning!! Your version of Windows 10 does not conform to STIG standards." 157 | - "Update systems on the Semi-Annual Channel to Microsoft Windows Version 20H2 (OS Build 190xx.x) or greater." 158 | - "It is recommended systems be upgraded to the most recently released version." 159 | - "Special-purpose systems using the LTSC\\B may be at the following versions:" 160 | - "v1507 (Build 10240)" 161 | - "v1607 (Build 14393)" 162 | - "v1809 (Build 17763)" 163 | - "v21H2 (Build 19044)" 164 | 165 | - name: "HIGH | WN10-00-000040 | AUDIT | Windows 10 systems must be maintained at a supported servicing level | Warn Count." 166 | ansible.builtin.import_tasks: warning_facts.yml 167 | vars: 168 | warn_control_id: 'WN10-00-000040' 169 | 170 | # Using ansible.windows.win_service_info because there is a bug in win_service with permissions 171 | # Below is the link to the most recent thing I can find on the issue. There are a few others that are the same but a bit older 172 | # https://githubmemory.com/repo/ansible-collections/ansible.windows/issues/269 173 | - name: "HIGH | WN10-00-000045 | AUDIT | The Windows 10 system must use an anti-virus program." 174 | when: wn10_00_000045 175 | tags: 176 | - WIN10-00-000045 177 | - CAT1 178 | - CCI-000366 179 | - SRG-OS-000480-GPOS-00227 180 | - SV-220707r1016358_rule 181 | - V-220707 182 | - NIST800-53_CM-6_b 183 | - NIST800-53A_CM-6.1_iv 184 | - NIST800-53R4_CM-6_b 185 | block: 186 | - name: "HIGH | WN10-00-000045 | AUDIT | The Windows 10 system must use an anti-virus program. | Get AV service status" 187 | ansible.windows.win_service_info: 188 | name: "{{ win10stig_av_sftw }}" 189 | changed_when: false 190 | failed_when: false 191 | register: wn10_00_000045_av_sftw_status 192 | 193 | - name: "HIGH | WN10-00-000045 | AUDIT | The Windows 10 system must use an anti-virus program. | Alert on service not running." 194 | when: not wn10_00_000045_av_sftw_status.exists or wn10_00_000045_av_sftw_status.services[0].state != "started" 195 | ansible.builtin.debug: 196 | msg: 197 | - "Warning!! You do not have any AV software running." 198 | - "Please enable Microsoft Defender or a 3rd party antivirus solution." 199 | 200 | - name: "HIGH | WN10-00-000045 | AUDIT | The Windows 10 system must use an anti-virus program. | Warn Count." 201 | when: not wn10_00_000045_av_sftw_status.exists or wn10_00_000045_av_sftw_status.services[0].state != "started" 202 | ansible.builtin.import_tasks: warning_facts.yml 203 | vars: 204 | warn_control_id: 'WN10-00-000045' 205 | 206 | - name: "HIGH | WN10-00-000050 | PATCH | Local volumes must be formatted using NTFS" 207 | when: wn10_00_000050 208 | tags: 209 | - WN10-00-000050 210 | - CAT1 211 | - CCI-000213 212 | - SRG-OS-000080-GPOS-00048 213 | - SV-220708r958472_rule 214 | - V-220708 215 | - NIST800-53_AC-3 216 | - NIST800-53A_AC-3.1 217 | - NIST800-53R4_AC-3 218 | block: 219 | - name: "HIGH | WN10-00-000050 | PATCH | Local volumes must be formatted using NTFS | List All Non-NTFS Drives" 220 | ansible.windows.win_shell: | 221 | $volumes = Get-Volume | Where-Object { $_.DriveLetter -match "^[A-Z]$" } 222 | $partitions = Get-Partition | Where-Object { $_.GptType -notin @("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B") } 223 | 224 | $non_ntfs = $volumes | Where-Object { 225 | $_.FileSystem -ne "NTFS" -and 226 | $_.DriveLetter -in $partitions.DriveLetter 227 | } 228 | 229 | if ($non_ntfs) { 230 | $non_ntfs_list = $non_ntfs | Select-Object -ExpandProperty DriveLetter -Unique | ConvertTo-Json -Compress 231 | Write-Output $non_ntfs_list 232 | } else { 233 | Write-Output "[]" 234 | } 235 | changed_when: false 236 | failed_when: false 237 | register: wn10_00_000050_volume_info 238 | 239 | - name: "HIGH | WN10-00-000050 | PATCH | Local volumes must be formatted using NTFS | Show non-NTFS volumes" 240 | when: (wn10_00_000050_volume_info.stdout | from_json) | length > 0 241 | ansible.builtin.debug: 242 | msg: 243 | - "Warning!! The following volumes are not formatted NTFS." 244 | - "STIG requirements are to format all local volumes to use NTFS." 245 | - "This does not apply to system partitions such the Recovery and EFI System Partition." 246 | - "{{ wn10_00_000050_volume_info.stdout | from_json }}" 247 | 248 | - name: "HIGH | WN10-00-000050 | PATCH | Local volumes must be formatted using NTFS | Warn Count." 249 | when: (wn10_00_000050_volume_info.stdout | from_json) | length > 0 250 | ansible.builtin.import_tasks: warning_facts.yml 251 | vars: 252 | warn_control_id: 'WN10-00-000050' 253 | 254 | - name: "HIGH | WN10-00-000070 | AUDIT | Only accounts responsible for the administration of a system must have Administrator rights on the system." 255 | when: wn10_00_000070 256 | tags: 257 | - WN10-00-000070 258 | - CAT1 259 | - CCI-002235 260 | - SRG-OS-000324-GPOS-00125 261 | - SV-220712r958726_rule 262 | - V-220712 263 | - NIST800-53R4_AC-6_10 264 | block: 265 | - name: "HIGH | WN10-00-000070 | AUDIT | Only accounts responsible for the administration of a system must have Administrator rights on the system. | Show Accounts." 266 | ansible.builtin.debug: 267 | msg: 268 | - "The following users or groups have Administrator rights on this system." 269 | - "Please make sure that these users or groups meet the sites policies to be STIG compliant." 270 | - "{{ discovered_admin_users_groups.stdout_lines }}" 271 | 272 | - name: "HIGH | WN10-00-000070 | AUDIT | Only accounts responsible for the administration of a system must have Administrator rights on the system. | Check for presence of Domain Admins" 273 | ansible.builtin.set_fact: 274 | wn10_00_000070_domain_admins_found: "{{ 'Domain Admins' in discovered_admin_users_groups.stdout }}" 275 | 276 | - name: "HIGH | WN10-00-000070 | AUDIT | Only accounts responsible for the administration of a system must have Administrator rights on the system. | Warning" 277 | when: wn10_00_000070_domain_admins_found 278 | ansible.builtin.debug: 279 | msg: "Warning!! Domain Admins are currently listed as local administrators. Replace them with a delegated workstation admin group." 280 | 281 | - name: "HIGH | WN10-00-000070 | AUDIT | Only accounts responsible for the administration of a system must have Administrator rights on the system. | Warn Count." 282 | ansible.builtin.import_tasks: warning_facts.yml 283 | vars: 284 | warn_control_id: 'WN10-00-000070' 285 | 286 | - name: "HIGH | WN10-00-000100 | PATCH | Internet Information System (IIS) or its subcomponents must not be installed on a workstation." 287 | when: 288 | - wn10_00_000100 289 | - not win10stig_web_server 290 | tags: 291 | - WN10-00-000100 292 | - CAT1 293 | - CCI-000381 294 | - SRG-OS-000095-GPOS-00049 295 | - SV-220718r958478_rule 296 | - V-220718 297 | - NIST800-53_CM-7 298 | - NIST800-53A_CM-7.1_ii 299 | - NIST800-53R4_CM-7_a 300 | ansible.windows.win_optional_feature: 301 | name: "{{ item }}" 302 | state: absent 303 | with_items: 304 | - IIS-WebServer 305 | - IIS-HostableWebCore 306 | 307 | - name: "HIGH | WN10-00-000145 | PATCH | Data Execution Prevention (DEP) must be configured to at least OptOut." 308 | when: wn10_00_000145 309 | tags: 310 | - WN10-00-000145 311 | - CAT1 312 | - CCI-002824 313 | - SRG-OS-000433-GPOS-00193 314 | - SV-220726r958928_rule 315 | - V-220726 316 | - NIST800-53R4_SI-16 317 | block: 318 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Detect OS Drive." 319 | ansible.windows.win_shell: $env:SystemDrive -replace ':','' 320 | changed_when: false 321 | failed_when: false 322 | register: wn10_00_000145_os_drive 323 | 324 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Show Detected OS Drive" 325 | ansible.builtin.debug: 326 | msg: "The OS drive is {{ wn10_00_000145_os_drive.stdout | trim }}:" 327 | 328 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Check if BitLocker is enabled on OS Drive" 329 | ansible.windows.win_shell: (Get-BitLockerVolume -MountPoint "{{ wn10_00_000145_os_drive.stdout | trim }}:").ProtectionStatus 330 | changed_when: false 331 | failed_when: false 332 | register: wn10_00_000145_bitlocker_status 333 | 334 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Show BitLocker Status" 335 | ansible.builtin.debug: 336 | msg: "BitLocker Protection Status: {{ wn10_00_000145_bitlocker_status.stdout | trim }} (1 = Enabled, 0 = Disabled, 'No BitLocker Found' if missing)" 337 | 338 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Suspend BitLocker if enabled" 339 | when: wn10_00_000145_bitlocker_status.stdout | trim == "1" 340 | ansible.windows.win_shell: Suspend-BitLocker -MountPoint "{{ wn10_00_000145_os_drive.stdout | trim }}:" -RebootCount 1 341 | 342 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | No BitLocker Found Skipping Suspension" 343 | when: wn10_00_000145_bitlocker_status.stdout | trim == "No BitLocker Found" 344 | ansible.builtin.debug: 345 | msg: "BitLocker is not installed. Skipping suspension step." 346 | 347 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Status check for idempotency." 348 | ansible.windows.win_shell: BCDEdit /enum "{current}" 349 | changed_when: false 350 | failed_when: false 351 | register: wn10_00_000145_dep_setting_search 352 | 353 | - name: "HIGH | WN10-00-000145 | PATCH | Data Execution Prevention (DEP) must be configured to at least OptOut. | Make change to match {{ wn10stig_dep_value }}." 354 | when: wn10stig_dep_value not in wn10_00_000145_dep_setting_search.stdout | regex_search('nx\\s.*') | trim | regex_replace('nx','') | trim 355 | ansible.windows.win_shell: BCDEdit /set "{current}" nx {{ wn10stig_dep_value }} 356 | 357 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Retrieve Existing DEP Opt-Out Applications" 358 | when: wn10stig_dep_optout_apps | length > 0 359 | ansible.windows.win_shell: | 360 | $exceptions = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppCompatFlags\Layers" -ErrorAction SilentlyContinue 361 | if ($exceptions) { 362 | $apps = $exceptions.PSObject.Properties | Where-Object { $_.Value -match "DisableNX" } | Select-Object -ExpandProperty Name 363 | $apps | ConvertTo-Json -Compress 364 | } else { 365 | Write-Output "[]" 366 | } 367 | changed_when: false 368 | failed_when: false 369 | register: wn10_00_000145_existing_dep_exceptions 370 | 371 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Store Existing DEP Opt-Out Applications" 372 | when: 373 | - (wn10_00_000145_existing_dep_exceptions.stdout | default('[]') | from_json | length) == 0 374 | - wn10stig_dep_optout_apps | length > 0 375 | ansible.builtin.set_fact: 376 | wn10_00_000145_existing_dep_apps: "{{ wn10_00_000145_existing_dep_exceptions.stdout | from_json }}" 377 | 378 | - name: "HIGH | WN10-00-000145 | AUDIT | Data Execution Prevention (DEP) must be configured to at least OptOut. | Applications to Remove (Not in Approved List)" 379 | when: 380 | - (wn10_00_000145_existing_dep_exceptions.stdout | default('[]') | from_json | length) == 0 381 | - wn10stig_dep_optout_apps | length > 0 382 | ansible.builtin.set_fact: 383 | wn10_00_000145_dep_apps_to_remove: "{{ wn10_00_000145_existing_dep_apps | difference(wn10stig_dep_optout_apps) }}" 384 | 385 | - name: "HIGH | WN10-00-000145 | PATCH | Data Execution Prevention (DEP) must be configured to at least OptOut. | Delete Unapproved DEP Opt-Out Entries" 386 | when: 387 | - (wn10_00_000145_existing_dep_exceptions.stdout | default('[]') | from_json | length) == 0 388 | - wn10stig_dep_optout_apps | length > 0 389 | ansible.windows.win_regedit: 390 | path: "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\AppCompatFlags\\Layers" 391 | name: "{{ item }}" 392 | state: absent 393 | loop: "{{ wn10_00_000145_dep_apps_to_remove }}" 394 | 395 | - name: "HIGH | WN10-00-000145 | PATCH | Data Execution Prevention (DEP) must be configured to at least OptOut. | Insert Approved DEP Opt-Out Applications into Registry" 396 | when: wn10stig_dep_optout_apps | length > 0 397 | ansible.windows.win_regedit: 398 | path: "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\AppCompatFlags\\Layers" 399 | name: "{{ item }}" 400 | data: "DisableNX" 401 | type: string 402 | loop: "{{ wn10stig_dep_optout_apps }}" 403 | 404 | - name: "HIGH | WN10-00-000150 | PATCH | Structured Exception Handling Overwrite Protection (SEHOP) must be enabled." 405 | when: wn10_00_000150 406 | tags: 407 | - WN10-00-000150 408 | - CAT1 409 | - CCI-002824 410 | - SRG-OS-000433-GPOS-00192 411 | - SV-220727r958928_rule 412 | - V-220727 413 | - NIST800-53R4_SI-16 414 | ansible.windows.win_regedit: 415 | path: HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel 416 | name: DisableExceptionChainValidation 417 | data: 0 418 | type: dword 419 | 420 | - name: "HIGH | WN10-00-000240 | AUDIT | Administrative accounts must not be used with applications that access the Internet, such as web browsers, or with potential Internet sources, such as email." 421 | when: wn10_00_000240 422 | tags: 423 | - WN10-00-000240 424 | - CAT1 425 | - CCI-000366 426 | - SRG-OS-000480-GPOS-00227 427 | - SV-220737r991589_rule 428 | - V-220737 429 | - NIST800-53_CM-6_b 430 | - NIST800-53A_CM-6.1_iv 431 | - NIST800-53R4_CM-6_b 432 | block: 433 | - name: "HIGH | WN10-00-000240 | AUDIT | Administrative accounts must not be used with applications that access the Internet, such as web browsers, or with potential Internet sources, such as email | Check if AppLocker rules are defined for Executables" 434 | ansible.windows.win_shell: | 435 | $policy = Get-AppLockerPolicy -Effective -ErrorAction SilentlyContinue 436 | if ($policy.RuleCollections.Exe) { 437 | $policy.RuleCollections.Exe | ConvertTo-Json -Depth 10 438 | } 439 | changed_when: false 440 | failed_when: false 441 | register: wn10_00_000240_applocker_rules_raw 442 | 443 | - name: "HIGH | WN10-00-000240 | AUDIT | Administrative accounts must not be used with applications that access the Internet, such as web browsers, or with potential Internet sources, such as email | Determine if any Deny rules for Admin group match app list" 444 | ansible.windows.win_shell: | 445 | $apps = @({% for app in wn10stig_internet_based_apps_to_check %}"{{ app }}",{% endfor %}) 446 | $policy = Get-AppLockerPolicy -Effective 447 | $denyRules = $policy.RuleCollections.Exe | 448 | Where-Object { $_.Action -eq "Deny" -and $_.UserOrGroupSid -eq "S-1-5-32-544" } 449 | 450 | $denyHits = @() 451 | foreach ($rule in $denyRules) { 452 | foreach ($app in $apps) { 453 | if ($rule.Conditions.FilePathCondition.Path -like "*$app") { 454 | $denyHits += $app 455 | } 456 | } 457 | } 458 | 459 | $denyHits | Sort-Object | Get-Unique 460 | changed_when: false 461 | failed_when: false 462 | register: wn10_00_000240_applocker_admin_denies 463 | 464 | - name: "HIGH | WN10-00-000240 | AUDIT | Administrative accounts must not be used with applications that access the Internet, such as web browsers, or with potential Internet sources, such as email | Display results and compliance status" 465 | ansible.builtin.debug: 466 | msg: >- 467 | [ 468 | "═══════════════════════════════════════════════════════════════════════════════", 469 | " Admin Access to Internet-Based Apps (AppLocker Audit) ", 470 | "═══════════════════════════════════════════════════════════════════════════════", 471 | "Apps Denied for Admins:", 472 | {% if wn10_00_000240_applocker_admin_denies.stdout_lines | length > 0 %} 473 | {% for app in wn10_00_000240_applocker_admin_denies.stdout_lines %} 474 | " Rule In Place For: {{ app }}", 475 | {% endfor %} 476 | "───────────────────────────────────────────────────────────────────────────────", 477 | "COMPLIANCE STATUS: COMPLIANT — AppLocker blocks apps for Admins" 478 | {% else %} 479 | "No AppLocker Deny rules found for any listed apps.", 480 | "───────────────────────────────────────────────────────────────────────────────", 481 | "COMPLIANCE STATUS: Warning!!", 482 | "The system is NOT COMPLIANT — Admins can access internet-based apps." 483 | {% endif %}, 484 | "═══════════════════════════════════════════════════════════════════════════════" 485 | ] 486 | 487 | - name: "HIGH | WN10-00-000240 | AUDIT | Administrative accounts must not be used with applications that access the Internet, such as web browsers, or with potential Internet sources, such as email | Warn Count." 488 | ansible.builtin.import_tasks: warning_facts.yml 489 | vars: 490 | warn_control_id: 'WN10-00-000240' 491 | 492 | # Use of this flag is not recommended per Microsoft's documentation. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gpsb/0b40db09-d95d-40a6-8467-32aedec8140c 493 | - name: "HIGH | WN10-AC-000045 | PATCH | Reversible password encryption must be disabled." 494 | when: wn10_ac_000045 495 | tags: 496 | - WN10-AC-000045 497 | - CAT1 498 | - CCI-000196 499 | - SRG-OS-000073-GPOS-00041 500 | - SV-220747r1016409_rule 501 | - V-220747 502 | - NIST800-53_IA-5_1_c 503 | - NIST800-53A_IA-5_1.1_v 504 | - NIST800-53R4_IA-5_1_c 505 | community.windows.win_security_policy: 506 | section: System Access 507 | key: ClearTextPassword 508 | value: "0" 509 | 510 | - name: "HIGH | WN10-CC-000075 | PATCH | Credential Guard must be running on Windows 10 domain-joined systems." 511 | when: 512 | - wn10_cc_000075 513 | - discovered_domain_joined 514 | - not discovered_vdi_non_persistent 515 | tags: 516 | - WN10-CC-000075 517 | - CAT1 518 | - CCI-000366 519 | - SRG-OS-000480-GPOS-00227 520 | - SV-220812r991589_rule 521 | - V-220812 522 | - NIST800-53_CM-6_b 523 | - NIST800-53A_CM-6.1_iv 524 | - NIST800-53R4_CM-6_b 525 | block: 526 | - name: "HIGH | WN10-CC-000075 | PATCH | Credential Guard must be running on Windows 10 domain-joined systems. | Patch Registry." 527 | ansible.windows.win_regedit: 528 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard 529 | name: LsaCfgFlags 530 | data: 1 531 | type: dword 532 | 533 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Check if Credential Guard is running via DeviceGuard" 534 | ansible.windows.win_shell: Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard | Select-Object -ExpandProperty SecurityServicesRunning 535 | register: wn10_cc_000075_credential_guard_status 536 | changed_when: false 537 | ignore_errors: true 538 | 539 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Check if Credential Guard is listed in System Information" 540 | ansible.windows.win_shell: systeminfo | findstr /C:"Credential Guard" 541 | register: wn10_cc_000075_systeminfo_status 542 | changed_when: false 543 | ignore_errors: true 544 | 545 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Check if Secure Boot is enabled" 546 | ansible.windows.win_shell: Confirm-SecureBootUEFI 547 | register: wn10_cc_000075_secure_boot_status 548 | changed_when: false 549 | ignore_errors: true 550 | 551 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Check if TPM is enabled" 552 | ansible.windows.win_shell: "(Get-WmiObject -Namespace 'Root\\CIMv2\\Security\\MicrosoftTpm' -Class Win32_Tpm).Enabled" 553 | register: wn10_cc_000075_tpm_status 554 | changed_when: false 555 | ignore_errors: true 556 | 557 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Check if Hyper-V is enabled" 558 | ansible.windows.win_shell: systeminfo | findstr /C:"Hyper-V Requirements" 559 | register: wn10_cc_000075_hyper_v_status 560 | changed_when: false 561 | ignore_errors: true 562 | 563 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Credential Guard and System Security Check Summary." 564 | ansible.builtin.debug: 565 | msg: 566 | - "==== Credential Guard Audit Summary ====" 567 | - "Credential Guard (DeviceGuard Check): {{ 'Running' if '1' in wn10_cc_000075_credential_guard_status.stdout else 'NOT Running (Finding)' }}" 568 | - "Credential Guard (System Information Check): {{ wn10_cc_000075_systeminfo_status.stdout_lines if wn10_cc_000075_systeminfo_status.stdout_lines else 'Credential Guard NOT found (Finding)' }}" 569 | - "Secure Boot: {{ 'Enabled' if wn10_cc_000075_secure_boot_status.stdout == 'True' else 'NOT Enabled (Finding)' }}" 570 | - "TPM: {{ 'Enabled' if wn10_cc_000075_tpm_status.stdout == 'True' else 'NOT Enabled (Finding)' }}" 571 | - "Hyper-V: {{ wn10_cc_000075_hyper_v_status.stdout_lines if wn10_cc_000075_hyper_v_status.stdout_lines else 'Hyper-V NOT supported or enabled (Finding)' }}" 572 | - "=====================================" 573 | - "If any of the above checks indicate (Finding), remediation is required." 574 | 575 | - name: "HIGH | WN10-CC-000075 | AUDIT | Credential Guard must be running on Windows 10 domain-joined systems. | Warn Count." 576 | ansible.builtin.import_tasks: warning_facts.yml 577 | vars: 578 | warn_control_id: 'WN10-CC-000075' 579 | 580 | - name: "HIGH | WN10-CC-000155 | PATCH | Solicited Remote Assistance must not be allowed." 581 | when: wn10_cc_000155 582 | tags: 583 | - WN10-CC-000155 584 | - CAT1 585 | - CCI-001090 586 | - SRG-OS-000138-GPOS-00069 587 | - SV-220823r569187_rule 588 | - V-220823 589 | - NIST800-53_SC-4 590 | - NIST800-53A_SC-4.1 591 | - NIST800-53R4_SC-4 592 | ansible.windows.win_regedit: 593 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services 594 | name: fAllowToGetHelp 595 | data: 0 596 | type: dword 597 | 598 | - name: "HIGH | WN10-CC-000180 | PATCH | Autoplay must be turned off for non-volume devices" 599 | when: wn10_cc_000180 600 | tags: 601 | - WN10-CC-000180 602 | - CAT1 603 | - CCI-001764 604 | - SRG-OS-000368-GPOS-00154 605 | - SV-220827r958804_rule 606 | - V-220827 607 | - NIST800-53R4_CM-7_2 608 | ansible.windows.win_regedit: 609 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer 610 | name: NoAutoplayfornonVolume 611 | data: 1 612 | type: dword 613 | 614 | - name: "HIGH | WN10-CC-000185 | PATCH | The default autorun behavior must be configured to prevent autorun commands." 615 | when: wn10_cc_000185 616 | tags: 617 | - WN10-CC-000185 618 | - CAT1 619 | - CCI-001764 620 | - SRG-OS-000368-GPOS-00154 621 | - SV-220828r958804_rule 622 | - V-220828 623 | - NIST800-53R4_CM-7_2 624 | ansible.windows.win_regedit: 625 | path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer 626 | name: NoAutorun 627 | data: 1 628 | type: dword 629 | 630 | - name: "HIGH | WN10-CC-000190 | PATCH | Autoplay must be disabled for all drives." 631 | when: wn10_cc_000190 632 | tags: 633 | - WN10-CC-000190 634 | - CAT1 635 | - CCI-001764 636 | - SRG-OS-000368-GPOS-00154 637 | - SV-220829r958804_rule 638 | - V-220829 639 | - NIST800-53R4_CM-7_2 640 | ansible.windows.win_regedit: 641 | path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer 642 | name: NoDriveTypeAutoRun 643 | data: 255 644 | type: dword 645 | 646 | - name: "HIGH | WN10-CC-000315 | PATCH | The Windows Installer Always install with elevated privileges must be disabled." 647 | when: wn10_cc_000315 648 | tags: 649 | - WN10-CC-000315 650 | - CAT1 651 | - CCI-001812 652 | - SRG-OS-000362-GPOS-00149 653 | - SV-220857r1016417_rule 654 | - V-220857 655 | - NIST800-53R4_CM-11_2 656 | ansible.windows.win_regedit: 657 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer 658 | name: AlwaysInstallElevated 659 | data: 0 660 | type: dword 661 | 662 | - name: "HIGH | WN10-CC-000330 | PATCH | The Windows Remote Management (WinRM) client must not use Basic authentication." 663 | when: 664 | - wn10_cc_000330 665 | - not win_skip_for_test 666 | tags: 667 | - WN10-CC-000330 668 | - CAT1 669 | - CCI-000877 670 | - SRG-OS-000125-GPOS-00065 671 | - SV-220862r958510_rule 672 | - V-220862 673 | - NIST800-53_MA-4_c 674 | - NIST800-53A_MA-4.1_iv 675 | - NIST800-53R4_MA-4_c 676 | ansible.windows.win_regedit: 677 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Client 678 | name: AllowBasic 679 | data: 0 680 | type: dword 681 | 682 | - name: "HIGH | WN10-CC-000345 | PATCH | The Windows Remote Management (WinRM) service must not use Basic authentication." 683 | when: 684 | - wn10_cc_000345 685 | - not win_skip_for_test 686 | tags: 687 | - WN10-CC-000345 688 | - CAT1 689 | - CCI-000877 690 | - SRG-OS-000125-GPOS-00065 691 | - SV-220865r958510_rule 692 | - V-220865 693 | - NIST800-53_MA-4_c 694 | - NIST800-53A_MA-4.1_iv 695 | - NIST800-53R4_MA-4_c 696 | ansible.windows.win_regedit: 697 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service 698 | name: AllowBasic 699 | data: 0 700 | type: dword 701 | 702 | - name: "HIGH | WN10-SO-000140 | PATCH | Anonymous SID/Name translation must not be allowed." 703 | when: wn10_so_000140 704 | tags: 705 | - WN10-SO-000140 706 | - CAT1 707 | - CCI-000366 708 | - SRG-OS-000480-GPOS-00227 709 | - SV-220928r991589_rule 710 | - V-220928 711 | - NIST800-53_CM-6_b 712 | - NIST800-53A_CM-6.1_iv 713 | - NIST800-53R4_CM-6_b 714 | community.windows.win_security_policy: 715 | section: System Access 716 | key: LSAAnonymousNameLookup 717 | value: 0 718 | 719 | - name: "HIGH | WN10-SO-000145 | PATCH | Anonymous enumeration of SAM accounts must not be allowed." 720 | when: wn10_so_000145 721 | tags: 722 | - WN10-SO-000145 723 | - CAT1 724 | - CCI-000366 725 | - SRG-OS-000480-GPOS-00227 726 | - SV-220929r991589_rule 727 | - V-220929 728 | - NIST800-53_CM-6_b 729 | - NIST800-53A_CM-6.1_iv 730 | - NIST800-53R4_CM-6_b 731 | ansible.windows.win_regedit: 732 | path: HKLM:\SYSTEM\CurrentControlSet\Control\Lsa 733 | name: RestrictAnonymousSAM 734 | data: 1 735 | type: dword 736 | 737 | - name: "HIGH | WN10-SO-000150 | PATCH | Anonymous enumeration of shares must be restricted." 738 | when: wn10_so_000150 739 | tags: 740 | - WN10-SO-000150 741 | - CAT1 742 | - CCI-001090 743 | - SRG-OS-000138-GPOS-00069 744 | - SV-220930r958524_rule 745 | - V-220930 746 | - NIST800-53_SC-4 747 | - NIST800-53A_SC-4.1 748 | - NIST800-53R4_SC-4 749 | ansible.windows.win_regedit: 750 | path: HKLM:\SYSTEM\CurrentControlSet\Control\Lsa 751 | name: RestrictAnonymous 752 | data: 1 753 | type: dword 754 | 755 | - name: "HIGH | WN10-SO-000165 | PATCH | Anonymous access to Named Pipes and Shares must be restricted." 756 | when: wn10_so_000165 757 | tags: 758 | - WN10-SO-000165 759 | - CAT1 760 | - CCI-001090 761 | - SRG-OS-000138-GPOS-00069 762 | - SV-220932r958524_rule 763 | - V-220932 764 | - NIST800-53_SC-4 765 | - NIST800-53A_SC-4.1 766 | - NIST800-53R4_SC-4 767 | ansible.windows.win_regedit: 768 | path: HKLM:\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters 769 | name: RestrictNullSessAccess 770 | data: 1 771 | type: dword 772 | 773 | - name: "HIGH | WN10-SO-000195 | PATCH | The system must be configured to prevent the storage of the LAN Manager hash of passwords." 774 | when: wn10_so_000195 775 | tags: 776 | - WN10-SO-000195 777 | - CAT1 778 | - CCI-000196 779 | - SRG-OS-000073-GPOS-00041 780 | - SV-220937r1016419_rule 781 | - V-220937 782 | - NIST800-53_IA-5_1_c 783 | - NIST800-53A_IA-5_1.1_v 784 | - NIST800-53R4_IA-5_1_c 785 | ansible.windows.win_regedit: 786 | path: HKLM:\SYSTEM\CurrentControlSet\Control\Lsa 787 | name: NoLMHash 788 | data: 1 789 | type: dword 790 | 791 | - name: "HIGH | WN10-SO-000205 | PATCH | The LanMan authentication level must be set to send NTLMv2 response only, and to refuse LM and NTLM." 792 | when: wn10_so_000205 793 | tags: 794 | - WN10-SO-000205 795 | - CAT1 796 | - CCI-000366 797 | - SRG-OS-000480-GPOS-00227 798 | - SV-220938r991589_rule 799 | - V-220938 800 | - NIST800-53_CM-6_b 801 | - NIST800-53A_CM-6.1_iv 802 | - NIST800-53R4_CM-6_b 803 | ansible.windows.win_regedit: 804 | path: HKLM:\SYSTEM\CurrentControlSet\Control\Lsa 805 | name: LmCompatibilityLevel 806 | data: 5 807 | type: dword 808 | 809 | - name: "HIGH | WN10-UR-000015 | PATCH | The Act as part of the operating system user right must not be assigned to any groups or accounts." 810 | when: wn10_ur_000015 811 | tags: 812 | - WN10-UR-000015 813 | - CAT1 814 | - CCI-002235 815 | - SRG-OS-000324-GPOS-00125 816 | - SV-220958r958726_rule 817 | - V-220958 818 | - NIST800-53R4_AC-6_10 819 | ansible.windows.win_user_right: 820 | name: SeTcbPrivilege 821 | users: [] 822 | action: set 823 | 824 | - name: "HIGH | WN10-UR-000045 | PATCH | The Create a token object user right must not be assigned to any groups or accounts." 825 | when: wn10_ur_000045 826 | tags: 827 | - WN10-UR-000045 828 | - CAT1 829 | - CCI-002235 830 | - SRG-OS-000324-GPOS-00125 831 | - SV-220963r958726_rule 832 | - V-220963 833 | - NIST800-53R4_AC-6_10 834 | ansible.windows.win_user_right: 835 | name: SeCreateTokenPrivilege 836 | users: [] 837 | action: set 838 | 839 | - name: "HIGH | WN10-UR-000065 | PATCH | The Debug programs user right must only be assigned to the Administrators group." 840 | when: wn10_ur_000065 841 | tags: 842 | - WN10-UR-000065 843 | - CAT1 844 | - CCI-002235 845 | - SRG-OS-000324-GPOS-00125 846 | - SV-220967r958726_rule 847 | - V-220967 848 | - NIST800-53R4_AC-6_10 849 | ansible.windows.win_user_right: 850 | name: SeDebugPrivilege 851 | users: Administrators 852 | action: set 853 | -------------------------------------------------------------------------------- /tasks/cat2_cloud_lockout_order.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # THE FOLLOWING 3 CONTROLS WILL FAIL UNLESS THEY ARE IN THE FOLLOWING ORDER FOR CLOUD BASED SYSTEMS 4 | # CONTROL WN10-AC-000010, CONTROL WN10-AC-000005, CONTROL WN10-AC-000015 5 | # Needs to go before WN10-AC-000005 since the Lockout Duration could be disabled if the Lockout Policy is set to 0 causing the task to fail. 6 | - name: "MEDIUM | WN10-AC-000010 | PATCH | The number of allowed bad logon attempts must be configured to 3 or less." 7 | when: wn10_ac_000010 8 | tags: 9 | - WN10-AC-000010 10 | - CAT2 11 | - CCI-000044 12 | - SRG-OS-000021-GPOS-00005 13 | - SV-220740r958388_rule 14 | - V-220740 15 | - NIST800-53_AC-7_a 16 | - NIST800-53A_AC-7.1_ii 17 | - NIST800-53R4_AC-7_a 18 | block: 19 | - name: "MEDIUM | WN10-AC-000010 | PATCH | The number of allowed bad logon attempts must be configured to 3 or less. | Set Variable" 20 | when: 21 | - win10stig_bad_login_lockout_count <= 3 22 | - win10stig_bad_login_lockout_count > 0 23 | community.windows.win_security_policy: 24 | section: System Access 25 | key: LockoutBadCount 26 | value: "{{ win10stig_bad_login_lockout_count }}" 27 | 28 | - name: "MEDIUM | WN10-AC-000010 | AUDIT | The number of allowed bad logon attempts must be configured to 3 or less. | Verify Variable Not 0 or more then 3 warning." 29 | when: win10stig_bad_login_lockout_count > 3 or win10stig_bad_login_lockout_count == 0 30 | ansible.builtin.debug: 31 | msg: 32 | - "Warning!! You have an invalid number of attempts set for win10stig_bad_login_lockout_count. Please read" 33 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 34 | 35 | - name: "MEDIUM | WN10-AC-000010 | AUDIT | The number of allowed bad logon attempts must be configured to 3 or less. | Set warning count." 36 | when: win10stig_bad_login_lockout_count > 3 or win10stig_bad_login_lockout_count == 0 37 | ansible.builtin.import_tasks: 38 | file: warning_facts.yml 39 | vars: 40 | warn_control_id: 'WN10-AC-000010' 41 | 42 | - name: "MEDIUM | WN10-AC-000005 | PATCH | Windows 10 account lockout duration must be configured to 15 minutes or greater." 43 | when: wn10_ac_000005 44 | tags: 45 | - WN10-AC-000005 46 | - CAT2 47 | - CCI-002238 48 | - SRG-OS-000329-GPOS-00128 49 | - SV-220739r958736_rule 50 | - V-220739 51 | - NIST800-53_AC-7_b 52 | block: 53 | - name: "MEDIUM | WN10-AC-000005 | PATCH | Windows 10 account lockout duration must be configured to 15 minutes or greater." 54 | when: win10stig_account_lockout_duration >= 15 or win10stig_account_lockout_duration == 0 55 | community.windows.win_security_policy: 56 | section: System Access 57 | key: LockoutDuration 58 | value: "{{ win10stig_account_lockout_duration }}" 59 | 60 | - name: "MEDIUM | WN10-AC-000005 | AUDIT | Windows 10 account lockout duration must be configured to 15 minutes or greater. | Verify variable set to 15 or more minutes warning." 61 | when: win10stig_account_lockout_duration < 15 and win10stig_account_lockout_duration != 0 62 | ansible.builtin.debug: 63 | msg: 64 | - "Warning!! You have an invalid number of minutes set for win10stig_account_lockout_duration please read" 65 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 66 | 67 | - name: "MEDIUM | WN10-AC-000005 | AUDIT | Windows 10 account lockout duration must be configured to 15 minutes or greater. | Set warning count." 68 | when: win10stig_account_lockout_duration < 15 and win10stig_account_lockout_duration != 0 69 | ansible.builtin.import_tasks: 70 | file: warning_facts.yml 71 | vars: 72 | warn_control_id: 'WN10-AC-000005' 73 | 74 | - name: "MEDIUM | WN10-AC-000015 | PATCH | The period of time before the bad logon counter is reset must be configured to 15 minutes." 75 | when: wn10_ac_000015 76 | tags: 77 | - WN10-AC-000015 78 | - CAT2 79 | - CCI-000044 80 | - CCI-002238 81 | - SRG-OS-000021-GPOS-00005 82 | - SV-220741r958388_rule 83 | - V-220741 84 | - NIST800-53_AC-7_a 85 | - NIST800-53A_AC-7.1_ii 86 | - NIST800-53R4_AC-7_a 87 | - NIST800-53R4_AC-7_b 88 | # The Lockout Duration must be greater or equal to the Reset Account Lockout counter. 89 | block: 90 | - name: "MEDIUM | WN10-AC-000015 | PATCH | The period of time before the bad logon counter is reset must be configured to 15 minutes." 91 | when: 92 | - win10stig_account_lockout_counter_reset >= 15 93 | - win10stig_account_lockout_counter_reset <= win10stig_account_lockout_duration 94 | community.windows.win_security_policy: 95 | section: System Access 96 | key: ResetLockoutCount 97 | value: "{{ win10stig_account_lockout_counter_reset }}" 98 | 99 | - name: "MEDIUM | WN10-AC-000015 | AUDIT | The period of time before the bad logon counter is reset must be configured to 15 minutes. | Verify variable set to 15 or more minutes warning." 100 | when: win10stig_account_lockout_counter_reset > win10stig_account_lockout_duration or win10stig_account_lockout_counter_reset < 15 101 | ansible.builtin.debug: 102 | msg: 103 | - "Warning!! You have an invalid number of minutes set for win10stig_account_lockout_counter_reset. Please read" 104 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 105 | 106 | - name: "MEDIUM | WN10-AC-000015 | AUDIT | The period of time before the bad logon counter is reset must be configured to 15 minutes. | Set warning count." 107 | when: win10stig_account_lockout_counter_reset > win10stig_account_lockout_duration or win10stig_account_lockout_counter_reset < 15 108 | ansible.builtin.import_tasks: 109 | file: warning_facts.yml 110 | vars: 111 | warn_control_id: 'WN10-AC-000015' 112 | -------------------------------------------------------------------------------- /tasks/cat3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "LOW | WN10-00-000020 | AUDIT | Secure Boot must be enabled on Windows 10 systems." 4 | when: 5 | - wn10_00_000020 6 | - not discovered_vdi_non_persistent 7 | tags: 8 | - WN10-00-000020 9 | - CAT3 10 | - CCI-000366 11 | - SRG-OS-000480-GPOS-00227 12 | - SV-220700r991589_rule 13 | - V-220700 14 | - NIST800-53_CM-6_b 15 | - NIST800-53A_CM-6.1_iv 16 | - NIST800-53R4_CM-6_b 17 | block: 18 | - name: "LOW | WN10-00-000020 | AUDIT | Secure Boot must be enabled on Windows 10 systems. | Check secure boot." 19 | ansible.windows.win_shell: Confirm-SecureBootUEFI 20 | changed_when: false 21 | failed_when: false 22 | register: wn10_00_000020_secure_boot_audit 23 | 24 | - name: "LOW | WN10-00-000020 | AUDIT | Secure Boot must be enabled on Windows 10 systems. | Virtual System Check." 25 | when: "'undefined' in wn10_00_000020_secure_boot_audit.stderr | string" 26 | ansible.builtin.debug: 27 | msg: 28 | - "Warning!! Your running a virtual system that does not support Secure Boot." 29 | - "Please take note for audit purposes and verify it is compliant with sites policies to be STIG compliant." 30 | 31 | - name: "LOW | WN10-00-000020 | AUDIT | Secure Boot must be enabled on Windows 10 systems. | Hardware Not supported Check." 32 | when: "'CMdlet' in wn10_00_000020_secure_boot_audit.stderr | string" 33 | ansible.builtin.debug: 34 | msg: 35 | - "Warning!! Your computers hardware does not support Secure Boot." 36 | - "Please take note for audit purposes and verify it is compliant with sites policies to be STIG compliant." 37 | 38 | - name: "LOW | WN10-00-000020 | AUDIT | Secure Boot must be enabled on Windows 10 systems. | Secure Boot Set To Disabled." 39 | when: "'False' in wn10_00_000020_secure_boot_audit.stdout | string" 40 | ansible.builtin.debug: 41 | msg: 42 | - "Warning!! Secure Boot is set to DISABLED." 43 | - "Please take note for audit purposes and verify it is compliant with sites policies to be STIG compliant." 44 | 45 | - name: "LOW | WN10-00-000020 | AUDIT | Secure Boot must be enabled on Windows 10 systems. | Warn Count." 46 | when: "('undefined' in wn10_00_000020_secure_boot_audit.stderr | string) or ('CMdlet' in wn10_00_000020_secure_boot_audit.stderr | string) or ('False' in wn10_00_000020_secure_boot_audit.stdout | string)" 47 | ansible.builtin.import_tasks: warning_facts.yml 48 | vars: 49 | warn_control_id: 'WN10-00-000020' 50 | 51 | - name: "LOW | WN10-00-000065 | AUDIT | Unused accounts must be disabled or removed from the system after 35 days of inactivity." 52 | when: wn10_00_000065 53 | tags: 54 | - WN10-00-000065 55 | - CAT3 56 | - CCI-000795 57 | - SRG-OS-000118-GPOS-00060 58 | - SV-220711r1016403_rule 59 | - V-220711 60 | - NIST800-53_IA-4_e 61 | - NIST800-53A_IA-4.1_iii 62 | - NIST800-53R4_IA-4_e 63 | block: 64 | - name: "LOW | WN10-00-000065 | AUDIT | Unused accounts must be disabled or removed from the system after 35 days of inactivity. | Powershell To Get Accounts." 65 | ansible.windows.win_shell: Get-LocalUser | Where-Object {$_.Lastlogon -le (Get-Date).AddDays(-35)} | Select-Object Name, Enabled, Lastlogon | Format-Table -AutoSize 66 | changed_when: false 67 | failed_when: false 68 | register: wn10_00_000065_user_local_accounts 69 | 70 | - name: "LOW | WN10-00-000065 | AUDIT | Unused accounts must be disabled or removed from the system after 35 days of inactivity. | Print Results." 71 | ansible.builtin.debug: 72 | msg: 73 | - "Warning!! Review the list below and make sure it meets site policies." 74 | - "The list below includes all accounts that have not been logged into for the last 35 days, those unused accounts" 75 | - "must be disabled or removed from the system after 35 days of inactivity per STIG." 76 | - "Inactive accounts that have been reviewed and deemed to be required must be documented with the ISSO.." 77 | - "{{ wn10_00_000065_user_local_accounts.stdout_lines }}" 78 | 79 | - name: "LOW | WN10-00-000065 | AUDIT | Unused accounts must be disabled or removed from the system after 35 days of inactivity. | Warn Count." 80 | ansible.builtin.import_tasks: warning_facts.yml 81 | vars: 82 | warn_control_id: 'WN10-00-000065' 83 | 84 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain." 85 | when: 86 | - wn10_00_000085 87 | - discovered_domain_joined 88 | tags: 89 | - WN10-00-000085 90 | - CAT3 91 | - CCI-000366 92 | - SRG-OS-000480-GPOS-00227 93 | - SV-220715r991589_rule 94 | - V-220715 95 | - NIST800-53_CM-6_b 96 | - NIST800-53A_CM-6.1_iv 97 | - NIST800-53R4_CM-6_b 98 | block: 99 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Verify allowed built-in accounts are disabled" 100 | ansible.windows.win_shell: | 101 | $allowedBuiltIn = @("Administrator", "Guest", "DefaultAccount", "defaultuser0", "WDAGUtilityAccount") 102 | $results = @() 103 | foreach ($acct in $allowedBuiltIn) { 104 | $user = Get-LocalUser -Name $acct -ErrorAction SilentlyContinue 105 | if ($user) { 106 | if (-not $user.Disabled) { 107 | $results += [pscustomobject]@{ 108 | Name = $acct 109 | Issue = "Built-in account is enabled" 110 | Enabled = $true 111 | } 112 | } 113 | else { 114 | $results += [pscustomobject]@{ 115 | Name = $acct 116 | Issue = "Built-in account is disabled" 117 | Enabled = $false 118 | } 119 | } 120 | } 121 | else { 122 | $results += [pscustomobject]@{ 123 | Name = $acct 124 | Issue = "Account not found" 125 | Enabled = $null 126 | } 127 | } 128 | } 129 | $results | ConvertTo-Json 130 | register: wn10_00_000085_built_in_check 131 | 132 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Set fact for built-in accounts check results." 133 | ansible.builtin.set_fact: 134 | wn10_00_000085_built_in_accounts: "{{ wn10_00_000085_built_in_check.stdout | from_json }}" 135 | 136 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Find non-allowed local accounts." 137 | ansible.windows.win_shell: | 138 | $allowedBuiltIn = @("Administrator", "Guest", "DefaultAccount", "defaultuser0", "WDAGUtilityAccount") 139 | $localAdmins = Get-LocalGroupMember -Group "Administrators" | 140 | Where-Object { $_.objectClass -eq "User" } | 141 | Select-Object -ExpandProperty Name 142 | $results = @() 143 | $allUsers = Get-LocalUser 144 | foreach ($user in $allUsers) { 145 | if (($allowedBuiltIn -notcontains $user.Name) -and ($localAdmins -notcontains $user.Name)) { 146 | $results += [pscustomobject]@{ 147 | Name = $user.Name 148 | Issue = "Account is not allowed" 149 | Enabled = -not $user.Disabled 150 | } 151 | } 152 | } 153 | $results | ConvertTo-Json 154 | register: wn10_00_000085_disallowed_check 155 | 156 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Set fact for disallowed accounts check results." 157 | ansible.builtin.set_fact: 158 | wn10_00_000085_non_allowed_accounts: "{{ wn10_00_000085_disallowed_check.stdout | from_json }}" 159 | 160 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Set compliance status fact based on local accounts checks." 161 | ansible.builtin.set_fact: 162 | wn10_00_000085_local_accounts_compliant: >- 163 | {{ 164 | (wn10_00_000085_built_in_accounts | selectattr('Issue', 'equalto', 'Built-in account is disabled') | list | length == wn10_00_000085_built_in_accounts | length) 165 | and 166 | ( 167 | (wn10_00_000085_non_allowed_accounts is mapping and wn10_00_000085_non_allowed_accounts | length == 0) 168 | or 169 | (wn10_00_000085_non_allowed_accounts is sequence and wn10_00_000085_non_allowed_accounts | length == 0) 170 | ) 171 | }} 172 | 173 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Verify local account compliance and display results" 174 | when: not wn10_00_000085_local_accounts_compliant 175 | ansible.builtin.debug: 176 | msg: >- 177 | [ 178 | "═══════════════════════════════════════════════════════════════════════════════════", 179 | " Local Account Compliance Check - Domain Connected ", 180 | "═══════════════════════════════════════════════════════════════════════════════════", 181 | "", 182 | "Built-in Accounts Status:", 183 | "", 184 | {% for acct in wn10_00_000085_built_in_accounts %} 185 | " {{ acct.Name }} - {{ acct.Issue }} (Enabled: {{ acct.Enabled }})", 186 | {% endfor %} 187 | "───────────────────────────────────────────────────────────────────────────────────", 188 | "", 189 | "Disallowed Accounts:", 190 | "", 191 | {% if wn10_00_000085_non_allowed_accounts is mapping %} 192 | " {{ wn10_00_000085_non_allowed_accounts.Name }} - {{ wn10_00_000085_non_allowed_accounts.Issue }} (Enabled: {{ wn10_00_000085_non_allowed_accounts.Enabled }})", 193 | {% elif wn10_00_000085_non_allowed_accounts | length > 0 %} 194 | {% for acct in wn10_00_000085_non_allowed_accounts %} 195 | " {{ acct.Name }} - {{ acct.Issue }} (Enabled: {{ acct.Enabled }})", 196 | {% endfor %} 197 | {% else %} 198 | " No disallowed accounts found.", 199 | {% endif %} 200 | "", 201 | "───────────────────────────────────────────────────────────────────────────────────", 202 | "", 203 | {% if (wn10_00_000085_built_in_accounts | selectattr('Issue', 'equalto', 'Built-in account is disabled') | list | length == wn10_00_000085_built_in_accounts | length) and ((wn10_00_000085_non_allowed_accounts is mapping and wn10_00_000085_non_allowed_accounts | length == 0) or (wn10_00_000085_non_allowed_accounts is sequence and wn10_00_000085_non_allowed_accounts | length == 0)) %} 204 | "COMPLIANCE STATUS: COMPLIANT — All built-in accounts are disabled and no disallowed accounts found.", 205 | {% else %} 206 | "COMPLIANCE STATUS: Warning!! NON-COMPLIANT — Issues detected with local accounts.", 207 | {% endif %} 208 | "", 209 | "═══════════════════════════════════════════════════════════════════════════════════" 210 | ] 211 | 212 | - name: "LOW | WN10-00-000085 | AUDIT | Standard local user accounts must not exist on a system in a domain. | Warn Count." 213 | when: not wn10_00_000085_local_accounts_compliant 214 | ansible.builtin.import_tasks: warning_facts.yml 215 | vars: 216 | warn_control_id: 'WN10-00-000085' 217 | 218 | - name: "LOW | WN10-CC-000030 | PATCH | The system must be configured to prevent Internet Control Message Protocol (ICMP) redirects from overriding Open Shortest Path First (OSPF) generated routes." 219 | when: wn10_cc_000030 220 | tags: 221 | - WN10-CC-000030 222 | - CAT3 223 | - CCI-000366 224 | - SRG-OS-000480-GPOS-00227 225 | - SV-220797r991589_rule 226 | - V-220797 227 | - NIST800-53_CM-6_b 228 | - NIST800-53A_CM-6.1_iv 229 | - NIST800-53R4_CM-6_b 230 | ansible.windows.win_regedit: 231 | path: HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 232 | name: EnableICMPRedirect 233 | data: 0 234 | type: dword 235 | 236 | - name: "LOW | WN10-CC-000035 | PATCH | The system must be configured to ignore NetBIOS name release requests except from WINS servers." 237 | when: wn10_cc_000035 238 | tags: 239 | - WN10-CC-000035 240 | - CAT3 241 | - CCI-002385 242 | - SRG-OS-000420-GPOS-00186 243 | - SV-220798r958902_rule 244 | - V-220798 245 | - NIST800-53R4_SC-5 246 | ansible.windows.win_regedit: 247 | path: HKLM:\SYSTEM\CurrentControlSet\Services\Netbt\Parameters 248 | name: NoNameReleaseOnDemand 249 | data: 1 250 | type: dword 251 | 252 | - name: "LOW | WN10-CC-000170 | PATCH | The setting to allow Microsoft accounts to be optional for modern style apps must be enabled" 253 | when: wn10_cc_000170 254 | tags: 255 | - WN10-CC-000170 256 | - CAT3 257 | - CCI-000366 258 | - SRG-OS-000480-GPOS-00227 259 | - SV-220825r991589_rule 260 | - V-220825 261 | - NIST800-53_CM-6_b 262 | - NIST800-53A_CM-6.1_iv 263 | - NIST800-53R4_CM-6_b 264 | ansible.windows.win_regedit: 265 | path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 266 | name: MSAOptional 267 | data: 1 268 | type: dword 269 | 270 | - name: "LOW | WN10-CC-000175 | PATCH | The Application Compatibility Program Inventory must be prevented from collecting data and sending the information to Microsoft." 271 | when: wn10_cc_000175 272 | tags: 273 | - WN10-CC-000175 274 | - CAT3 275 | - CCI-000381 276 | - SRG-OS-000095-GPOS-00049 277 | - SV-220826r958478_rule 278 | - V-220826 279 | - NIST800-53_CM-7 280 | - NIST800-53A_CM-7.1_ii 281 | - NIST800-53R4_CM-7_a 282 | ansible.windows.win_regedit: 283 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppCompat 284 | name: DisableInventory 285 | data: 1 286 | type: dword 287 | 288 | - name: "LOW | WN10-CC-000197 | PATCH | Microsoft consumer experiences must be turned off." 289 | when: wn10_cc_000197 290 | tags: 291 | - WN10-CC-000197 292 | - CAT3 293 | - CCI-000381 294 | - SRG-OS-000095-GPOS-00049 295 | - SV-220831r958478_rule 296 | - V-220831 297 | - NIST800-53_CM-7 298 | - NIST800-53A_CM-7.1_ii 299 | - NIST800-53R4_CM-7_a 300 | ansible.windows.win_regedit: 301 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent 302 | name: DisableWindowsConsumerFeatures 303 | data: 1 304 | type: dword 305 | 306 | - name: "LOW | WN10-CC-000206 | PATCH | Windows Update must not obtain updates from other PCs on the Internet." 307 | when: wn10_cc_000206 308 | tags: 309 | - WN10-CC-000206 310 | - CAT3 311 | - CCI-000366 312 | - SRG-OS-000480-GPOS-00227 313 | - SV-220835r991589_rule 314 | - V-220835 315 | - NIST800-53_CM-6_b 316 | - NIST800-53A_CM-6.1_iv 317 | - NIST800-53R4_CM-6_b 318 | block: 319 | - name: "LOW | WN10-CC-000206 | PATCH | Windows Update must not obtain updates from other PCs on the Internet. | On a domain" 320 | when: 321 | - discovered_domain_joined 322 | - win10stig_dodownloadmode | int in [0, 1, 2, 99, 100] 323 | ansible.windows.win_regedit: 324 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization 325 | name: DODownloadMode 326 | data: "{{ win10stig_dodownloadmode }}" 327 | type: dword 328 | 329 | - name: "LOW | WN10-CC-000206 | PATCH | Windows Update must not obtain updates from other PCs on the Internet. | Stand-alone" 330 | when: 331 | - not discovered_domain_joined 332 | - win10stig_dodownloadmode | int in [0, 1] 333 | ansible.windows.win_regedit: 334 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization 335 | name: DODownloadMode 336 | data: "{{ win10stig_dodownloadmode }}" 337 | type: dword 338 | 339 | - name: "LOW | WN10-CC-000206 | AUDIT | Windows Update must not obtain updates from other PCs on the Internet. | Warning Message." 340 | when: 341 | - (not discovered_domain_joined and win10stig_dodownloadmode | int not in [0, 1]) or 342 | (discovered_domain_joined and win10stig_dodownloadmode | int not in [0, 1, 2, 99, 100]) 343 | ansible.builtin.debug: 344 | msg: 345 | - "Warning!! You have an invalid setting for win10stig_dodownloadmode. Please read" 346 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 347 | 348 | - name: "LOW | WN10-CC-000206 | AUDIT | Windows Update must not obtain updates from other PCs on the Internet. | Warn Count." 349 | when: 350 | - (not discovered_domain_joined and win10stig_dodownloadmode | int not in [0, 1]) or 351 | (discovered_domain_joined and win10stig_dodownloadmode | int not in [0, 1, 2, 99, 100]) 352 | ansible.builtin.import_tasks: warning_facts.yml 353 | vars: 354 | warn_control_id: 'WN10-CC-000206' 355 | 356 | - name: "LOW | WN10-CC-000220 | PATCH | Turning off File Explorer heap termination on corruption must be disabled." 357 | when: wn10_cc_000220 358 | tags: 359 | - WN10-CC-000220 360 | - CAT3 361 | - CCI-002385 362 | - SRG-OS-000420-GPOS-00186 363 | - SV-220838r958902_rule 364 | - V-220838 365 | - NIST800-53R4_SC-5 366 | ansible.windows.win_regedit: 367 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer 368 | name: NoHeapTerminationOnCorruption 369 | data: 0 370 | type: dword 371 | 372 | - name: "LOW | WN10-CC-000390 | PATCH | Windows 10 should be configured to prevent users from receiving suggestions for third-party or additional applications." 373 | when: wn10_cc_000390 374 | tags: 375 | - WN10-CC-000390 376 | - CAT3 377 | - CCI-000381 378 | - SRG-OS-000095-GPOS-00049 379 | - SV-220872r958478_rule 380 | - V-220872 381 | - NIST800-53_CM-7 382 | - NIST800-53A_CM-7.1_ii 383 | - NIST800-53R4_CM-7_a 384 | ansible.windows.win_regedit: 385 | path: HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent 386 | name: DisableThirdPartySuggestions 387 | data: 1 388 | type: dword 389 | 390 | - name: "LOW | WN10-SO-000050 | PATCH | The computer account password must not be prevented from being reset." 391 | when: wn10_so_000050 392 | tags: 393 | - WN10-SO-000050 394 | - CAT3 395 | - CCI-000366 396 | - SRG-OS-000480-GPOS-00227 397 | - SV-220917r991589_rule 398 | - V-220917 399 | - NIST800-53_CM-6_b 400 | - NIST800-53A_CM-6.1_iv 401 | - NIST800-53R4_CM-6_b 402 | ansible.windows.win_regedit: 403 | path: HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters 404 | name: DisablePasswordChange 405 | data: 0 406 | type: dword 407 | 408 | - name: "LOW | WN10-SO-000055 | PATCH | The maximum age for machine account passwords must be configured to 30 days or less." 409 | when: wn10_so_000055 410 | tags: 411 | - WN10-SO-000055 412 | - CAT3 413 | - CCI-000366 414 | - SRG-OS-000480-GPOS-00227 415 | - SV-220918r991589_rule 416 | - V-220918 417 | - NIST800-53_CM-6_b 418 | - NIST800-53A_CM-6.1_iv 419 | - NIST800-53R4_CM-6_b 420 | block: 421 | - name: "LOW | WN10-SO-000055 | PATCH | The maximum age for machine account passwords must be configured to 30 days or less." 422 | when: 423 | - win10stig_max_pw_age <= 30 424 | - win10stig_max_pw_age >= 1 425 | ansible.windows.win_regedit: 426 | path: HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters 427 | name: MaximumPasswordAge 428 | data: "{{ win10stig_max_pw_age }}" 429 | type: dword 430 | 431 | - name: "LOW | WN10-SO-000055 | AUDIT | The maximum age for machine account passwords must be configured to 30 days or less. | Warning Message." 432 | when: win10stig_max_pw_age > 30 or win10stig_max_pw_age == 0 433 | ansible.builtin.debug: 434 | msg: 435 | - "Warning!! You have an invalid setting for win10stig_max_pw_age. Please read" 436 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 437 | 438 | - name: "LOW | WN10-SO-000055 | PATCH | The maximum age for machine account passwords must be configured to 30 days or less. | Warn Count." 439 | when: win10stig_max_pw_age > 30 or win10stig_max_pw_age == 0 440 | ansible.builtin.import_tasks: warning_facts.yml 441 | vars: 442 | warn_control_id: 'WN10-SO-000055' 443 | 444 | - name: "LOW | WN10-SO-000080 | PATCH | The Windows dialog box title for the legal banner must be configured." 445 | when: wn10_so_000080 446 | tags: 447 | - WN10-SO-000080 448 | - CAT3 449 | - CCI-000048 450 | - CCI-001384 451 | - CCI-001385 452 | - CCI-001386 453 | - CCI-001387 454 | - CCI-001388 455 | - SRG-OS-000228-GPOS-00088 456 | - SV-220922r958390_rule 457 | - V-220922 458 | - NIST800-53_AC-8_a 459 | - NIST800-53_AC-8_c 460 | - NIST800-53A_AC-8.1_ii 461 | - NIST800-53A_AC-8.2_i 462 | - NIST800-53A_AC-8.2_ii 463 | - NIST800-53A_AC-8.2_iii 464 | - NIST800-53R4_AC-8_a 465 | - NIST800-53R4_AC-8_c_1 466 | - NIST800-53R4_AC-8_c_2 467 | - NIST800-53R4_AC-8_c_3 468 | ansible.windows.win_regedit: 469 | path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 470 | name: LegalNoticeCaption 471 | data: "{{ win10stig_legal_notice_caption }}" 472 | type: string 473 | 474 | - name: "LOW | WN10-SO-000085 | PATCH | Caching of logon credentials must be limited." 475 | when: wn10_so_000085 476 | tags: 477 | - WN10-SO-000085 478 | - CAT3 479 | - CCI-000366 480 | - SRG-OS-000480-GPOS-00227 481 | - SV-220923r991589_rule 482 | - V-220923 483 | - NIST800-53_CM-6_b 484 | - NIST800-53A_CM-6.1_iv 485 | - NIST800-53R4_CM-6_b 486 | block: 487 | - name: "LOW | WN10-SO-000085 | PATCH | Caching of logon credentials must be limited. | Set Variable" 488 | when: win10stig_cached_logons_count <= 10 489 | ansible.windows.win_regedit: 490 | path: HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 491 | name: CachedLogonsCount 492 | data: "{{ win10stig_cached_logons_count }}" 493 | type: string 494 | 495 | - name: "LOW | WN10-SO-000085 | AUDIT | Caching of logon credentials must be limited. | Warning Message." 496 | when: win10stig_cached_logons_count > 10 497 | ansible.builtin.debug: 498 | msg: 499 | - "Warning!! You have an invalid setting for win10stig_cached_logons_count. Please read" 500 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 501 | 502 | - name: "LOW | WN10-SO-000085 | AUDIT | Caching of logon credentials must be limited. | Warn Count." 503 | when: win10stig_cached_logons_count > 10 504 | ansible.builtin.import_tasks: warning_facts.yml 505 | vars: 506 | warn_control_id: 'WN10-SO-000085' 507 | 508 | - name: "LOW | WN10-SO-000240 | PATCH | The default permissions of global system objects must be increased." 509 | when: wn10_so_000240 510 | tags: 511 | - WN10-SO-000240 512 | - CAT3 513 | - CCI-000366 514 | - SRG-OS-000480-GPOS-00227 515 | - SV-220943r991589_rule 516 | - V-220943 517 | - NIST800-53_CM-6_b 518 | - NIST800-53A_CM-6.1_iv 519 | - NIST800-53R4_CM-6_b 520 | ansible.windows.win_regedit: 521 | path: HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager 522 | name: ProtectionMode 523 | data: 1 524 | type: dword 525 | 526 | - name: "LOW | WN10-UC-000015 | PATCH | Toast notifications to the lock screen must be turned off." 527 | when: wn10_uc_000015 528 | tags: 529 | - WN10-UC-000015 530 | - CAT3 531 | - CCI-000381 532 | - SRG-OS-000095-GPOS-00049 533 | - SV-220954r958478_rule 534 | - V-220954 535 | - NIST800-53_CM-7 536 | - NIST800-53A_CM-7.1_ii 537 | - NIST800-53R4_CM-7_a 538 | ansible.windows.win_regedit: 539 | path: HKCU:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications 540 | name: NoToastApplicationNotificationOnLockScreen 541 | data: 1 542 | type: dword 543 | 544 | - name: "MEDIUM | WN10-CC-000080 | PATCH | Virtualization-based protection of code integrity must be enabled." 545 | when: 546 | - wn10_cc_000080 547 | - not discovered_vdi_non_persistent 548 | tags: 549 | - WN10-CC-000080 550 | - CAT2 551 | - CCI-000366 552 | - SRG-OS-000480-GPOS-00227 553 | - SV-252903r991589_rule 554 | - V-252903 555 | - NIST800-53_CM-6_b 556 | - NIST800-53A_CM-6.1_iv 557 | - NIST800-53R4_CM-6_b 558 | block: 559 | - name: "MEDIUM | WN10-CC-000080 | PATCH | Virtualization-based protection of code integrity must be enabled. | Set registry settings." 560 | when: win10stig_hypervisor_enforce_code_integrity == 1 or win10stig_hypervisor_enforce_code_integrity == 2 561 | ansible.windows.win_regedit: 562 | path: HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeviceGuard\ 563 | name: HypervisorEnforcedCodeIntegrity 564 | data: "{{ win10stig_hypervisor_enforce_code_integrity }}" 565 | type: dword 566 | 567 | - name: "MEDIUM | WN10-CC-000080 | AUDIT | Virtualization-based protection of code integrity must be enabled. | Warning Check For Variable Standards." 568 | when: 569 | - win10stig_hypervisor_enforce_code_integrity != 1 570 | - win10stig_hypervisor_enforce_code_integrity != 2 571 | ansible.builtin.debug: 572 | msg: 573 | - "Warning!! You have an invalid setting for win10stig_hypervisor_enforce_code_integrity. Please read" 574 | - "the notes for the variable and make the necessary change to the variable to be in compliance." 575 | 576 | - name: "MEDIUM | WN10-CC-000080 | AUDIT | Virtualization-based protection of code integrity must be enabled. | Warning Count." 577 | when: 578 | - win10stig_hypervisor_enforce_code_integrity != 1 579 | - win10stig_hypervisor_enforce_code_integrity != 2 580 | ansible.builtin.import_tasks: 581 | file: warning_facts.yml 582 | vars: 583 | warn_control_id: 'WN10-CC-000080' 584 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "MAIN | Display Banner" 4 | tags: 5 | - always 6 | ansible.builtin.debug: 7 | msg: "{{ lockdown_banner.split('\n') }}" 8 | 9 | - name: "MAIN | Gather distribution info" 10 | when: ansible_distribution is not defined 11 | tags: 12 | - always 13 | ansible.builtin.setup: 14 | gather_subset: distribution,!all,!min 15 | 16 | - name: "MAIN | Check OS version and family" 17 | tags: 18 | - always 19 | ansible.builtin.assert: 20 | that: 21 | - ansible_os_family == 'Windows' 22 | - ansible_distribution | regex_search('(Microsoft Windows 10)') 23 | success_msg: "{{ ansible_distribution }} {{ ansible_distribution_major_version }} is the detected operating system." 24 | fail_msg: "This role can only be run against Windows 10 Editions. {{ ansible_distribution }} {{ ansible_distribution_major_version }} is not supported." 25 | 26 | - name: "MAIN | Get Disk Facts" 27 | when: wn10_00_000050 or wn10_00_000130 28 | community.windows.win_disk_facts: 29 | 30 | - name: "MAIN | Check ansible version" 31 | tags: 32 | - always 33 | ansible.builtin.assert: 34 | that: ansible_version.full is version_compare(win10stig_min_ansible_version, '>=') 35 | msg: You must use Ansible {{ win10stig_min_ansible_version }} or greater 36 | 37 | - name: "MAIN | Include the Preliminary tasks" 38 | tags: 39 | - prelim_tasks 40 | ansible.builtin.import_tasks: 41 | file: prelim.yml 42 | 43 | - name: "MAIN | Execute CAT 1 Controls Tasks" 44 | when: win10stig_cat1_patch | bool 45 | tags: 46 | - cat1 47 | - high 48 | ansible.builtin.import_tasks: 49 | file: cat1.yml 50 | 51 | - name: "MAIN | Execute CAT 2 Controls Tasks" 52 | when: win10stig_cat2_patch | bool 53 | tags: 54 | - cat2 55 | - medium 56 | ansible.builtin.import_tasks: 57 | file: cat2.yml 58 | 59 | - name: "MAIN | Execute CAT 3 Controls Tasks" 60 | when: win10stig_cat3_patch | bool 61 | tags: 62 | - cat3 63 | - low 64 | ansible.builtin.import_tasks: 65 | file: cat3.yml 66 | 67 | - name: "MAIN | Run Post Tasks" 68 | tags: 69 | - always 70 | ansible.builtin.import_tasks: 71 | file: post.yml 72 | 73 | - name: "MAIN | If Warnings found Output count and control IDs affected" 74 | when: warn_count != 0 75 | tags: 76 | - always 77 | ansible.builtin.debug: 78 | msg: 79 | - "You have {{ warn_count }} Warning(s) that require investigation(s). Their ID’s are listed below:" 80 | - "{{ warn_control_list }}" 81 | -------------------------------------------------------------------------------- /tasks/post.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "POST | Flush Handlers" 4 | tags: 5 | - always 6 | ansible.builtin.meta: flush_handlers 7 | 8 | - name: "POST | Reboot System Options" 9 | vars: 10 | warn_control_id: Reboot_Required 11 | tags: 12 | - always 13 | block: 14 | - name: "POST | Rebooting System................. Skip Reboot Has Been Set To: False" 15 | when: 16 | - reboot_host 17 | - not skip_reboot 18 | ansible.windows.win_reboot: 19 | reboot_timeout: 3600 20 | 21 | - name: "POST | Warning A Reboot Is Required, Skip Reboot Has Been Set" 22 | when: 23 | - reboot_host 24 | - skip_reboot 25 | ansible.builtin.debug: 26 | msg: 27 | - "Warning!! Changes Have Been Made That Require A Reboot To Be Implemented Manually." 28 | - "Skip Reboot Was Set To: True - This Can Affect Compliance Check Results." 29 | changed_when: true 30 | 31 | - name: "POST | Warning A Reboot Is Required, Skip Reboot Has Been Set | Warning Count" 32 | when: 33 | - reboot_host 34 | - skip_reboot 35 | ansible.builtin.import_tasks: 36 | file: warning_facts.yml 37 | -------------------------------------------------------------------------------- /tasks/prelim.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "PRELIM | Get Display Version value." 4 | tags: 5 | - always 6 | ansible.windows.win_reg_stat: 7 | path: HKLM:\Software\Microsoft\Windows NT\CurrentVersion 8 | name: DisplayVersion 9 | changed_when: false 10 | failed_when: false 11 | register: discovered_displayversion 12 | 13 | - name: "PRELIM | Get OS Build value." 14 | tags: 15 | - always 16 | ansible.windows.win_reg_stat: 17 | path: HKLM:\Software\Microsoft\Windows NT\CurrentVersion 18 | name: CurrentBuild 19 | changed_when: false 20 | failed_when: false 21 | register: discovered_currentbuild 22 | 23 | - name: "PRELIM | Detect if Trusted Platform Module (TPM) is Available" 24 | tags: 25 | - always 26 | block: 27 | - name: "PRELIM | Retrieve TPM information" 28 | ansible.windows.win_shell: Get-Tpm | ConvertTo-Json 29 | changed_when: false 30 | failed_when: false 31 | register: discovered_tpm_info 32 | 33 | - name: "PRELIM | Set fact for TPM presence" 34 | ansible.builtin.set_fact: 35 | discovered_tpm_present: "{{ (discovered_tpm_info.stdout | from_json).TpmPresent }}" 36 | 37 | - name: "PRELIM | Detect if Remote Desktop Services (RDP) is enabled" 38 | tags: 39 | - always 40 | ansible.windows.win_reg_stat: 41 | path: HKLM:\System\CurrentControlSet\Control\Terminal Server 42 | name: fDenyTSConnections 43 | changed_when: false 44 | failed_when: false 45 | register: discovered_rdp_enabled 46 | 47 | - name: "PRELIM | Set Fact If Domain Joined." 48 | when: ansible_windows_domain_member is defined 49 | tags: 50 | - always 51 | ansible.builtin.set_fact: 52 | discovered_domain_joined: "{{ ansible_windows_domain_member }}" 53 | 54 | ### DETECT IF SYSTEM IS VDI OR AVD ### 55 | - name: "PRELIM | Determine if system is a Virtual Machine (VDI)" 56 | tags: 57 | - always 58 | ansible.windows.win_shell: (Get-WmiObject Win32_ComputerSystem).Model 59 | changed_when: false 60 | failed_when: false 61 | register: discovered_vm_check 62 | 63 | - name: "PRELIM | Determine if system is using FSLogix (Roaming Profile Storage)" 64 | tags: 65 | - always 66 | ansible.windows.win_shell: Get-Service FSLogixApps -ErrorAction SilentlyContinue 67 | changed_when: false 68 | failed_when: false 69 | ignore_errors: true 70 | register: discovered_fslogix_check 71 | 72 | - name: "PRELIM | Determine if OS disk is Ephemeral (No Data at Rest)" 73 | tags: 74 | - always 75 | ansible.windows.win_shell: Get-PhysicalDisk | Select-Object MediaType, OperationalStatus | Format-List 76 | changed_when: false 77 | failed_when: false 78 | ignore_errors: true 79 | register: discovered_disk_check 80 | 81 | - name: "PRELIM | Determine if system is Azure Virtual Desktop (AVD)" 82 | tags: 83 | - always 84 | ansible.windows.win_shell: Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\*" 85 | changed_when: false 86 | failed_when: false 87 | ignore_errors: true 88 | register: discovered_avd_check 89 | 90 | - name: "PRELIM | Show VDI, AVD, FSLogix, and Disk Info" 91 | tags: 92 | - always 93 | ansible.builtin.debug: 94 | msg: 95 | - "VM Model: {{ discovered_vm_check.stdout }}" 96 | - "FSLogix Status: {{ discovered_fslogix_check.stdout | default('FSLogix not installed') }}" 97 | - "Disk Info: {{ discovered_disk_check.stdout_lines }}" 98 | - "AVD Check: {{ discovered_avd_check.stdout | default('Not an AVD system') }}" 99 | 100 | ### SET FACT IF SYSTEM IS AVD WITH NO DATA AT REST ### 101 | - name: "PRELIM | Mark system as AVD with no data at rest" 102 | when: ("Azure" in discovered_vm_check.stdout) or ("CloudDomainJoin" in discovered_avd_check.stdout | default('')) or ("Running" in discovered_fslogix_check.stdout | default('')) 103 | tags: 104 | - always 105 | ansible.builtin.set_fact: 106 | discovered_avd_no_data_at_rest: true 107 | 108 | ### SET FACT IF SYSTEM IS A NON-PERSISTENT VDI ### 109 | - name: "PRELIM | Mark system as Non-Persistent VDI" 110 | when: 111 | - ("Virtual Machine" in discovered_vm_check.stdout) 112 | - ("SSD" in discovered_disk_check.stdout | default('')) 113 | - not ("Persistent" in discovered_vdi_persistence.stdout | default('')) 114 | tags: 115 | - always 116 | ansible.builtin.set_fact: 117 | discovered_vdi_non_persistent: true 118 | 119 | ### SET FACT IF SYSTEM IS A PERSISTENT VDI ### 120 | - name: "PRELIM | Mark system as Persistent VDI" 121 | when: 122 | - ("Virtual Machine" in discovered_vm_check.stdout) 123 | - ("Persistent" in discovered_vdi_persistence.stdout | default('')) 124 | tags: 125 | - always 126 | ansible.builtin.set_fact: 127 | discovered_vdi_persistent: true 128 | 129 | ### DISPLAY MESSAGE IF SYSTEM IS AVD WITH NO DATA AT REST ### 130 | - name: "PRELIM | System is an AVD instance with NO data at rest - Certain Controls Will Be Skipped" 131 | when: discovered_avd_no_data_at_rest 132 | tags: 133 | - always 134 | ansible.builtin.debug: 135 | msg: "This system is an AVD instance with NO DATA AT REST. Certain controls will not be applied." 136 | 137 | ### DISPLAY MESSAGE IF SYSTEM IS A NON-PERSISTENT VDI ### 138 | - name: "PRELIM | System is a Non-Persistent VDI - Certain Controls Will Be Skipped" 139 | when: discovered_vdi_persistent 140 | tags: 141 | - always 142 | ansible.builtin.debug: 143 | msg: "This system is a Non-Persistent VDI, meaning it is deleted or refreshed upon logoff. Certain controls will not be applied." 144 | 145 | ### DISPLAY MESSAGE IF SYSTEM IS A PERSISTENT VDI ### 146 | - name: "PRELIM | System is a Persistent VDI - All Relevant Controls Will Be Applied" 147 | when: discovered_vdi_non_persistent 148 | tags: 149 | - always 150 | ansible.builtin.debug: 151 | msg: "This system is a Persistent VDI, meaning data is retained across logins. All applicable controls will be enforced." 152 | 153 | ### DISPLAY MESSAGE IF SYSTEM IS NOT A VDI/AVD ### 154 | - name: "PRELIM | System is Not a VDI or AVD - All Controls Will Apply" 155 | when: 156 | - not discovered_avd_no_data_at_rest 157 | - not discovered_vdi_non_persistent 158 | - not discovered_vdi_persistent 159 | tags: 160 | - always 161 | ansible.builtin.debug: 162 | msg: "This system is not a VDI or AVD and will have all applicable security controls enforced." 163 | 164 | # hvm is for amazon ami's, Hyper-V we have found for azure, kvm is used for ('QEMU', 'Amazon EC2', 'DigitalOcean', 'Google', 'Scaleway', 'Nutanix', 'KVM', 'KVM Server', 'Bochs', 'AHV') 165 | # This list is not complete and will be updated as we try on more cloud based services. 166 | # As of now testing is working in azure using Hyper-V. We are currently using this for reference: 167 | # https://github.com/ansible/ansible/blob/905131fc76a07cf89dbc8d33e7a4910da3f10a16/lib/ansible/module_utils/facts/virtual/linux.py#L205 168 | - name: "PRELIM | Set Fact If Cloud Based System." 169 | when: 170 | - not ansible_virtualization_type == 'VMware' or 171 | (ansible_system_vendor == 'Microsoft Corporation' and 172 | ansible_virtualization_type in ['Hyper-V', 'hvm', 'kvm']) 173 | tags: 174 | - always 175 | ansible.builtin.set_fact: 176 | discovered_cloud_based_system: true 177 | 178 | - name: "PRELIM | Get Admin Users and Groups" 179 | tags: 180 | - always 181 | ansible.windows.win_shell: Get-LocalGroupMember -Name 'Administrators' 182 | changed_when: false 183 | failed_when: false 184 | register: discovered_admin_users_groups 185 | 186 | - name: "PRELIM | Get List of All Administrative Accounts" 187 | tags: 188 | - always 189 | ansible.windows.win_shell: Get-LocalGroupMember -Name 'Administrators' | Select-Object -ExpandProperty Name | ConvertTo-Json -Compress 190 | changed_when: false 191 | failed_when: false 192 | register: discovered_admin_accounts 193 | -------------------------------------------------------------------------------- /tasks/warning_facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # This task is used to create variables used in giving a warning summary for manual tasks 4 | # that need attention 5 | # 6 | # The warn_control_list and warn_count vars start life in vars/main.yml but get updated 7 | # as the tasks that have a warning complete 8 | # 9 | # Those two variables are used in the tasks/main.yml to display a list of warnings 10 | # 11 | # warn_control_id is set within the task itself and has the control ID as the value 12 | # 13 | # warn_control_list is the main variable to be used and is a list made up of the warn_control_id’s 14 | # 15 | # warn_count the main variable for the number of warnings and each time a warn_control_id is added 16 | # the count increases by a value of 1 17 | - name: "NO CONTROL ID | AUDIT | Set fact for manual task warning." 18 | ansible.builtin.set_fact: 19 | warn_control_list: "{{ warn_control_list }} [{{ warn_control_id }}]" 20 | warn_count: "{{ warn_count | int + 1 }}" 21 | -------------------------------------------------------------------------------- /templates/banner.txt: -------------------------------------------------------------------------------- 1 | ░█████╗░███╗░░██╗░██████╗██╗██████╗░██╗░░░░░███████╗ 2 | ██╔══██╗████╗░██║██╔════╝██║██╔══██╗██║░░░░░██╔════╝ 3 | ███████║██╔██╗██║╚█████╗░██║██████╦╝██║░░░░░█████╗░░ 4 | ██╔══██║██║╚████║░╚═══██╗██║██╔══██╗██║░░░░░██╔══╝░░ 5 | ██║░░██║██║░╚███║██████╔╝██║██████╦╝███████╗███████╗ 6 | ╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░╚═╝╚═════╝░╚══════╝╚══════╝ 7 | ██╗░░░░░░█████╗░░█████╗░██╗░░██╗██████╗░░█████╗░░██╗░░░░░░░██╗███╗░░██╗ 8 | ██║░░░░░██╔══██╗██╔══██╗██║░██╔╝██╔══██╗██╔══██╗░██║░░██╗░░██║████╗░██║ 9 | ██║░░░░░██║░░██║██║░░╚═╝█████═╝░██║░░██║██║░░██║░╚██╗████╗██╔╝██╔██╗██║ 10 | ██║░░░░░██║░░██║██║░░██╗██╔═██╗░██║░░██║██║░░██║░░████╔═████║░██║╚████║ 11 | ███████╗╚█████╔╝╚█████╔╝██║░╚██╗██████╔╝╚█████╔╝░░╚██╔╝░╚██╔╝░██║░╚███║ 12 | ╚══════╝░╚════╝░░╚════╝░╚═╝░░╚═╝╚═════╝░░╚════╝░░░░╚═╝░░░╚═╝░░╚═╝░░╚══╝ 13 | .-----------------------------------------------------. 14 | | SUPPORTED BY MINDPOINT GROUP, A TYTO ATHENE COMPANY | 15 | '-----------------------------------------------------' 16 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for . 3 | 4 | # Used to control warning summary 5 | warn_control_list: "" 6 | warn_count: 0 7 | 8 | # This sets the variable that is created for the banner. 9 | lockdown_banner: "{{ lookup('file', './templates/banner.txt') }}" 10 | 11 | # Default setting, this should not be changed 12 | # and is overridden if a task that changed sets the value if required. 13 | reboot_host: false 14 | 15 | # This variable indicates if the system is an Azure Virtual Desktop (AVD) instance **with no data at rest**. 16 | # If `true`, certain controls (like BitLocker enforcement) **will not be applied** as per STIG compliance. 17 | # Conditions that set this to `true`: 18 | # - System is detected as running in Azure (`Azure` keyword in system check). 19 | # - FSLogix profile management is in use (`Running` in FSLogix check). 20 | # - Cloud domain join is detected (`CloudDomainJoin` keyword). 21 | discovered_avd_no_data_at_rest: false 22 | 23 | # This variable indicates if the system is a **Non-Persistent Virtual Desktop Infrastructure (VDI)**. 24 | # Non-Persistent VDIs **reset or refresh upon user logoff**, meaning no user data is retained. 25 | # If `true`, certain controls (like BitLocker enforcement) **will not be applied**, as the system is stateless. 26 | # Conditions that set this to `true`: 27 | # - System is a Virtual Machine (`Virtual Machine` keyword in system check). 28 | # - The VDI instance is **not marked as persistent**. 29 | # - The system drive is an SSD (often used for stateless VDIs). 30 | discovered_vdi_non_persistent: false 31 | 32 | # This variable indicates if the system is a **Persistent Virtual Desktop Infrastructure (VDI)**. 33 | # Persistent VDIs **retain user data across sessions**, functioning like traditional desktops. 34 | # If `true`, all applicable security controls **will be enforced**, including BitLocker. 35 | # Conditions that set this to `true`: 36 | # - System is a Virtual Machine (`Virtual Machine` keyword in system check). 37 | # - The VDI instance is explicitly **marked as persistent**. 38 | discovered_vdi_persistent: false 39 | 40 | # discovered_domain_joined is a setting built into the playbook for some controls that only applies 41 | # to standalone or domain joined systems. By default this is set to true. 42 | discovered_domain_joined: true 43 | 44 | # This will be changed to true if discovered. 45 | discovered_cloud_based_system: false 46 | 47 | # This variable is used in the tracking of only 1 copy of Windows being installed on the machine related. 48 | win10stig_os_keyword: "Windows" 49 | win10stig_non_windows_os_keywords: 50 | - "Ubuntu" 51 | - "Linux" 52 | - "Fedora" 53 | - "Alma" 54 | - "Debian" 55 | - "Red Hat" 56 | - "Rocky" 57 | - "Kali" 58 | - "Arch" 59 | - "SUSE" 60 | - "CentOS" 61 | - "Mac OS" 62 | - "Apple" 63 | 64 | # WN10-RG-000005 65 | # These are the default permissions that should be on the hives to compare against. 66 | win10stig_expected_software_acl: 67 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", RegistryRights: "FullControl", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 68 | - { IdentityReference: "BUILTIN\\Administrators", RegistryRights: "FullControl", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 69 | - { IdentityReference: "BUILTIN\\Users", RegistryRights: "ReadKey", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 70 | - { IdentityReference: "CREATOR OWNER", RegistryRights: "FullControl", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 71 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES", RegistryRights: "ReadKey", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 72 | - { IdentityReference: "S-1-15-3-1024-1065365936-1281604716-3511738428-1654721687-432734479-3232135806-4053264122-3456934681", RegistryRights: "ReadKey", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 73 | win10stig_expected_system_acl: 74 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", RegistryRights: "FullControl", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 75 | - { IdentityReference: "BUILTIN\\Administrators", RegistryRights: "FullControl", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 76 | - { IdentityReference: "BUILTIN\\Users", RegistryRights: "ReadKey", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 77 | - { IdentityReference: "CREATOR OWNER", RegistryRights: "FullControl", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 78 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES", RegistryRights: "ReadKey", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 79 | - { IdentityReference: "S-1-15-3-1024-1065365936-1281604716-3511738428-1654721687-432734479-3232135806-4053264122-3456934681", RegistryRights: "ReadKey", AccessControlType: "Allow", IsInherited: false, InheritanceFlags: "ContainerInherit", PropagationFlags: "None" } 80 | 81 | # WN10-00-000095 82 | # These are the default file system permissions to compare against. 83 | win10stig_expected_c_acl: 84 | - { IdentityReference: "S-1-15-3-65536-1888954469-739942743-1668119174-2468466756-4239452838-1296943325-355587736-700089176", Permissions: "(S,RD,X,RA)" } 85 | - { IdentityReference: "NT AUTHORITY\\Authenticated Users", Permissions: "(AD)" } 86 | - { IdentityReference: "NT AUTHORITY\\Authenticated Users", Permissions: "(OI)(CI)(IO)(M)" } 87 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", Permissions: "(OI)(CI)(F)" } 88 | - { IdentityReference: "BUILTIN\\Administrators", Permissions: "(OI)(CI)(F)" } 89 | - { IdentityReference: "BUILTIN\\Users", Permissions: "(OI)(CI)(RX)" } 90 | - { IdentityReference: "Mandatory Label\\High Mandatory Level", Permissions: "(OI)(NP)(IO)(NW)" } 91 | 92 | win10stig_expected_programfiles_acl: 93 | - { IdentityReference: "NT SERVICE\\TrustedInstaller", Permissions: "(F)" } 94 | - { IdentityReference: "NT SERVICE\\TrustedInstaller", Permissions: "(CI)(IO)(F)" } 95 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", Permissions: "(M)" } 96 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", Permissions: "(OI)(CI)(IO)(F)" } 97 | - { IdentityReference: "BUILTIN\\Administrators", Permissions: "(M)" } 98 | - { IdentityReference: "BUILTIN\\Administrators", Permissions: "(OI)(CI)(IO)(F)" } 99 | - { IdentityReference: "BUILTIN\\Users", Permissions: "(RX)" } 100 | - { IdentityReference: "BUILTIN\\Users", Permissions: "(OI)(CI)(IO)(GR,GE)" } 101 | - { IdentityReference: "CREATOR OWNER", Permissions: "(OI)(CI)(IO)(F)" } 102 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES", Permissions: "(RX)" } 103 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES", Permissions: "(OI)(CI)(IO)(GR,GE)" } 104 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL RESTRICTED APPLICATION PACKAGES", Permissions: "(RX)" } 105 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL RESTRICTED APPLICATION PACKAGES", Permissions: "(OI)(CI)(IO)(GR,GE)" } 106 | 107 | win10stig_expected_windows_acl: 108 | - { IdentityReference: "NT SERVICE\\TrustedInstaller", Permissions: "(F)" } 109 | - { IdentityReference: "NT SERVICE\\TrustedInstaller", Permissions: "(CI)(IO)(F)" } 110 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", Permissions: "(M)" } 111 | - { IdentityReference: "NT AUTHORITY\\SYSTEM", Permissions: "(OI)(CI)(IO)(F)" } 112 | - { IdentityReference: "BUILTIN\\Administrators", Permissions: "(M)" } 113 | - { IdentityReference: "BUILTIN\\Administrators", Permissions: "(OI)(CI)(IO)(F)" } 114 | - { IdentityReference: "BUILTIN\\Users", Permissions: "(RX)" } 115 | - { IdentityReference: "BUILTIN\\Users", Permissions: "(OI)(CI)(IO)(GR,GE)" } 116 | - { IdentityReference: "CREATOR OWNER", Permissions: "(OI)(CI)(IO)(F)" } 117 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES", Permissions: "(RX)" } 118 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL APPLICATION PACKAGES", Permissions: "(OI)(CI)(IO)(GR,GE)" } 119 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL RESTRICTED APPLICATION PACKAGES", Permissions: "(RX)" } 120 | - { IdentityReference: "APPLICATION PACKAGE AUTHORITY\\ALL RESTRICTED APPLICATION PACKAGES", Permissions: "(OI)(CI)(IO)(GR,GE)" } 121 | --------------------------------------------------------------------------------