Hardening Windows Virtual Machine with Azure State Configuration (DSC)

Getting your OS secured is one of the most crucial task nowadays. But how to know which settings needs to be configured and how? Those questions can be answered by Security Baselines. At the moment two most popular system configuration baselines are CIS (https://www.cisecurity.org/) and DISA STIG (https://public.cyber.mil/stigs). Here You can find great comparison between the two: https://nira.com/stig-vs-cis/.

Main advantage that DISA STIG have when compared to CIS is fact that DISA provides you already pre-created GPOs (https://public.cyber.mil/stigs/gpo/) for free when CIS for free gives only PDF benchmarks with all recommendations. Of course you can always review CIS benchmark and create your own GPO but in our case having one already created is a time saver.


Keep in mind that all security baselines before applying needs to be reviewed, so they don't impact your OS functionality. 


First you need to download or create your GPO. As said before in this example we will use pre-created "DoD Windows Server 2019 Member Server STIG Computer v2r4". This GPO configures Computer level settings for Servers, which are Members of the domain - there is separate policy for Domain Controllers. Policy name can be checked in gporeport.xml file (which is located inside policy directory).

Next Step is to install PowerShell BaselineManagement module (https://docs.microsoft.com/pl-PL/powershell/dsc/quickstarts/gpo-quickstart?view=dsc-1.1). This module is the tool that will create DSC config based on chosen GPO. To do that we use ConvertFrom-GPO command:

ConvertFrom-GPO -Path 'policy_path' -OutputConfigurationScript 'output_directory'

In case of "DoD Windows Server 2019 Member Server STIG Computer v2r4" GPO the right directory would be: "U_July_2022_STIG_GPO\DoD Windows Server 2019 MS and DC v2r4\GPOs\{66F060EE-AA92-4D42-A8BA-A52462E94A6A}".

The end result of that command should be a directory with two files .ps1 file and a .mof file. The file with .ps1 extension is a DSC configuration script and .mof file is a compiled DSC configuration. 

If above command errors out that means the .mof couldn't be successfully created from DSC configuration script. In that case DSC configuration script needs to be reviewed. Since in our example we will compile DSC configuration script in Azure we can now remove .mof file. Below are all of the changes I needed to make to be able to successfully compile DSC configuration script in Azure:







Also there were also some additional changes for enabling RDP access for local admin account:







Finding out what needs to be change was a pretty straightforward process - just upload your configuration and try to compile it. Azure should point you to exact parts that requires changing.

First we need to go to Automation Account and access "State Configuration (DSC)". Now we can start uploading Configuration Script.


Under "Name" you need to put the Name of your Configuration Script (second line of Configuration Script). In this case I've changed it to STIG (default Configuration Name is set to DSCFromGPO).


Now it's time co Compile our Configuration Script.




Before compiling configuration script first make sure all required PowerShell modules have been imported to Automation Account - GPRegistryPolicyDsc, AuditPolicyDSC, SecurityPolicyDSC. In case of any issues with your Configuration Script, Compilation job will change it status to "Suspended".


To review problematic pieces of code go inside of that Compilation job and review Exception tab.



After all of the issues are solved and configuration script has been successfully compiled you can deploy it on your VMs.




Initially you can see some errors but after a couple of minutes everything should be compliant.



Comments