Public/Test-SecurityState.ps1
#Requires -Version 5.1 #Requires -PSEdition Core, Desktop #Requires -Modules @{ ModuleName="PKI"; ModuleVersion="1.0.0.0" } using module PKI using namespace System.Security.Cryptography.X509Certificates [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 class SicherheitInfoCheck { [int] $Id [string] $Status [string] $Kategorie [string] $Test [Object] $IST [Object] $SOLL SicherheitInfoCheck([int]$Id, [string]$Status, [string]$Kategorie, [string]$Test, [Object]$IST, [Object]$SOLL) { $this.Id = $Id $this.Status = $Status $this.Kategorie = $Kategorie $this.Test = $Test $this.IST = $IST $this.SOLL = $SOLL } } function IstZertifikatExportierbar { param([X509Certificate2]$Cert) try { $Cert.Export(([X509ContentType]::Pfx)) | Out-Null return $true } catch { return $false } } function Test-SecurityState { <# .SYNOPSIS Analysiert das aktuelle System auch Sicherheitsschwachstellen in Verbindung mit PowerShell. .OUTPUTS Analyseergebnis wird per [SicherheitInfoCheck]-Objekt zurückgegeben. Erklärende Informationen erhältst Du per -Verbose-Meldung .EXAMPLE Test-SecurityState .EXAMPLE Test-SecurityState -Verbose .EXAMPLE Test-SecurityState -SkipModuleVersionTest -Verbose .EXAMPLE Test-SecurityState -SkipAlternateDataStreamTest -Verbose .EXAMPLE Test-SecurityState -SkipModuleVersionTest -SkipAlternateDataStreamTest -Verbose #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingEmptyCatchBlock','')] [CmdletBinding()] param( # Überspringt die zeitaufwändige Modul-Versions-Test zu der eine Internet-Verbindung bestehen muss. [switch]$SkipModuleVersionTest, # Überspringt die zeitaufwändige Alternate-Data-Stream-Test. [switch]$SkipAlternateDataStreamTest ) $My = [HashTable]::Synchronized(@{}) $My.ESC = [char]0x1b $My.Status = $null $My.Result = $null $My.TargetResult = $null $My.Id = 1 $My.Neutral = "Neutral" $My.Passed = "$($My.ESC)[92mBestanden$($My.ESC)[0m" $My.Failed = "$($My.ESC)[91mDurchgefallen$($My.ESC)[0m" $My.Skip = "$($My.ESC)[95mÜbersprungen$($My.ESC)[0m" $my.IsAdminRights = (New-Object -TypeName Security.Principal.WindowsPrincipal -ArgumentLIST ([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::AdminISTrator) #region Allgemein [SicherheitInfoCheck]::new($My.Id++, $My.Neutral, 'Allgemein', 'PSEdition', $PSVersionTable.PSEdition, '') "Zu $($My.Id - 1)) Weitere Details siehe about_PowerShell_Editions" | Write-Verbose if ($PSVersionTable.PSVersion -le [Version]"2.0.0.0") { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++ , $My.Status, 'Allgemein', 'PSVersion', $PSVersionTable.PSVersion, '-gt 2.0') "Zu $($My.Id - 1)) Schutzmechaniken können in Windows PowerShell 2.0 umgangen werden, daher diese Versionen unter Windows-Feature-/Optionen deaktivieren." | Write-Verbose [SicherheitInfoCheck]::new($My.Id++, $My.Neutral, 'Allgemein', 'Platform', $PSVersionTable.Platform, '') [SicherheitInfoCheck]::new($My.Id++, $My.Neutral, 'Allgemein', 'CurrentPSHost', (Get-Host | Select-Object -ExpandProperty Name), '') "Zu $($My.Id - 1)) weitere PowerShell-Hosts können sein: ConsoleHost, Visual Studio Code Host, Windows PowerShell ISE Host, etc." | Write-Verbose if ($ExecutionContext.SessionState.LanguageMode -ieq "FullLanguage") { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Allgemein', 'PSSessionLanguageMode', ($ExecutionContext.SessionState.LanguageMode), 'ConstrainedLanguage') "Zu $($My.Id - 1)) Weitere Details siehe about_Language_Modes" | Write-Verbose if ((Get-ExecutionPolicy) -ine "AllSigned") { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Allgemein', 'ExecutionPolicy', (Get-ExecutionPolicy), 'AllSigned') "Zu $($My.Id - 1)) *Policy sollte auf AllSigned stehen. Für PSEntwickler empfiehlt sich RemoteSigned" | Write-Verbose if ($my.IsAdminRights) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Allgemein', 'Erhöhte Admin-Rechte', $my.IsAdminRights, $false) #endregion #region PROFILE $my.Result = Test-Path -Path $PROFILE.AllUsersAllHosts -PathType Leaf if ($My.Result) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Profile-Datei vorhanden', 'AllUsersAllHosts', $My.Result, $false) $my.Result = Test-Path -Path $PROFILE.AllUsersCurrentHost -PathType Leaf if ($My.Result) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Profile-Datei vorhanden', 'AllUsersCurrentHost', $My.Result, $false) "Zu $($My.Id - 1)) Auch PFade in anderen PowerShell-Hosts (s.o.) testen." | Write-Verbose $my.Result = Test-Path -Path $PROFILE.CurrentUserAllHosts -PathType Leaf if ($My.Result) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Profile-Datei vorhanden', 'CurrentUserAllHosts', $My.Result, $false) $my.Result = Test-Path -Path $PROFILE.CurrentUserCurrentHost -PathType Leaf if ($My.Result) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Profile-Datei vorhanden', 'CurrentUserCurrentHost', $My.Result, $false) "Zu $($My.Id - 1)) Auch PFade in anderen PowerShell-Hosts (s.o.) testen." | Write-Verbose #endregion #region Microsoft Defender Antivirus $my.Result = Get-MpPreference | Select-Object -ExpandProperty ExclusionPath if ($null -ne $My.Result) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status , 'Defender', 'ExclusionPath', $My.Result, 'No Exclusion Paths') #endregion #region Module Version Check $My.Status = $my.Skip ; $My.Result = "Test übersprungen" ; $My.TargetResult = "Test übersprungen" if (-not $SkipModuleVersionTest) { $My.Status = $My.Passed ; $My.Result = "unnötig in PowerShell 7" ; $My.TargetResult = "unnötig in PowerShell 7" if (-not $PSVersionTable.PSVersion -ge 6) { $My.Result = (Get-PackageProvider -Name NuGet).Version $My.TargetResult = (Find-PackageProvider -Name NuGet).Version if ($My.Result -le $My.TargetResult) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } } } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'PackageProvider', 'NuGet', $My.Result, $My.TargetResult) "Zu $($My.Id - 1)) Nur in Windows PowerShell 5.1 wichtig." | Write-Verbose #endregion #region Module Version Check $My.Status = $my.Skip ; $My.Result = "Test übersprungen" ; $My.TargetResult = "Test übersprungen" if (-not $SkipModuleVersionTest) { $My.Result = (Get-Module -Name PackageManagement -LISTAvailable -Verbose:$false).Version | Sort-Object -Descending | Select-Object -First 1 $My.TargetResult = [Version](Find-Module -Name PackageManagement).Version if ($My.Result -lt $My.TargetResult) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Module', 'PackageManagement', $My.Result, $My.TargetResult) $My.Status = $my.Skip ; $My.Result = "Test übersprungen" ; $My.TargetResult = "Test übersprungen" if (-not $SkipModuleVersionTest) { $My.Result = (Get-Module -Name PowerShellGet -LISTAvailable -Verbose:$false).Version | Sort-Object -Descending | Select-Object -First 1 $My.TargetResult = [Version](Find-Module -Name PowerShellGet).Version if ($My.Result -lt $My.TargetResult) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Module', 'PowerShellGet', $My.Result, $My.TargetResult) $My.Status = $my.Skip ; $My.Result = "Test übersprungen" ; $My.TargetResult = "Test übersprungen" if (-not $SkipModuleVersionTest) { $My.Result = (Get-Module -Name PSScriptAnalyzer -LISTAvailable -Verbose:$false).Version | Sort-Object -Descending | Select-Object -First 1 $My.TargetResult = [Version](Find-Module -Name PSScriptAnalyzer).Version if ($My.Result -lt $My.TargetResult) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Module', 'PSScriptAnalyzer', $My.Result, $My.TargetResult) $My.Status = $my.Skip ; $My.Result = "Test übersprungen" ; $My.TargetResult = "Test übersprungen" if (-not $SkipModuleVersionTest) { $My.Result = (Get-Module -Name Pester -LISTAvailable -Verbose:$false).Version | Sort-Object -Descending | Select-Object -First 1 $My.TargetResult = [Version](Find-Module -Name Pester).Version if ($My.Result -lt $My.TargetResult) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Module', 'Pester', $My.Result, $My.TargetResult) #endregion #region ScriptBlockLogging $My.Result = Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name 'EnableScriptBlockLogging' if ($My.Result -eq 0) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'ScriptBlockLogging', 'Windows PowerShell 64bit', $My.Result, 1) "Zu $($My.Id - 1)) ScriptBlockLogging sollte inkl. Verschlüsselung aktiviert werden. Für weitere Details siehe about_Logging_Windows." | Write-Verbose $My.Result = Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name 'EnableScriptBlockLogging' if ($My.Result -eq 0) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'ScriptBlockLogging', 'Windows PowerShell 32bit', $My.Result, 1) "Zu $($My.Id - 1)) ScriptBlockLogging sollte inkl. Verschlüsselung aktiviert werden. Für weitere Details siehe about_Logging_Windows." | Write-Verbose $My.Result = Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name 'EnableScriptBlockLogging' if ($My.Result -eq 0) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'ScriptBlockLogging', 'PowerShell 7 64bit', $My.Result, 1) "Zu $($My.Id - 1)) ScriptBlockLogging sollte inkl. Verschlüsselung aktiviert werden. Für weitere Details siehe about_Logging_Windows." | Write-Verbose #endregion #region Just Enough Administration if($my.IsAdminRights) { $My.Result = Get-PSSessionConfiguration -Verbose:$false | Where-Object -Property Name -NotMatch -Value 'PowerShell' | Select-Object -ExpandProperty Name; $sc -join ', ' } else { "Zu $($My.Id - 1)) ACHTUNG! Keine Admin-Rechte zum testen vorhanden. Führe diesen Test erneut mit Admin-Rechten aus." | Write-Warning $My.Result = "n/v" } [SicherheitInfoCheck]::new($My.Id++, $My.Neutral, 'JEA', 'SessionConfigurations', $my.Result, '') "Zu $($My.Id - 1)) Das Einrichten von JEA für Nicht-Administratoren/Konten mit administrativen Aufgaben anstreben." | Write-Verbose #endregion #region Alternate Data Stream $My.Status = $My.Skip; $My.Result = "Test übersprungen" if (-not $SkipAlternateDataStreamTest) { $My.CountFiles = Get-ChildItem -Path 'C:\' -File -Force -ErrorAction Ignore -Recurse | Measure-Object | Select-Object -ExpandProperty Count $My.CurrentCounter = 1 $My.Status = $My.Neutral $My.Result = Get-ChildItem -Path c:\ -File -Force -Recurse -ErrorAction Ignore | ForEach-Object -Process { Write-Progress -Activity 'Scanne Dateien nach Alternate Data Stream''s' -Status $My.CurrentCounter -PercentComplete ([System.Math]::Floor(($My.CurrentCounter++) / $My.CountFiles * 100)) try { Get-Item -Path $_.FullName -Stream * -ErrorAction Ignore | Where-Object -Property Stream -ne ':$DATA' } catch { } } | Group-Object -Property Stream | Sort-Object -Descending Count | Select-Object -Property Count, Name, @{Name = 'Sum'; Expression = { ($_.Group | Measure-Object -Property Length -Sum | Select-Object -ExpandProperty SumLengthKB) / 1KB } }, Group Write-Progress -Activity 'Scanne Dateien nach Alternate Data Stream''s' -Completed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'Alternate Data Stream', 'Gruppiert IST', $My.Result, 'Zero ADS Strategy') "Zu $($My.Id - 1)) Auffällige / Große ADS-Dateien manuell prüfen. Siehe das gruppierte Ergebnis der IST-Eigenschaft." | Write-Verbose #endregion #region PKI $My.Result = Get-ChildItem -Path 'Cert:\' -Recurse -Force | Where-Object -Property 'HasPrivateKey' | ForEach-Object -Process { if ((IstZertifikatExportierbar $_)) { return "SUBJECT: $($_.Subject) THUMBPRINT: $($_.Thumbprint)" } } if ($null -ne $My.Result) { $My.Status = $My.Failed } else { $My.Status = $My.Passed } [SicherheitInfoCheck]::new($My.Id++, $My.Status, 'PKI', 'ExportablePrivateCertificate', $My.Result, 'Zero Strategie') "Zu $($My.Id - 1)) Zertifikate mit privatem Schlüssel sollten mit diesem nicht exportierbar sein." | Write-Verbose #endregion Remove-Variable -Name My -Force -ErrorAction Ignore } <# KOMPONENTEN TEST Test-SecurityState Test-SecurityState -Verbose Test-SecurityState -SkipModuleVersionTest -Verbose Test-SecurityState -SkipAlternateDataStreamTest -Verbose Test-SecurityState -SkipModuleVersionTest -SkipAlternateDataStreamTest -Verbose #> # SIG # Begin signature block # MIIcYgYJKoZIhvcNAQcCoIIcUzCCHE8CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDdciBtz+Ob6quI # 2F2mjjYYej3txz4Id7sXHrDQ5kcYXKCCFn0wggNyMIICWqADAgECAhA8emkJ82H0 # pEx+itPRny0WMA0GCSqGSIb3DQEBDQUAMFExIzAhBgkqhkiG9w0BCQEWFGluZm9A # YXR0aWxha3JpY2suY29tMSowKAYDVQQDDCFBdHRpbGEgS3JpY2sgKFNvZnR3YXJl # IERldmVsb3BlcikwHhcNMjIxMDE2MTg1MTA3WhcNMzIxMDE2MTkwMTA3WjBRMSMw # IQYJKoZIhvcNAQkBFhRpbmZvQGF0dGlsYWtyaWNrLmNvbTEqMCgGA1UEAwwhQXR0 # aWxhIEtyaWNrIChTb2Z0d2FyZSBEZXZlbG9wZXIpMIIBIjANBgkqhkiG9w0BAQEF # AAOCAQ8AMIIBCgKCAQEAvbn3JNw62vDI7mnX6gD+V/MyDkvFSzclaqC3Kfn+wDxj # xkmgwho343N/JCxAUjHoBjNDpx4W3KTVv3X7PYrPHxoz/134JTIBdV+yIyL/VkCS # Mnp9exMhMPxa1RvX3p/zphPMosv7xGgRPF3QVKxoBBUtifql80/pDHvOCPtROZ+9 # xSfXJ6P9jXGH4YSlNJxAKv53AXV0avihpa1BWL6ohyS1Bnjdbcw/hq0TIf4as1Dy # 7IbrU6Fneaqm/XIEEs11I0BrDNwgXnmB8PSojsm/DOtQY5Ps8eGJzwiXP2Vdvk0j # OsqDaJe3cxiOCXk6dz2zylB6rfP+Kph97bjaQoNI2QIDAQABo0YwRDAOBgNVHQ8B # Af8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFKrSiXRUaupI # 5orXIniIR5sTcWwIMA0GCSqGSIb3DQEBDQUAA4IBAQAQ+6LPLF6Ua7JCC9LuwOCG # UlWwawgV/D5wK+FU8PQ+/onwBx9ZBqXnZw4f7NQtqaiR1bwm7sRTZeaIcif57zHM # /WBicYjB9dwZoGylfeCW6LRNQaoBvjuavOTsQw3lYF//ylJV8QyUKloJd9W6CVtm # tBSJEYopjygAm/9E9CxRFPSXxX/G+Af0+G+VeeBjSpaYKO688dVXa7pqMOm6hq9P # Ww6jgiCL3aRk0qbWwl2mt1POcfdRk/rdvt66BcO91cLDKhSCOIp7coJZ8Cf2xHDP # 99NcZ8ct02Cco6qjtlUkrCBRYNsuUAcToTvqQLiSSkywj+jTI4gm0vcjSiVXwnyy # MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0BAQwFADBl # MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 # d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv # b3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G # CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7J # IT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxS # D1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb # 7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1ef # VFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoY # OAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSa # M0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI # 8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9L # BADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfm # Q6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDr # McXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15Gkv # mB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E # FgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGL # p6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAkBggrBgEF # BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRw # Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu # Y3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRVHSAAMA0G # CSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyhhyzshV6p # Grsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO0Cre+i1W # z/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo8L8vC6bp # 8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++hUD38dglo # hJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5xaiNrIv8S # uFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIGrjCCBJagAwIBAgIQ # BzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEV # MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t # MSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAw # MDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5 # NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A # MIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYR # oUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CE # iiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCH # RgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5K # fc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDni # pUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2 # nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp # 88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1C # vwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+ # 0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl2 # 7KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOC # AV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaa # L3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1Ud # DwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkw # JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcw # AoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJv # b3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwB # BAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ # ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvX # bYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tP # iix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCy # Xen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpF # yd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3 # fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t # 5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejx # mF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxah # ZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAA # zV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vup # L0QVSucTDh3bNzgaoSv27dZ8/DCCBsAwggSooAMCAQICEAxNaXJLlPo8Kko9KQeA # PVowDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYg # U0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMjA5MjEwMDAwMDBaFw0zMzExMjEy # MzU5NTlaMEYxCzAJBgNVBAYTAlVTMREwDwYDVQQKEwhEaWdpQ2VydDEkMCIGA1UE # AxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIgLSAyMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEAz+ylJjrGqfJru43BDZrboegUhXQzGias0BxVHh42bbyS # VQxh9J0Jdz0Vlggva2Sk/QaDFteRkjgcMQKW+3KxlzpVrzPsYYrppijbkGNcvYlT # 4DotjIdCriak5Lt4eLl6FuFWxsC6ZFO7KhbnUEi7iGkMiMbxvuAvfTuxylONQIMe # 58tySSgeTIAehVbnhe3yYbyqOgd99qtu5Wbd4lz1L+2N1E2VhGjjgMtqedHSEJFG # Kes+JvK0jM1MuWbIu6pQOA3ljJRdGVq/9XtAbm8WqJqclUeGhXk+DF5mjBoKJL6c # qtKctvdPbnjEKD+jHA9QBje6CNk1prUe2nhYHTno+EyREJZ+TeHdwq2lfvgtGx/s # K0YYoxn2Off1wU9xLokDEaJLu5i/+k/kezbvBkTkVf826uV8MefzwlLE5hZ7Wn6l # JXPbwGqZIS1j5Vn1TS+QHye30qsU5Thmh1EIa/tTQznQZPpWz+D0CuYUbWR4u5j9 # lMNzIfMvwi4g14Gs0/EH1OG92V1LbjGUKYvmQaRllMBY5eUuKZCmt2Fk+tkgbBhR # YLqmgQ8JJVPxvzvpqwcOagc5YhnJ1oV/E9mNec9ixezhe7nMZxMHmsF47caIyLBu # MnnHC1mDjcbu9Sx8e47LZInxscS451NeX1XSfRkpWQNO+l3qRXMchH7XzuLUOncC # AwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1Ud # JQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG # /WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4EFgQU # Yore0GH8jzEU7ZcLzT0qlBTfUpwwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2Ny # bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1NlRp # bWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUHMAGG # GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDovL2Nh # Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1 # NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAVaoqGvNG83hX # NzD8deNP1oUj8fz5lTmbJeb3coqYw3fUZPwV+zbCSVEseIhjVQlGOQD8adTKmyn7 # oz/AyQCbEx2wmIncePLNfIXNU52vYuJhZqMUKkWHSphCK1D8G7WeCDAJ+uQt1wmJ # efkJ5ojOfRu4aqKbwVNgCeijuJ3XrR8cuOyYQfD2DoD75P/fnRCn6wC6X0qPGjpS # tOq/CUkVNTZZmg9U0rIbf35eCa12VIp0bcrSBWcrduv/mLImlTgZiEQU5QpZomvn # Ij5EIdI/HMCb7XxIstiSDJFPPGaUr10CU+ue4p7k0x+GAWScAMLpWnR1DT3heYi/ # HAGXyRkjgNc2Wl+WFrFjDMZGQDvOXTXUWT5Dmhiuw8nLw/ubE19qtcfg8wXDWd8n # YiveQclTuf80EGf2JjKYe/5cQpSBlIKdrAqLxksVStOYkEVgM4DgI974A6T2RUfl # zrgDQkfoQTZxd639ouiXdE4u2h4djFrIHprVwvDGIqhPm73YHJpRxC+a9l+nJ5e6 # li6FV8Bg53hWf2rvwpWaSxECyIKcyRoFfLpxtU56mWz06J7UWpjIn7+NuxhcQ/XQ # KujiYu54BNu90ftbCqhwfvCXhHjjCANdRyxjqCU4lwHSPzra5eX25pvcfizM/xdM # TQCi2NYBDriL7ubgclWJLCcZYfZ3AYwxggU7MIIFNwIBATBlMFExIzAhBgkqhkiG # 9w0BCQEWFGluZm9AYXR0aWxha3JpY2suY29tMSowKAYDVQQDDCFBdHRpbGEgS3Jp # Y2sgKFNvZnR3YXJlIERldmVsb3BlcikCEDx6aQnzYfSkTH6K09GfLRYwDQYJYIZI # AWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B # CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAv # BgkqhkiG9w0BCQQxIgQgkzR1Y4ZMbODDcZKX/XogAqMK9tSCoDE9MaVJkghLBF4w # DQYJKoZIhvcNAQEBBQAEggEAbLQftQZA7+cpxRzZGwePps1VE+hCu8Qhdlkf7luB # QFZYwEIWmdgcyzqxYZhzg2ZITHU+LkMYcnYxOQERMudWY8XEzw+Mh+Z3lJhomUGE # kkr2t1TwnFQaDZANzW2XZWJDAP1MMOBktIkCljGAB3FFuNUaSL+A90Ls8wLUk3+T # E0JGV7foBk34FXeg5QMqWgaTN5yJP3Rlrm7oLhjqouM+UPcD/mL7brhHpcrzIzRv # J23IVIhAkarGpK6V3s3DvDL3J/7KEzQgYnGDGrcyKXhiWJFPHmhjQXygFpuGIIX7 # xB7Y2ktL5M8p9xZzNd1RbJlY3cQq0fWBnLIFsGoQxQ/996GCAyAwggMcBgkqhkiG # 9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp # Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2 # IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAxNaXJLlPo8Kko9KQeAPVowDQYJYIZI # AWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ # BTEPFw0yMzAyMDgyMTM1MjRaMC8GCSqGSIb3DQEJBDEiBCB3fqFZDVuKzzG689HU # 3dYKfNIZlg9BEsjdBoWx3AqhcTANBgkqhkiG9w0BAQEFAASCAgBPJlrm+KH9CIVn # 0djm+9oD5AxDh7Zwn07bcVyt/7WzPUt0JWwjoWyqnr4ZP4vdnDXXlfEy21fLyfA2 # rzVgRawQ40UMOVNezW6m+rs/ajw73Vy4PlsRA2YwS0ogFNGVa1hYhVhRkbqOyvUL # Vs23prM93KqNpHqm1zl0WM2LrUjAqpyJi6ZDHhCNu19XvEui9VL3ml2qhABx+z9A # iyiTyeWSq8nM+fucQMHxP3NCXWBEIhOu5Nyzm6T5fkKPuMwlRYfGC6M9Y4K4L3/u # LqpnG5gLG3+wU6JqwvIDZnIDaoWAOCtvSYKzXN5UWITtv/q73c1aFoaG/uM8rJCH # 7a/lR8K/mvWYoZSOmxo1BwGwZm7rY4WYY7XXP8g1aGJUZl5oh0XLCUmYDD2d6Wa/ # O79pAF3M2UZLFP0pKK970MznH6Gb3GG70Q71VKyOGcpcPYwP1tRJ9OheQkfhG5EU # ZvvnhEHAlHrPzD5h+6KRQHdTdtgfTo7/3yo08M0jmdkmydGiFcLsWGQ6T17itlsz # 5esKC9lqCpeg2n5cQ5wze8fsqDfKL/HP1n0BSDdHDdX0gp7H4kNKqT7MfmvMtdnz # XvnPtlC1GTdtJNwUeAsO+5r80HQ5dtsVPYH8UPlj8jQXnQ0ZpxIOj3+r80CJY4wk # rar418FdxHBlQEGcQMvS4UIxWFw0lA== # SIG # End signature block |