diff --git a/CYBRHardeningCheck/Hardening_HealthCheck_Report.html b/CYBRHardeningCheck/Hardening_HealthCheck_Report.html
index a7bc8f3..b4e0698 100644
--- a/CYBRHardeningCheck/Hardening_HealthCheck_Report.html
+++ b/CYBRHardeningCheck/Hardening_HealthCheck_Report.html
@@ -704,6 +704,11 @@
content:"\f057";
}
+details summary.Ignore:before,details ul li div.Ignore:before {
+color:#D3D3D3;
+content:"\f05e";
+}
+
@keyframes sweep {
0% {
margin-left:-1em;
diff --git a/CYBRHardeningCheck/Main.ps1 b/CYBRHardeningCheck/Main.ps1
index d1f1caa..d53a3f2 100644
--- a/CYBRHardeningCheck/Main.ps1
+++ b/CYBRHardeningCheck/Main.ps1
@@ -24,7 +24,7 @@ $global:InDebug = $PSBoundParameters.Debug.IsPresent
$global:InVerbose = $PSBoundParameters.Verbose.IsPresent
# Script Version
-$ScriptVersion = "3.0"
+$ScriptVersion = "3.1"
# Set Log file path
$global:LOG_FILE_PATH = "$ScriptLocation\Hardening_HealthCheck.log"
@@ -159,12 +159,12 @@ param(
$Item.Output = $(Get-SummaryOutput -Component $Item.Component -Status $Item.Status -Details $Item.Output)
}
# Count Errors
- If($item.Status -ne "Good")
+ If($item.Status -ne "Good" -and $item.Status -ne "Ignore")
{
$summary.errors++
}
}
- $summary.hardeningPercentage = ($summary.errors / $sortedHardeningStatus.count)
+ $summary.hardeningPercentage = 1-($summary.errors / @($sortedHardeningStatus | Where-Object { $_.Status -ne "Ignore" }).count)
# return the Hardening setup and the Summary
return @( $sortedHardeningStatus, $summary )
@@ -406,12 +406,20 @@ Function Out-HardeningFolderPath {
# Start a background job to search all InstallationAutomation folders and limit it to the maximum number of Total Components found
# Might want to add in the future filter on the actual components folder names (e.g. "CPM|PVWA|PSM|AIM")
Start-Job -Name FileCollection -ScriptBlock {Get-ChildItem -Path "$ENV:SystemDrive\*" -Include "InstallationAutomation" -Recurse -Directory -ErrorAction SilentlyContinue | Select-Object -First $args[0] } -ArgumentList $TotalComponentsFound | Out-Null
- While((Get-Job -Name FileCollection).State -eq "Running")
+
+ # set a timeout of max 2 minutes
+ $timeout = [TimeSpan]::FromMinutes(2)
+ While((Get-Job -Name FileCollection | Where-Object { $_.State -eq "Running" -and (($now - $_.PSBeginTime) -lt $timeout)} ))
{
Write-Progress -Activity "Searching for Hardening folders..." -PercentComplete $x
- If($x -eq 100){ $x = 1 } Else { $x += 1 }
- }
+ If($x -eq 100){ $x = 1 } Else { $x += 1 }
+ }
Write-Progress -Activity "Searching for Hardening folders..." -Completed
+ if((Get-Job -Name FileCollection).State -ne "Completed" -and $x -lt 100)
+ {
+ Write-LogMessage -type "Warning" -Msg "Timeout reached - canceling search"
+ Get-Job -Name FileCollection | Stop-Job
+ }
$allFolders = Receive-Job -Name FileCollection -AutoRemoveJob -Wait
Write-LogMessage -Type Debug -Msg "Found $($allFolders.FullName.Count) folders named 'InstallationAutomation'"
If($allFolders.FullName.Count -gt 1)
@@ -453,7 +461,10 @@ If($ExecutionContext.SessionState.LanguageMode -ne "FullLanguage")
}
Write-LogMessage -Type Info -MSG "Starting script (v$ScriptVersion)" -Header -LogFile $LOG_FILE_PATH
-if($InDebug) { Write-LogMessage -Type Info -MSG "Running in Debug Mode" -LogFile $LOG_FILE_PATH }
+if($InDebug) {
+ Write-LogMessage -Type Info -MSG "Running in Debug Mode, not stopping for debug messages" -LogFile $LOG_FILE_PATH
+ $DebugPreference = "Continue"
+}
if($InVerbose) { Write-LogMessage -Type Info -MSG "Running in Verbose Mode" -LogFile $LOG_FILE_PATH }
Write-LogMessage -Type Debug -MSG "Running PowerShell version $($PSVersionTable.PSVersion.Major) compatible of versions $($PSVersionTable.PSCompatibleVersions -join ", ")" -LogFile $LOG_FILE_PATH
# Verify the Powershell version is compatible
diff --git a/CYBRHardeningCheck/PVWA/PVWAHardeningSteps.psm1 b/CYBRHardeningCheck/PVWA/PVWAHardeningSteps.psm1
index 807174f..48cf454 100644
--- a/CYBRHardeningCheck/PVWA/PVWAHardeningSteps.psm1
+++ b/CYBRHardeningCheck/PVWA/PVWAHardeningSteps.psm1
@@ -74,7 +74,7 @@ Function PVWA_IIS_Registry_Shares
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not verify PVWA IIS Registry Shares. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not verify PVWA IIS Registry Shares. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not verify PVWA IIS Registry Shares."
return "Bad"
}
@@ -126,7 +126,7 @@ Function PVWA_IIS_WebDAV
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not verify if Web DAV Publishing is installed. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not verify if Web DAV Publishing is installed. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not verify if Web DAV Publishing is installed."
return "Bad"
}
@@ -166,7 +166,7 @@ Function PVWA_Cryptography_Settings
$res = "Good"
$iisPath = "iis:\Sites\Default Web Site\PasswordVault"
$filter = "/appSettings/add[@key='AdvancedFIPSCryptography']"
- $value = "yes"
+ $value = "value.value"
}
Process {
try{
@@ -177,16 +177,21 @@ Function PVWA_Cryptography_Settings
$currentValue = Get-WebConfigurationProperty -PSPath $iisPath -filter $filter -name $value
if($null -ne $currentValue)
{
- if($currentValue.ToLower() -ne $value)
+ if($currentValue.ToLower() -ne 'yes')
{
$res = "Warning"
- [ref]$refOutput.Value = "AdvancedFIPSCryptography is not properly set in PVWA Configuration. Current value: $currentValue"
+ [ref]$refOutput.Value = "AdvancedFIPSCryptography is set but does not have the correct value configured. Current value is: $currentValue"
+ }
+ else
+ {
+ $res = "Good"
+ [ref]$refOutput.Value = "AdvancedFIPSCryptography is set and has the correct value of 'yes'"
}
}
else
{
$res = "Warning"
- [ref]$refOutput.Value = "AdvancedFIPSCryptography is not set in PVWA Configuration"
+ [ref]$refOutput.Value = "AdvancedFIPSCryptography key has not been set at the 'PasswordVault' level"
}
Write-LogMessage -Type Info -Msg "Finish verify if Web DAV Publishing is installed"
@@ -194,7 +199,7 @@ Function PVWA_Cryptography_Settings
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not verify PVWA Cryptography Mode Settings. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not verify PVWA Cryptography Mode Settings. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not verify PVWA Cryptography Mode Settings."
return "Bad"
}
@@ -252,7 +257,7 @@ Function PVWA_IIS_MimeTypes
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not verify allowed mime types. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not verify allowed mime types. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not verify allowed mime types."
return "Bad"
}
@@ -310,7 +315,7 @@ Function PVWA_AnonymousAuthentication
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not verify Anonymous Authentication in application pools. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not verify Anonymous Authentication in application pools. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not verify Anonymous Authentication in application pools."
return "Bad"
}
@@ -368,7 +373,7 @@ Function PVWA_DirectoryBrowsing
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not verify Directory Browsing. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not verify Directory Browsing. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not verify Directory Browsing."
return "Bad"
}
@@ -532,7 +537,7 @@ Function PVWA_IIS_SSL_TLS_Settings
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not validate hardening machine use only TLS 1.2. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate hardening machine use only TLS 1.2. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate hardening machine use only TLS 1.2."
return "Bad"
}
@@ -625,7 +630,7 @@ Function PVWA_IIS_Cypher_Suites
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not validate Cypher Suites. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate Cypher Suites. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate Cypher Suites."
return "Bad"
}
@@ -749,7 +754,7 @@ Function PVWA_Scheduled_Task_Service_LocalUser
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not validate Scheduled Task Service configuration. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate Scheduled Task Service configuration. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate Scheduled Task Service configuration."
return "Bad"
}
@@ -859,7 +864,7 @@ Function PVWA_NonSystemDrive
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not validate PVWA is not installed on the system drive. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate PVWA is not installed on the system drive. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate PVWA is not installed on the system drive."
return "Bad"
}
@@ -943,7 +948,7 @@ Function PVWA_IIS_Hardening
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not validate PVWA IIS hardening configuration. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate PVWA IIS hardening configuration. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate PVWA IIS hardening configuration."
return "Bad"
}
@@ -1016,7 +1021,7 @@ Function PVWA_AdditionalAppPool
return $res
}
catch{
- Write-LogMessage -Type "Error" -Msg "Could not validate PVWA application pool settings. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate PVWA application pool settings. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate PVWA application pool settings."
return "Bad"
}
@@ -1076,7 +1081,7 @@ Function PVWA_CredFileHardening
Write-LogMessage -Type Info -Msg "Finish validating PVWA component credential file"
return $res
} catch {
- Write-LogMessage -Type "Error" -Msg "Could not validate the PVWA component credential file. Error: $(Join-ExceptionMessage $_.Exception)"
+ Write-LogMessage -Type "Error" -Msg "Could not validate the PVWA component credential file. Error: $(Join-ExceptionMessage $_.Exception)"
[ref]$refOutput.Value = "Could not validate PVWA component credential file."
return "Bad"
}
diff --git a/CYBRHardeningCheck/Vault/VaultHardeningSteps.psm1 b/CYBRHardeningCheck/Vault/VaultHardeningSteps.psm1
index d1e0490..030edb3 100644
--- a/CYBRHardeningCheck/Vault/VaultHardeningSteps.psm1
+++ b/CYBRHardeningCheck/Vault/VaultHardeningSteps.psm1
@@ -689,6 +689,7 @@ Function Vault_KeysProtection
$KeysFolderLocalAdmins = $KeysFolderLocalSystem = $true
foreach ($path in $KeysLocations)
{
+ $path = '"'+$path+'"'
Write-LogMessage -Type Verbose -Msg "Checking '$path' permissions..."
if ((Compare-UserPermissions -path $path -identity $(Get-LocalAdministrators) -rights "FullControl" -outStatus ([ref]$myRef)) -ne "Good")
{
@@ -738,4 +739,4 @@ Function Vault_KeysProtection
{
# Write output to HTML
}
-}
\ No newline at end of file
+}
diff --git a/CYBRHardeningCheck/bin/CommonUtil.psd1 b/CYBRHardeningCheck/bin/CommonUtil.psd1
index 1f4adba..5233ddc 100644
Binary files a/CYBRHardeningCheck/bin/CommonUtil.psd1 and b/CYBRHardeningCheck/bin/CommonUtil.psd1 differ
diff --git a/CYBRHardeningCheck/bin/CommonUtil.psm1 b/CYBRHardeningCheck/bin/CommonUtil.psm1
index bcb787b..3197830 100644
--- a/CYBRHardeningCheck/bin/CommonUtil.psm1
+++ b/CYBRHardeningCheck/bin/CommonUtil.psm1
@@ -1220,22 +1220,32 @@ Function Get-ServiceInstallPath
.PARAMETER ServiceName
The service name to query. Just one.
#>
- param ($ServiceName)
+ param (
+ [Parameter(Mandatory=$true)]
+ [String]$ServiceName
+ )
Begin {
}
Process {
$retInstallPath = $Null
try{
- if ($null -eq $m_ServiceList)
+ # Search only if user is an admin (will always fail otherwise)
+ if(Test-CurrentUserLocalAdmin)
{
- Set-Variable -Name m_ServiceList -Value $(Get-ChildItem "HKLM:\System\CurrentControlSet\Services" | ForEach-Object { Get-ItemProperty $_.PSPath }) -Scope Script
- #$m_ServiceList = Get-Reg -Hive "LocalMachine" -Key System\CurrentControlSet\Services -Value $null
+ if ($null -eq $m_ServiceList)
+ {
+ Set-Variable -Name m_ServiceList -Value $(Get-ChildItem "HKLM:\System\CurrentControlSet\Services" | ForEach-Object { Get-ItemProperty $_.PSPath }) -Scope Script
+ }
+ $regPath = $m_ServiceList | Where-Object {$_.PSChildName -eq $ServiceName}
+ If ($Null -ne $regPath)
+ {
+ $retInstallPath = $regPath.ImagePath.Substring($regPath.ImagePath.IndexOf('"'),$regPath.ImagePath.LastIndexOf('"')+1)
+ }
}
- $regPath = $m_ServiceList | Where-Object {$_.PSChildName -eq $ServiceName}
- If ($Null -ne $regPath)
+ else
{
- $retInstallPath = $regPath.ImagePath.Substring($regPath.ImagePath.IndexOf('"'),$regPath.ImagePath.LastIndexOf('"')+1)
+ Write-LogMessage -Type "Warning" -Msg "Skipping Service install path check as user is not a local admin"
}
}
catch{
@@ -2555,9 +2565,9 @@ Function Start-HardeningSteps
if ($(ConvertTo-Bool $step.Enable) -eq $False)
{
Write-LogMessage -Type Debug -Msg "Step $($step.Name) is disabled"
- $refHardeningStepStatus.Status = "Bad"
+ $refHardeningStepStatus.Status = "Ignore"
$refHardeningStepStatus.Output = "Step is disabled, verification was not performed"
- $AllStepsArray += New-Object PSObject -Property @{Name=$step.Name;CompletedSuccessfully=$false}
+ $AllStepsArray += New-Object PSObject -Property @{Name=$step.Name;CompletedSuccessfully=$true}
}
else
{
@@ -2586,7 +2596,6 @@ Function Start-HardeningSteps
Write-LogMessage -Type Info -Msg "Finished Step $($step.DisplayName)"
}
# Add to steps array
- #Write-LogMessage -Type Debug -Msg "$($refHardeningStepStatus.Name) ($($refHardeningStepStatus.Status)): $($refHardeningStepStatus.Output)"
Write-LogMessage -Type Debug -Msg "$($refHardeningStepStatus.Name) ($($refHardeningStepStatus.Status))"
$AllHardeningStepsStatus += $refHardeningStepStatus
}
diff --git a/CYBRHardeningCheck/bin/GeneralHardeningSteps.psd1 b/CYBRHardeningCheck/bin/GeneralHardeningSteps.psd1
index 7494579..f88271e 100644
Binary files a/CYBRHardeningCheck/bin/GeneralHardeningSteps.psd1 and b/CYBRHardeningCheck/bin/GeneralHardeningSteps.psd1 differ
diff --git a/CYBRHardeningCheck/bin/GeneralHardeningSteps.psm1 b/CYBRHardeningCheck/bin/GeneralHardeningSteps.psm1
index e5c1855..b9aed86 100644
--- a/CYBRHardeningCheck/bin/GeneralHardeningSteps.psm1
+++ b/CYBRHardeningCheck/bin/GeneralHardeningSteps.psm1
@@ -58,7 +58,7 @@ Function ImportingINFConfiguration
# Get the Component relative INF file path
$INFconfigFilePath = Get-CurrentComponentFolderPath -FileName $INFconfigFileName
- if(!Test-Path $INFconfigFilePath)
+ if(!(Test-Path $INFconfigFilePath))
{
# INF Configuration was not found
Throw "Could not find configuration file in path: $INFconfigFilePath"
@@ -415,14 +415,29 @@ Function RemoteDesktopServices
$UserDir = "$($env:WinDir)\system32\GroupPolicy\User\registry.pol"
$RegPath = "Software\Policies\Microsoft\Windows NT\Terminal Services"
+
+ # init variables
+ $regShadowData = $reMaxIdleTimeData = 0
+ # Checking for cases where PSM is installed vs. CPM/PVWA are installed
+ If($(Get-DetectedComponents).Name -contains "PSM")
+ {
+ # Set values according to PSM hardening
+ $regShadowData = '4'
+ $reMaxIdleTimeData = '1800000'
+ }
+ else {
+ # Set values according to general CPM/PVWA hardening
+ $regShadowData = '0'
+ $reMaxIdleTimeData = '1'
+ }
- if((Compare-PolicyEntry -EntryTitle "Set rules for remote control of Remote Desktop Services user sessions" -UserDir $UserDir -RegPath $RegPath -RegName 'Shadow' -RegData '4' -outStatus ([ref]$myRef)) -ne "Good")
+ if((Compare-PolicyEntry -EntryTitle "Set rules for remote control of Remote Desktop Services user sessions" -UserDir $UserDir -RegPath $RegPath -RegName 'Shadow' -RegData $regShadowData -outStatus ([ref]$myRef)) -ne "Good")
{
$tmpStatus += $myRef.Value + "
"
$statusChanged = $true
}
- if((Compare-PolicyEntry -EntryTitle "Set time limit for active but idle Remote Desktop Services sessions" -UserDir $UserDir -RegPath $RegPath -RegName 'MaxIdleTime' -RegData '1800000' -outStatus ([ref]$myRef)) -ne "Good")
+ if((Compare-PolicyEntry -EntryTitle "Set time limit for active but idle Remote Desktop Services sessions" -UserDir $UserDir -RegPath $RegPath -RegName 'MaxIdleTime' -RegData $reMaxIdleTimeData -outStatus ([ref]$myRef)) -ne "Good")
{
$tmpStatus += $myRef.Value + "
"
$statusChanged = $true