Private/Collectors.SecurityConfiguration.ps1
|
function Get-ICSecurityConfigurationEvidence { [CmdletBinding()] param( [Parameter(Mandatory)] [object]$Context ) $warnings = New-Object System.Collections.ArrayList $files = New-Object System.Collections.ArrayList $firewallProfiles = @() if (Test-ICCommandAvailable -Name 'Get-NetFirewallProfile') { try { $firewallProfiles = @(Get-NetFirewallProfile -PolicyStore ActiveStore -ErrorAction Stop | ForEach-Object { [pscustomobject][ordered]@{ Name = $_.Name Enabled = $_.Enabled DefaultInboundAction = $_.DefaultInboundAction.ToString() DefaultOutboundAction = $_.DefaultOutboundAction.ToString() AllowInboundRules = $_.AllowInboundRules AllowLocalFirewallRules = $_.AllowLocalFirewallRules AllowLocalIPsecRules = $_.AllowLocalIPsecRules AllowUnicastResponseToMulticast = $_.AllowUnicastResponseToMulticast NotifyOnListen = $_.NotifyOnListen EnableStealthModeForIPsec = $_.EnableStealthModeForIPsec LogFileName = $_.LogFileName LogMaxSizeKilobytes = $_.LogMaxSizeKilobytes LogAllowed = $_.LogAllowed LogBlocked = $_.LogBlocked LogIgnored = Get-ICPropertyValue -InputObject $_ -Name 'LogIgnored' } }) } catch { Add-ICCollectorWarning -List $warnings -Message "Firewall profiles: $($_.Exception.Message)" } } else { Add-ICCollectorWarning -List $warnings -Message 'NetSecurity firewall cmdlets are unavailable.' } Add-ICOutputFiles -List $files -Path (Export-ICCollectorData -Context $Context -Collector SecurityConfiguration -RelativePath 'evidence/security/firewall-profiles.json' -Data $firewallProfiles -Csv) $firewallRules = @() $firewallRuleTotal = $null if (Test-ICCommandAvailable -Name 'Get-NetFirewallRule') { try { $maximumFirewallRules = [int]$Context.Configuration.MaximumFirewallRules $boundedRules = @(Get-NetFirewallRule -PolicyStore ActiveStore -ErrorAction Stop | Select-Object -First ($maximumFirewallRules + 1)) $firewallRules = @($boundedRules | Select-Object -First $maximumFirewallRules | ForEach-Object { [pscustomobject][ordered]@{ Name = $_.Name DisplayName = $_.DisplayName Description = $_.Description DisplayGroup = $_.DisplayGroup Group = $_.Group Enabled = $_.Enabled.ToString() Profile = $_.Profile.ToString() Platform = @($_.Platform) Direction = $_.Direction.ToString() Action = $_.Action.ToString() EdgeTraversalPolicy = $_.EdgeTraversalPolicy.ToString() LooseSourceMapping = $_.LooseSourceMapping LocalOnlyMapping = $_.LocalOnlyMapping Owner = $_.Owner PrimaryStatus = $_.PrimaryStatus.ToString() Status = $_.Status.ToString() EnforcementStatus = $_.EnforcementStatus.ToString() PolicyStoreSource = $_.PolicyStoreSource PolicyStoreSourceType = $_.PolicyStoreSourceType.ToString() } }) $firewallRuleTotal = $firewallRules.Count if ($boundedRules.Count -gt $firewallRules.Count) { $firewallRuleTotal = $null Add-ICCollectorWarning -List $warnings -Message "Firewall-rule export reached the configured limit of $($firewallRules.Count) rules; additional rules exist." } } catch { Add-ICCollectorWarning -List $warnings -Message "Firewall rules: $($_.Exception.Message)" } } Add-ICOutputFiles -List $files -Path (Export-ICCollectorData -Context $Context -Collector SecurityConfiguration -RelativePath 'evidence/security/firewall-rules.json' -Data $firewallRules -Csv) $securityRegistry = @(Get-ICRegistryValues -Path @( 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System', 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server', 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp', 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa', 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest', 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters', 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters' ) -ValueName @( 'EnableLUA', 'ConsentPromptBehaviorAdmin', 'PromptOnSecureDesktop', 'FilterAdministratorToken', 'LocalAccountTokenFilterPolicy', 'fDenyTSConnections', 'UserAuthentication', 'SecurityLayer', 'MinEncryptionLevel', 'LmCompatibilityLevel', 'RunAsPPL', 'DisableDomainCreds', 'NoLMHash', 'RestrictAnonymous', 'RestrictAnonymousSAM', 'UseLogonCredential', 'RequireSecuritySignature', 'EnableSecuritySignature', 'EnablePlainTextPassword' )) Add-ICOutputFiles -List $files -Path (Export-ICCollectorData -Context $Context -Collector SecurityConfiguration -RelativePath 'evidence/security/uac-rdp-lsa.json' -Data $securityRegistry -Csv) $deviceGuard = @() try { $deviceGuard = @(Get-CimInstance -Namespace 'root/Microsoft/Windows/DeviceGuard' -ClassName Win32_DeviceGuard -ErrorAction Stop | ForEach-Object { [pscustomobject][ordered]@{ AvailableSecurityProperties = @($_.AvailableSecurityProperties) CodeIntegrityPolicyEnforcementStatus = $_.CodeIntegrityPolicyEnforcementStatus InstanceIdentifier = $_.InstanceIdentifier RequiredSecurityProperties = @($_.RequiredSecurityProperties) SecurityFeaturesEnabled = @($_.SecurityFeaturesEnabled) SecurityServicesConfigured = @($_.SecurityServicesConfigured) SecurityServicesRunning = @($_.SecurityServicesRunning) UsermodeCodeIntegrityPolicyEnforcementStatus = $_.UsermodeCodeIntegrityPolicyEnforcementStatus Version = $_.Version VirtualizationBasedSecurityStatus = $_.VirtualizationBasedSecurityStatus } }) } catch { Add-ICCollectorWarning -List $warnings -Message "Device Guard status: $($_.Exception.Message)" } Add-ICOutputFiles -List $files -Path (Export-ICCollectorData -Context $Context -Collector SecurityConfiguration -RelativePath 'evidence/security/device-guard.json' -Data $deviceGuard) $auditPol = Export-ICNativeCommandOutput -Context $Context -RelativePath 'evidence/security/audit-policy.txt' -FilePath (Get-ICSystemExecutable -Name 'auditpol.exe') -ArgumentList @('/get', '/category:*', '/r') [void]$files.Add($auditPol.Path) if ($null -ne $auditPol.Error -or ($null -ne $auditPol.ExitCode -and $auditPol.ExitCode -ne 0)) { Add-ICCollectorWarning -List $warnings -Message 'auditpol export failed; inspect evidence/security/audit-policy.txt.' } $netsh = Export-ICNativeCommandOutput -Context $Context -RelativePath 'evidence/security/netsh-firewall-profiles.txt' -FilePath (Get-ICSystemExecutable -Name 'netsh.exe') -ArgumentList @('advfirewall', 'show', 'allprofiles') [void]$files.Add($netsh.Path) if ($null -ne $netsh.Error -or ($null -ne $netsh.ExitCode -and $netsh.ExitCode -ne 0)) { Add-ICCollectorWarning -List $warnings -Message 'netsh firewall profile export failed.' } $securityPolicyPath = Join-Path $Context.RootPath 'evidence/security/local-security-policy.inf' $secedit = Invoke-ICNativeCommand -FilePath (Get-ICSystemExecutable -Name 'secedit.exe') -ArgumentList @('/export', '/cfg', $securityPolicyPath, '/quiet') -Context $Context $seceditLogPath = Join-Path $Context.RootPath 'evidence/security/secedit-export.txt' [void](Write-ICUtf8File -Path $seceditLogPath -Content ((@( "# capturedAtUtc: $([datetime]::UtcNow.ToString('o'))", "# exitCode: $($secedit.ExitCode)", "# error: $($secedit.Error)", '' ) + @($secedit.Output)) -join [Environment]::NewLine)) [void]$files.Add($seceditLogPath) if (Test-Path -LiteralPath $securityPolicyPath -PathType Leaf) { [void]$files.Add($securityPolicyPath) } else { Add-ICCollectorWarning -List $warnings -Message 'Local security policy export was not created; elevation can be required.' } if (Test-ICCommandAvailable -Name 'Get-AppLockerPolicy') { try { $xml = Get-AppLockerPolicy -Effective -Xml -ErrorAction Stop $appLockerPath = Join-Path $Context.RootPath 'evidence/security/applocker-policy.xml' [void](Write-ICUtf8File -Path $appLockerPath -Content ([string]$xml)) [void]$files.Add($appLockerPath) } catch { Add-ICCollectorWarning -List $warnings -Message "AppLocker policy: $($_.Exception.Message)" } } return New-ICCollectorResultData -OutputFiles @($files) -Warnings @($warnings) -Metrics ([ordered]@{ FirewallProfiles = $firewallProfiles.Count EnabledFirewallProfiles = @($firewallProfiles | Where-Object Enabled -eq $true).Count FirewallRulesTotal = $firewallRuleTotal FirewallRulesExported = $firewallRules.Count DeviceGuardRecords = $deviceGuard.Count LocalSecurityPolicyExported = Test-Path -LiteralPath $securityPolicyPath -PathType Leaf }) } |