Hardening Windows 2016 with Powershell

In this post I will outline few details around development and deployment of the powershell script developed to automate the hardening of a Windows 2016 machine. It should work equally well for Windows 2012, but 2012 was never tested. The whole procedure is simple in its approach - the script modifies a number of local policy attributes. It does that by either adjusting the corresponding registry key for a value or modifies the policy attribute directly.
Few assumptions before you run the script are given in a script header, but I will outline them here just to add clarity.
First of all, the script should be run from the powershell console opened with administrative privileges. Another thing to bear in mind is either the internet access to PSGallery, a powershell repository that contains a number of scripts, modules etc. If your server does not have an online accessibility, you can still download the PSGallery locally to the machine. Below is the comment I inserted into the script header.

# 2. Server needs access to powershell gallery (PSGallery)- if not online, make sure you copy PSGallery locally
# https://microsoft.github.io/DSCEA/mydoc_psgallery_download.html
#============================================================

Also, you will need to install several modules manually - this one is an ugly solution, I know, but embedding those instructions into the powershell script simply does not work.

I came across some posts that say you'd need to separate the code that loads the modules from the rest of script, but it would create two files/scripts which is not the route I was ready to take. Therefore, I added comments into the script header.

# 3. Need to manually install those modules before the script executes. Embedding these commands into the script does not do the job.
#
# find-module -name NetworkingDsc -Repository PSGallery | Install-module -Force
# find-module -name AuditPolicyDsc -Repository PSGallery | Install-module -Force
# find-module -name SecurityPolicyDsc -Repository PSGallery | Install-module -Force

Next step was ensuring that the script will be able to execute. Note that powershell in Windows 2016 comes with the default execution policy set to 'restricted'. This means your script will not run out-of-the-box. So, you will need to set execution policy to 'unrestricted' temporarily.

# 4. The end of the script returns PowerShell into the 'Restricted' mode.
# Therefore, any subsequent execution of the powershell script will be prohibited.
# You will need to manually re-enable the powershell execution by :
# Set-ExecutionPolicy unrestricted

I remind you again, you need to run this command with administrative privileges, otherwise it will fail.
One more issue I came across at certain point was where Windows was complaining that I am messing around with Public interface of a firewall (I believe it was when I tried to disable the Windows firewall). This is how you remediate this complaint - simply "skipnetworkprofilecheck" as below.
As a side note for those who use intercepting proxy to inspect what the underlying powershell cmdlets are doing. Numerous methods found googling did not help me. At the end, I came across Fiddler proxy that did the job, being able to intercept requests from applications other than browsers.
So, option A was defining the system wide proxy:

netsh winhttp set proxy <ip>:<port> 

That did now work for me, not sure if this setting is supposed to work with IE only or is it really systemwide (meaning that other applications should proxy their traffic too).

Option B was trying to use embedded proxy flag (-Proxy <proxy>) for Powershell cmdlets:
As you can see, it did not work. According to the warning, some DNS problem, however both proxy and source machine had DNS working flawlessly.

Option C was using Fiddler proxy which supports interception of HTTP(s) traffic from any process.

The whole script is available at 

WARNING: There seems to be one undesired consequence of the hardening as per the script above. When you try to "Add Roles" in the Server Manager, the following error is displayed (at least when the new role is DNS server)
WinRM missing or corrupted plugin can be identified in the Group policy editor. Make sure to set it to "Enabled" or alternatively , change the script snippet as described below.
And finally, this is the script snippet responsible for the error.
Make sure to edit $value to "1" instead of "0". That should do the work.

Comments

Popular posts from this blog

Signature verification bypass vulnerability in some Huawei routers

Attacking encrypted VOIP (SIP) protocols

DNS insights - UDP vs TCP and EDNS