Quick Windows Hardening with Infrastructure-as-Code — Chef and Inspec
CIS, Center for Internet Security, publishes prescriptive system hardening documents which provide guidance for establishing a secure system configuration on platforms such as Windows. Usually, their Windows hardening documents are over a hundred pages long and would take a long time to perform hardening manually by one person. Thankfully, there is an Infrastructure-as-Code configuration management approach, e.g. the one introduced below leveraging Chef and Inspec, to achieve automation of the hardening process and validating the results.
Instead of demonstrating the power of infrastructure as code fully, this quick post only aims at introducing the concept by leveraging Chef hardening recipes found on the Internet, showing the steps to perform Windows hardening on a single local machine quickly, which may suit one-time use cases. We will install Chef Development Kit to use chef-apply
for applying Chef recipes to harden a local machine and inspec
for verifying the hardening.
Tools Required
- Chef cookbook or recipes for Windows OS hardening (e.g. ones from my GitHub repository below, wandersick/windows_hardening, originally forked from MattTunny/windows_hardening GitHub repository, adjusted to fit the examples using the
chef-apply
approach in this article. You may use others found on the Internet, or craft ones that are catered to your needs)
Download: https://github.com/wandersick/windows_hardening
- Chef recipes crafted according to CIS-published guidance
- The example is for Windows Server 2012 and 2012 R2, which is similar for Windows Server 2016 and 2019
- You should customize. Here are some ideas:
a. You may not want to run some of the recipes which break functionalities such asharden_winrm.rb
(WinRM)
b. Incore_hardening.rb
, you may want UAC to be disabled (EnableLUA
not set to 1), the warning text displayed at logon to be different (legalnoticecaption
andlegalnoticetext
edited as desired). For domain controllers, you may wantEnableAuthEpResolution
to be removed in order to enable certain cross-forest/domain scenarios. For older printers/scanners/copiers not supporting NTLMv2 for scanning to shared folders, or you are encountering an issue in which Remote Desktop client keeps saying ‘the logon attempt failed’, you may wantLmCompatibilityLevel
to be removed. Similarly forRestrictNTLMInDomain
if it is a domain controller.
c. InlocalComputer.inf
, you may preferNewAdministratorName
andNewGuestName
are not set to_administrator
and_guest
, the maximum password age (MaximumPasswordAge
) not set to 42 days, and the minimum password length (MinimumPasswordLength
) not set to 14
(All of the above are the default settings from the recipes) - Some recipes require specific variables to be defined such as
cwd
for the path to some configuration files. Be sure to refer to the README.md and comments within each recipe file.
2. RegShot 2.0.1.70 (optional)
Download: https://www.wincert.net/forum/index.php?/files/file/16-regshot2-unicode
(This site requires account registration and login prior to download)
- This utility compares registry changes before and after hardening, provides a report of which, allows backup of registry in .reg and .hive files, as well as producing UNDO and REDO reg files
3. Chef Development Kit installed on a supported Windows machine
Download: https://downloads.chef.io/chefdk#windows
- Although the Chef Development Kit provides a lot of features, we will only use
chef-apply
for applying recipes (.rb files) to a local machine andinspec
for verification - The version used for this article is 4.4.27–1
4. Windows Command Prompt (run as administrator)
Pre-Hardening Configuration
- Install Chef Development Kit (on the target system to be hardened) with default settings
- Add
C:\opscode\chefdk\bin\
to the environment variable —%PATH%
— if not already added - Store downloaded
windows_hardening
directory like our working directory in this example,c:\temp\windows_hardening
instead ofc:\temp\windows_hardening-master
which may be inaccurately shown in a few screenshots
Pre-Hardening Verification and Backup
- For safety, back up the OS drive or at least the system state (most of the settings are registry settings)
- Perform 1st shot with Regshot 2.0
- Save .reg and .hive files (for an additional backup)
- Do not close the Regshot application yet (a 2nd shot will be run at the end of hardening as a comparison) - Verify with
inspec
- See a report of what have been hardened and what have not, for comparison later:
cd C:\temp\windows_hardening\
inspec exec test/integration/default/default_spec.rb
Performing Hardening
Friendly reminder: Ensure this is not done to a system without thoughtfulness — it is normal for issues to emerge after hardening. Think twice. Still insist? OK. Here you go!
First, ensure we are at the directory containing recipes.
cd C:\temp\windows_hardening\recipes
dir
Run the listed OS hardening recipes as needed with one of the chef-apply
methods below.
- Either apply recipes one by one using
chef-apply
, e.g. on the main recipe file containing most of the settings by replacing<file_name>.rb
withcore_hardening.rb
:
chef-apply <file_name>.rb
- Or apply multiple recipes in a go using
chef-apply
with afor
loop:
for /f "usebackq tokens=* delims=" %i in (`dir /b`) do chef-apply "%i"
Tips
- For the for-loop technique, please be reminded to carefully examine what will execute as all contents from all recipes will be applied. Some recipes may have a special purpose which are not meant to be run this way.
- Most hardening rules should work out of the box and do not require further modification if you choose the compatible Chef recipe named
core_hardening.rb
(where most of the hardening rules reside).
Side Talk — Ideas for Fixing Recipes Incompatible with chef-apply
Let’s take a detour before verifying the results.
The use of chef-apply
in this post (treating Chef recipes as scripts), while straight-forward for a quick demonstration or use, is not how Chef is run in production. If you use recipes not from my GitHub repository, you might encounter errors for those incompatible withchef-apply
. As an example, in this repository, a majority of errors encountered in the incompatible recipes were eliminated by manually modifying .rb files.
For example, for the harden_winrm.rb
recipe in Figure 1 (the top of this article), remove the first line after comment, and if
… end
outer wrapping from each block, leaving only inner registry_key
… end
parts.
Post-Hardening Verification and Backup
Verify with inspec
again after applying (Observe the increase in the count of passed items and the decrease in failed items.
cd ..
inspec exec test/integration/default/default_spec.rb
(The test run results in Figure 9 are available are available for viewing here)
Perform 2nd shot with Regshot 2.0 (to compare registry changes)
- Save .reg and .hive files (for backup)
- Back up
C:\HIVE
folder (the Regshot working folder) which contains UNDO and REDO reg files, which are useful for rollback and for understanding what has changed. (Note that some keys are unrelated due to other concurrent Windows activities)
For failed items reported by the second inspec
run which should be much lower now (e.g. 25 failed items in a case of mine on Windows Server 2016, where some of the recipes were left out intentionally; 0 failed items in another case). In case of any issues, you can also always fix them according to the official CIS Benchmarks documents. For user rights and privileges, it would be useful to refer to Microsoft documentation as well.
Is It Good to Go?
Although this is a Windows hardening method that is not officially supported (use it at your own risk), when tested and implemented correctly by a DevOps engineer familiar with Infrastructure-as-Code (here are freelancing marketplaces to hire one), it is an elegant way to improve productivity and make sure security settings are correctly applied in a way that is less prone to human errors. For home servers or labs that do not require as much consideration, this is a godsend. Thanks!
Originally published at https://tech.wandersick.com on 24 April, 2018.