This repository has been archived by the owner on Oct 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 522
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Add windowssecuretls.ps1 (#4567)
* chore: Add windowssecuretls.ps1 * Update per comments * Remove comment
- Loading branch information
Showing
1 changed file
with
385 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,385 @@ | ||
#*************************************************************************************************************** | ||
# It does the following: | ||
# * Disable TLS 1.O, TLS 1.1, SSLv2, SSLv3 and enables TLS1.2 | ||
# * The CipherSuite order is set to the SDL approved version. | ||
# * The FIPS MinEncryptionLevel is set to 3. | ||
# * RC4 is disabled | ||
#*************************************************************************************************************** | ||
|
||
#******************* FUNCTION THAT ACTUALLY UPDATES KEYS *********************** | ||
function Set-CryptoSetting { | ||
param ( | ||
$regKeyName, | ||
$value, | ||
$valuedata, | ||
$valuetype | ||
) | ||
|
||
# Check for existence of registry key, and create if it does not exist | ||
If (!(Test-Path -Path $regKeyName)) { | ||
New-Item $regKeyName | Out-Null | ||
} | ||
|
||
# Get data of registry value, or null if it does not exist | ||
$val = (Get-ItemProperty -Path $regKeyName -Name $value -ErrorAction SilentlyContinue).$value | ||
|
||
|
||
If ($val -eq $null) { | ||
# Value does not exist - create and set to desired value | ||
New-ItemProperty -Path $regKeyName -Name $value -Value $valuedata -PropertyType $valuetype | Out-Null | ||
} | ||
Else { | ||
# Value does exist - if not equal to desired value, change it | ||
If ($val -ne $valuedata) { | ||
Set-ItemProperty -Path $regKeyName -Name $value -Value $valuedata | ||
} | ||
} | ||
} | ||
#*************************************************************************************************************** | ||
|
||
#******************* FUNCTION THAT DISABLES RC4 *********************** | ||
function DisableRC4 { | ||
$subkeys = Get-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL" | ||
$ciphers = $subkeys.OpenSubKey("Ciphers", $true) | ||
|
||
Write-Log "----- Checking the status of RC4 -----" | ||
|
||
$RC4 = $false | ||
if ($ciphers.SubKeyCount -eq 0) { | ||
$k1 = $ciphers.CreateSubKey("RC4 128/128") | ||
$k1.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord) | ||
$k2 = $ciphers.CreateSubKey("RC4 64/128") | ||
$k2.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord) | ||
$k3 = $ciphers.CreateSubKey("RC4 56/128") | ||
$k3.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord) | ||
$k4 = $ciphers.CreateSubKey("RC4 40/128") | ||
$k4.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord) | ||
|
||
Write-Log "RC4 was disabled " | ||
$RC4 = $true | ||
} | ||
|
||
If ($RC4 -ne $true) { | ||
Write-Log "There was no change for RC4 " | ||
} | ||
} | ||
#*************************************************************************************************************** | ||
|
||
#******************* FUNCTION CHECKS FOR PROBLEMATIC FIPS SETTING AND FIXES IT *********************** | ||
function Test-RegistryValueForFipsSettings { | ||
$fipsPath = @( | ||
"HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp", | ||
"HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services", | ||
"HKLM:\System\CurrentControlSet\Control\Terminal Server\DefaultUserConfiguration" | ||
) | ||
|
||
$fipsValue = "MinEncryptionLevel" | ||
|
||
foreach ($path in $fipsPath) { | ||
Write-Log "Checking to see if $($path)\$fipsValue exists" | ||
|
||
$ErrorActionPreference = "stop" | ||
Try { | ||
$result = Get-ItemProperty -Path $path | Select-Object -ExpandProperty $fipsValue | ||
if ($result -eq 4) { | ||
set-itemproperty -Path $path -Name $fipsValue -value 3 | ||
Write-Log "Regkey $($path)\$fipsValue was changed from value $result to a value of 3" | ||
} | ||
else { | ||
Write-Log "Regkey $($path)\$fipsValue left at value $result" | ||
} | ||
|
||
} | ||
Catch [System.Management.Automation.ItemNotFoundException] { | ||
Write-Log "Reg path $path was not found" | ||
} | ||
Catch [System.Management.Automation.PSArgumentException] { | ||
Write-Log "Regkey $($path)\$fipsValue was not found" | ||
} | ||
Catch { | ||
Write-Log "Error of type $($Error[0].Exception.GetType().FullName) trying to get $($path)\$fipsValue" | ||
} | ||
Finally { | ||
$ErrorActionPreference = "Continue" | ||
} | ||
} | ||
} | ||
#*************************************************************************************************************** | ||
|
||
#********************************TLS CipherSuite Settings ******************************************* | ||
|
||
# CipherSuites for windows OS < 10 | ||
function Get-BaseCipherSuitesOlderWindows() | ||
{ | ||
param | ||
( | ||
[Parameter(Mandatory=$true, Position=0)][bool] $isExcellenceOrder | ||
) | ||
$cipherorder = @() | ||
|
||
if ($isExcellenceOrder -eq $true) | ||
{ | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256" | ||
} | ||
else | ||
{ | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384" | ||
} | ||
|
||
# Add additional ciphers when EnableOlderTlsVersions flag is set to true | ||
if ($EnableOlderTlsVersions) | ||
{ | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" | ||
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384" | ||
$cipherorder += "TLS_RSA_WITH_AES_128_GCM_SHA256" | ||
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256" | ||
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256" | ||
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA" | ||
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA" | ||
} | ||
return $cipherorder | ||
} | ||
|
||
# Ciphersuites needed for backwards compatibility with Firefox, Chrome | ||
# Server 2012 R2 doesn't support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | ||
# Both firefox and chrome negotiate ECDHE_RSA_AES_256_CBC_SHA1, Edge negotiates ECDHE_RSA_AES_256_CBC_SHA384 | ||
function Get-BrowserCompatCipherSuitesOlderWindows() | ||
{ | ||
param | ||
( | ||
[Parameter(Mandatory=$true, Position=0)][bool] $isExcellenceOrder | ||
) | ||
$cipherorder = @() | ||
|
||
if ($isExcellenceOrder -eq $true) | ||
{ | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384" # (uses SHA-1) | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" # (uses SHA-1) | ||
} | ||
else | ||
{ | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" # (uses SHA-1) | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384" # (uses SHA-1) | ||
} | ||
return $cipherorder | ||
} | ||
|
||
# Ciphersuites for OS versions windows 10 and above | ||
function Get-BaseCipherSuitesWin10Above() | ||
{ | ||
param | ||
( | ||
[Parameter(Mandatory=$true, Position=0)][bool] $isExcellenceOrder | ||
) | ||
|
||
$cipherorder = @() | ||
if ($isExcellenceOrder -eq $true) | ||
{ | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" | ||
} | ||
else | ||
{ | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" | ||
} | ||
# Add additional ciphers when EnableOlderTlsVersions flag is set to true | ||
if ($EnableOlderTlsVersions) | ||
{ | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256" | ||
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256" | ||
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" | ||
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384" | ||
$cipherorder += "TLS_RSA_WITH_AES_128_GCM_SHA256" | ||
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256" | ||
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256" | ||
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA" | ||
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA" | ||
} | ||
|
||
return $cipherorder | ||
} | ||
|
||
#******************************* TLS Version Settings **************************************************** | ||
|
||
function Get-RegKeyPathForTls12() | ||
{ | ||
$regKeyPath = @( | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" | ||
) | ||
return $regKeyPath | ||
} | ||
|
||
function Get-RegKeyPathForTls11() | ||
{ | ||
$regKeyPath = @( | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" | ||
) | ||
return $regKeyPath | ||
} | ||
|
||
function Get-RegKeypathForTls10() | ||
{ | ||
$regKeyPath = @( | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" | ||
) | ||
return $regKeyPath | ||
} | ||
|
||
function Get-RegKeyPathForSsl30() | ||
{ | ||
$regKeyPath = @( | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" | ||
) | ||
return $regKeyPath | ||
} | ||
|
||
function Get-RegKeyPathForSsl20() | ||
{ | ||
$regKeyPath = @( | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client", | ||
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" | ||
) | ||
return $regKeyPath | ||
} | ||
|
||
#******************************* Wrap TLSSettings.ps1 to a function without restart ********************** | ||
|
||
function Enable-SecureTls { | ||
$registryPathGoodGuys = @() | ||
$registryPathBadGuys = @() | ||
|
||
Write-Log -Message "========== Start of logging for Enable-SecureTls ==========" | ||
# we enable TLS 1.2 and disable others | ||
$registryPathGoodGuys += Get-RegKeyPathForTls12 | ||
|
||
$registryPathBadGuys += Get-RegKeyPathForSsl20 | ||
$registryPathBadGuys += Get-RegKeyPathForSsl30 | ||
$registryPathBadGuys += Get-RegKeypathForTls10 | ||
$registryPathBadGuys += Get-RegKeyPathForTls11 | ||
Write-Log "Enabling TLS1.2. Disabling TLS1.1, TLS1.0, SSL3.0, SSL2.0" | ||
|
||
Write-Log "Check which registry keys exist already and which registry keys need to be created." | ||
|
||
#******************* CREATE THE REGISTRY KEYS IF THEY DON'T EXIST******************************** | ||
# Check for existence of GoodGuy registry keys, and create if they do not exist | ||
For ($i = 0; $i -lt $registryPathGoodGuys.Length; $i = $i + 1) { | ||
Write-Log "Checking for existing of key: $($registryPathGoodGuys[$i]) " | ||
If (!(Test-Path -Path $registryPathGoodGuys[$i])) { | ||
New-Item $registryPathGoodGuys[$i] | Out-Null | ||
Write-Log "Creating key: $($registryPathGoodGuys[$i]) " | ||
} | ||
} | ||
|
||
# Check for existence of BadGuy registry keys, and create if they do not exist | ||
For ($i = 0; $i -lt $registryPathBadGuys.Length; $i = $i + 1) { | ||
Write-Log "Checking for existing of key: $($registryPathBadGuys[$i]) " | ||
If (!(Test-Path -Path $registryPathBadGuys[$i])) { | ||
Write-Log "Creating key: $($registryPathBadGuys[$i]) " | ||
New-Item $registryPathBadGuys[$i] | Out-Null | ||
} | ||
} | ||
|
||
#******************* EXPLICITLY DISABLE SSLV2, SSLV3, TLS10 AND TLS11 ******************************** | ||
For ($i = 0; $i -lt $registryPathBadGuys.Length; $i = $i + 1) { | ||
if ($registryPathBadGuys[$i].Contains("Client") -Or $registryPathBadGuys[$i].Contains("Server")) { | ||
Write-Log "Disabling this key: $($registryPathBadGuys[$i]) " | ||
Set-CryptoSetting $registryPathBadGuys[$i].ToString() Enabled 0 DWord | ||
Set-CryptoSetting $registryPathBadGuys[$i].ToString() DisabledByDefault 1 DWord | ||
} | ||
} | ||
|
||
#********************************* EXPLICITLY Enable TLS12 **************************************** | ||
For ($i = 0; $i -lt $registryPathGoodGuys.Length; $i = $i + 1) { | ||
if ($registryPathGoodGuys[$i].Contains("Client") -Or $registryPathGoodGuys[$i].Contains("Server")) { | ||
Write-Log "Enabling this key: $($registryPathGoodGuys[$i]) " | ||
Set-CryptoSetting $registryPathGoodGuys[$i].ToString() Enabled 1 DWord | ||
Set-CryptoSetting $registryPathGoodGuys[$i].ToString() DisabledByDefault 0 DWord | ||
} | ||
} | ||
|
||
#************************************** Disable RC4 ************************************************ | ||
DisableRC4 | ||
|
||
#************************************** Set Cipher Suite Order ************************************** | ||
Write-Log "----- starting ciphersuite order calculation for excellence cipher suite order -----" | ||
$cipherlist = @() | ||
|
||
if ([Environment]::OSVersion.Version.Major -lt 10) | ||
{ | ||
$cipherlist += Get-BaseCipherSuitesOlderWindows -isExcellenceOrder $true | ||
$cipherlist += Get-BrowserCompatCipherSuitesOlderWindows -isExcellenceOrder $true | ||
} | ||
else | ||
{ | ||
$cipherlist += Get-BaseCipherSuitesWin10Above -isExcellenceOrder $true | ||
} | ||
$cipherorder = [System.String]::Join(",", $cipherlist) | ||
Write-Log "Appropriate ciphersuite order : $cipherorder" | ||
|
||
$CipherSuiteRegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" | ||
|
||
if (!(Test-Path -Path $CipherSuiteRegKey)) | ||
{ | ||
New-Item $CipherSuiteRegKey | Out-Null | ||
Write-Log "Creating key: $($CipherSuiteRegKey) " | ||
} | ||
|
||
$val = (Get-Item -Path $CipherSuiteRegKey -ErrorAction SilentlyContinue).GetValue("Functions", $null) | ||
Write-Log "Previous cipher suite value: $val " | ||
Write-Log "New cipher suite value : $cipherorder " | ||
|
||
if ($val -ne $cipherorder) | ||
{ | ||
Write-Log "Cipher suite order needs to be updated. " | ||
Set-ItemProperty -Path $CipherSuiteRegKey -Name Functions -Value $cipherorder | ||
Write-Log "Cipher suite value was updated. " | ||
} | ||
else | ||
{ | ||
Write-Log "Cipher suite order does not need to be updated. " | ||
Write-Log "Cipher suite value was not updated as there was no change. " | ||
} | ||
|
||
#****************************** CHECK THE FIPS SETTING WHICH IMPACTS RDP'S ALLOWED CIPHERS ************************** | ||
#Check for FipsSettings | ||
Write-Log "Checking to see if reg keys exist and if MinEncryptionLevel is set to 4" | ||
Test-RegistryValueForFipsSettings | ||
|
||
Write-Log -Message "========== End of logging for Enable-SecureTls ==========" | ||
} |