Last active
July 2, 2021 02:00
-
-
Save hpaul-osi/011257c57a0fd9228bca9e0f1dde23f6 to your computer and use it in GitHub Desktop.
Examples from Extreme PI System Hardening at PI World 2018
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
Extreme PI System Hardening | |
High value systems warrant hardcore hardening measures. The PI System resides at a critical junction, communicating across strict network boundaries. Under this paradigm, the PI System acts as a 'safe harbor' for data, defending critical systems by reducing the number of users inside the security perimeter while enabling growth in the number of users getting value from OT data. An application can only be as secure as its operating platform, so this session will start from the ground up. We will establish a solid foundation with advanced hardening measures for the Windows operating system that OSIsoft has collected over many years working with the platform, such as security baselines, PowerShell’s Desired State Configuration, and arcane corners of the Windows Advanced Firewall. With the platform locked down, we will explore application hardening measures built within and tailored to the PI System. Emphasis will be on using the latest technology and tools available to embrace agility and configuration as code. Examples from session demos will be available on GitHub for administrators who want try them at home. | |
https://piworld.osisoft.com/us2018/sessions |
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
# We'll be using the core image | |
$TargetMachine = "pida.cyber.io" | |
# Establish a PSSession to the PI Data Archive | |
$pscore = New-PSSession -ComputerName $TargetMachine | |
# Go to demo working directory | |
sl ($home + "\Documents\demo") | |
# There are some modules we'll need for our baselines | |
$Modules = @( | |
'xPSDesiredStateConfiguration', | |
'AuditPolicyDSC', | |
'SecurityPolicyDSC', | |
'xStorage', | |
'xNetworking' | |
) | |
# We need to install a few prerequisites to run the DSC baselines | |
Invoke-Command -Session $pscore ` | |
-FilePath .\Supporting1_InstallDscBaselinePrerequisites.ps1 ` | |
-ArgumentList (,$Modules) | |
# Let's verify we installed the resources we think. | |
Invoke-Command -Session $pscore -ScriptBlock { Get-DscResource | select Module -Unique } | |
# Windows Security Baselines | |
# https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-security-baselines | |
# Security Compliance Toolkit | |
# https://www.microsoft.com/en-us/download/details.aspx?id=55319 | |
# Blog Post for Windows Server 2016 | |
# https://blogs.technet.microsoft.com/secguide/2016/10/17/security-baseline-for-windows-10-v1607-anniversary-edition-and-windows-server-2016/ | |
# GPO {088E04EC-440C-48CB-A8D7-A89D0162FBFB} corresponds to Windows Server 2016 Member Server Baseline - Computer | |
$BaselineModule = "BaselineManagement" | |
Install-Module $BaselineModule -Verbose | |
Import-Module $BaselineModule -Verbose | |
# Let's set a few paths | |
$GPOPath = $home + "\Documents\Demo\MSBaseline\GPOs\{088E04EC-440C-48CB-A8D7-A89D0162FBFB}" | |
$ConfigName = 'DSCFromGPO' | |
$OutputPath = ('.\' + $ConfigName) | |
if(!(test-path $OutputPath)){ ni $OutputPath -it Directory } | |
# Create our DSC config from the baseline | |
ConvertFrom-GPO -OutputConfigurationScript -OutputPath $OutputPath -Path $GPOPath | |
# Look inside the created folder | |
ls $ConfigName | |
# Don't need the MOF file here; we'll compile on the target | |
ri ".\$ConfigName\localhost.mof" | |
# Let's look at the head of the file for anything interesting | |
$ConfigFile = ".\$ConfigName\DSCFromGPO.ps1" | |
gc $ConfigFile -TotalCount 20 | |
gc $ConfigFile -Tail 20 | |
# Now we can compile the config on the target server | |
Invoke-Command -Session $pscore -FilePath $ConfigFile | |
# Stepping in will give us a closer look. | |
Enter-PSSession -Session $pscore | |
# Let's get our current status before we go crazy throwing settings on the machine. | |
$before = Test-DscConfiguration .\DSCFromGPO -Verbose | |
# Let's look at how the result is structured | |
$before | |
$before | get-member | FT | |
# Let's take a look at what is already good | |
$before.ResourcesInDesiredState | select resourceid | |
# And what needs to be done | |
$before.ResourcesNotInDesiredState | select resourceid | |
# Now we can make it so | |
Start-DscConfiguration .\DSCFromGPO -Wait -Verbose | |
# Let's get our current status before we go crazy throwing settings on the machine. | |
$after = Test-DscConfiguration .\DSCFromGPO -Verbose | |
# Let's take a look at what is already good | |
$after.ResourcesInDesiredState | select resourceid | |
# And what needs to be done | |
$after.ResourcesNotInDesiredState | select resourceid | |
# We can explore the other cmdlets related to DSC | |
Get-Command -Module PSDesiredStateConfiguration | |
# I can also look at the LCM config | |
Get-DscLocalConfigurationManager | |
# We can see the status of our configurations | |
Get-DscConfigurationStatus | |
# I can pull all the configs pushed to the machine | |
$DSCConfigs = Get-DscConfiguration | |
# Let's dig into these records | |
$DSCConfigs | Get-Member | |
$DSCConfigs | select ConfigurationName -Unique | |
$DSCConfigs | select ResourceId | FT | |
# Just one to see all the detail | |
$DSCConfigs[0] | |
# I can run the whole set again, but I won't... | |
Start-DscConfiguration -UseExisting -Wait -Verbose | |
# Step back out | |
Exit-PSSession | |
# Clean up | |
Remove-PSSession -Session $pscore -Verbose |
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
# Using the core image | |
$TargetMachine = "pida.cyber.io" | |
# Go to the working folder | |
sl ($home + "\Documents\demo") | |
# Location of PI Security DSC | |
$ModuleFolder = "$home\Documents\Utilities\PI-Security-Audit-Tools-v2.2.0.0-prerelease" | |
# Check the signatures so that we know we're using the right modules. | |
$signatures = gci $ModuleFolder -Recurse -File | ? { $_.Extension -in @('.ps1','.psm1','.psd1') } | Get-AuthenticodeSignature | |
$signatures | select Status, Path | FT -AutoSize | |
# Find the module | |
$ModuleFile = gci $ModuleFolder -File -Recurse -Filter 'PISYSAUDIT.psd1' | |
# Import the module | |
Import-Module $ModuleFile.FullName | |
# Let's see the full help | |
Get-Help PISysAudit -full | |
# Now look at the new report command | |
Get-Help New-PISysAuditReport -full | |
# Oh, let's check out conceptual help | |
Get-Help about_PISYSAUDIT | |
# Create a parameter and launcha an audit | |
$cpt = piauditparams $null $TargetMachine "pidataarchive" | |
piaudit -cpt $cpt | |
# Suppose we have another solution for monitoring, we can use SuppressCheckID | |
piaudit -cpt $cpt -SuppressCheckID @('AU10006') |
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
# Using our core image | |
$TargetMachine = "pida.cyber.io" | |
# Establish a PSSession to the PI Data Archive | |
$pscore = new-pssession -ComputerName $TargetMachine | |
# Go to working folder | |
sl ("$home\Documents\demo") | |
# Downloaded DSC | |
# https://github.com/osisoft/PI-Security-Audit-Tools/releases | |
# Let's check if the file is blocked... | |
$Release = "PI-Security-DSC-v2.2.0.0-prerelease" | |
$DownloadZIP = "$home\Documents\Utilities\$Release.zip" | |
gi $DownloadZIP -Stream Zone.Identifier -ea SilentlyContinue | |
# Easier if we unblock it before unzipping | |
Unblock-File $DownloadZIP | |
# Extract | |
Expand-Archive $DownloadZIP -DestinationPath "$home\Documents\Utilities\" -Verbose -Force | |
# Set the module folder | |
$ModuleFolder = "$home\Documents\Utilities\$Release\" | |
# Check the signatures so that we know we're using the right modules. | |
$signatures = gci $ModuleFolder -Recurse -File | ? { $_.Extension -in @('.ps1','.psm1','.psd1') } | Get-AuthenticodeSignature | |
$signatures | select Status, Path | FT -AutoSize | |
# Copy PI Security DSC module over. | |
Copy-Item $ModuleFolder -ToSession $pscore -Destination C:\users\hpaul\documents\utilities -Verbose -Recurse -Force | |
# Enter PSSession | |
Enter-PSSession -Session $pscore | |
# Set ourselves in the utilities folder. | |
sl ("$home\Documents\utilities") | |
# Find the path to the PISecurityDSC module | |
$ModuleDirectory = gci '.\' -File -Recurse -Filter 'PISecurityDSC.psd1' | select DirectoryName | |
# Throw that in the PowerShell modules folder to install | |
Copy-Item $ModuleDirectory.DirectoryName ` | |
-Destination ($env:ProgramFiles + "\WindowsPowerShell\Modules") ` | |
-Recurse -Verbose -Force | |
# The computer should now be aware of the module resources | |
Get-DscResource -Module PISecurityDSC | |
# Switch to the folder with the sample configurations | |
sl ($ModuleDirectory.DirectoryName + "\..\..\Configuration") | |
# What's in there? | |
ls | |
# Look at the whole script. | |
Get-Content .\PIDataArchive_BasicWindowsImplementation.ps1 -TotalCount 100 | |
# But if I dot source, then the session knows about my configuration function. | |
. .\PIDataArchive_BasicWindowsImplementation.ps1 | |
# Then I can call the standard Get-Help on my configuration if the author did comment based help. | |
Get-Help PIDataArchive_BasicWindowsImplementation -Full | |
# Compile the config with the appropriate parameters based on the help. | |
PIDataArchive_BasicWindowsImplementation ` | |
-PIAdministratorsADGroup "CS\PI Administrators" ` | |
-PIUsersADGroup "CS\PI Readers" ` | |
-PIBuffersADGroup "CS\PI Buffers" ` | |
-PIInterfacesADGroup "CS\PI Interfaces" ` | |
-PIPointsAnalysisCreatorADGroup "CS\PI Analytics" ` | |
-PIWebAppsADGroup "CS\PI Web Apps" | |
Get-Content .\PIDataArchive_BasicWindowsImplementation\localhost.mof | |
# Test the configuration | |
$before = Test-DscConfiguration .\PIDataArchive_BasicWindowsImplementation -Verbose | |
$before.ResourcesInDesiredState | select ResourceId | |
$before.ResourcesNotInDesiredState | select ResourceId | |
# Make it so! | |
Start-DscConfiguration .\PIDataArchive_BasicWindowsImplementation -Wait -Verbose | |
# Audit the result | |
$after = Test-DscConfiguration .\PIDataArchive_BasicWindowsImplementation -Verbose | |
$after.ResourcesInDesiredState | select ResourceId | |
$after.ResourcesNotInDesiredState | select ResourceId | |
# Moving on to the next configuration | |
Get-Content .\PIDataArchive_AuditBaseline.ps1 -TotalCount 100 | |
# Dot source | |
. .\PIDataArchive_AuditBaseline.ps1 | |
# Then call the standard Get-Help on my configuration if the author did comment based help. | |
Get-Help PIDataArchive_AuditBaseline -Full | |
# Compile the config with the appropriate parameters based on the help. | |
PIDataArchive_AuditBaseline -NodeName localhost ` | |
-OutputPath .\PIDataArchive_AuditBaseline ` | |
-DaysToAllowEdit 90 ` | |
-MaxQueryExecutionSeconds 60 ` | |
-PIFirewallHostmasks @('10.0.0.*') ` | |
-AuthenticationPolicy 3 ` | |
-AutoTrustConfig 1 | |
# Notice that an MOF file was generated. | |
get-content .\PIDataArchive_AuditBaseline\localhost.mof -Verbose | |
# Test and look at what is already in the desired state. | |
$before = Test-DscConfiguration .\PIDataArchive_AuditBaseline -Verbose | |
$before.ResourcesInDesiredState | select ResourceId | |
$before.ResourcesNotInDesiredState | select ResourceId | |
# Make it so! | |
Start-DscConfiguration .\PIDataArchive_AuditBaseline -Wait -Verbose | |
# Restart the PI Server so everything takes effect | |
& "$($env:PIServer)adm\pisrvstop.bat" | |
& "$($env:PIServer)adm\pisrvstart.bat" | |
# Audit the result | |
$after = Test-DscConfiguration .\PIDataArchive_AuditBaseline -Verbose | |
$after.ResourcesInDesiredState | select ResourceId | |
$after.ResourcesNotInDesiredState | select ResourceId | |
# When we're done, we leave. | |
Exit-PSSession | |
# You weren't raised in a barn. Close the door on your way out. | |
Get-PSSession -ComputerName $TargetMachine | Remove-PSSession |
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
$NotepadExe = 'C:\Program Files\Notepad++\notepad++.exe' | |
# Go to demo folder. | |
sl "$home\Documents\demo" | |
# Use our core image | |
$TargetMachine = "pida.cyber.io" | |
# Establish PSSession | |
$pss = New-PSSession -ComputerName $TargetMachine | |
# Move the Attack Surface config over | |
Copy-Item .\Supporting4_AttackSurfaceReduction.ps1 ` | |
-ToSession $pss ` | |
-Destination c:\users\hpaul\documents | |
# The configuration contains several measures to reduce surface area | |
Start-Process $NotepadExe .\Supporting4_AttackSurfaceReduction.ps1 | |
# Copy over the script | |
Copy-Item -Path .\Supporting4_AttackSurfaceReduction.ps1 ` | |
-ToSession $pss ` | |
-Destination C:\Users\hpaul\Documents\ | |
# Copy the scraper over to the target node. | |
# Scraper from ESIC project at WSU | |
# https://github.com/ESIC-DA/AHA-Scraper | |
Copy-Item -Path ..\Utilities\AHA-Scraper ` | |
-ToSession $pss ` | |
-Destination C:\Users\hpaul\Documents\ ` | |
-Recurse -Verbose -Force | |
# Hop into the PSSession | |
Enter-PSSession -Session $pss | |
# Compile the config | |
.\Supporting4_AttackSurfaceReduction.ps1 | |
# Make it so | |
Start-DscConfiguration .\AttackSurfaceReduction -Wait -Verbose | |
# ByPass the ExecutionPolicy, storing the current one to reset afterward | |
$ExecPolicy = Get-ExecutionPolicy | |
Set-ExecutionPolicy bypass | |
# Navigate to the Scraper folder | |
Push-Location .\AHA-Scraper | |
# Call the Scraper | |
.\AHA-Scraper.ps1 | |
# Rewind | |
Pop-Location;Set-ExecutionPolicy $ExecPolicy | |
# Hop out of the PS Session | |
Exit-PSSession | |
# Pull the analysis file from the session | |
Copy-Item -Path C:\Users\hpaul\Documents\AHA-Scraper\BinaryAnalysis.csv ` | |
-FromSession $pss ` | |
-Destination $home\Documents\demo\Supporting4_CoreInstallation.csv | |
# Now the PSSession can be closed | |
Remove-PSSession -Session $pss | |
# View results from Scraper with the GUI | |
# https://github.com/ESIC-DA/AHA-GUI | |
java -jar .\AHA\AHA-GUI.jar inputfile=Supporting4_CoreInstallation.csv | |
# View another example with Desktop environment | |
java -jar .\AHA\AHA-GUI.jar inputfile=Supporting4_DEInstallation.csv |
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
# Go to the demo folder | |
sl "$home\documents\demo" | |
# Target the core machine | |
$TargetMachine = "pida.cyber.io" | |
# Enter a PSSession | |
$pss = New-PSSession -ComputerName $TargetMachine | |
# Copy over the VBS Example | |
Copy-Item -Path .\Supporting5_PINetMgrWSH.vbs -ToSession $pss -Destination C:\Users\hpaul\Documents -Verbose | |
$NotepadExe = 'C:\Program Files\Notepad++\notepad++.exe' | |
# Look at the VBS example | |
Start-Process $NotepadExe .\Supporting5_PINetMgrWSH.vbs | |
<# | |
Switch to the core machine to run it! | |
#> | |
# Look at the native PS example | |
Start-Process $NotepadExe .\Supporting5_PINetMgrWSH.ps1 | |
# Now run it and see what the rules look like it creates | |
Invoke-Command -Session $pss -FilePath .\Supporting5_PINetMgrWSH.ps1 | |
<# | |
Switch to the core machine to look at the result! | |
#> | |
# Look at the DSC Example | |
Start-Process $NotepadExe .\Supporting5_PINetMgrWSHDSC.ps1 | |
# Invoke DSC example to compile it | |
Invoke-Command -Session $pss -FilePath .\Supporting5_PINetMgrWSHDSC.ps1 | |
# Run the test | |
Invoke-Command -Session $pss {Test-DscConfiguration .\PINetMgrWSH -Verbose} | |
# Verify the PI Data Archive is still remotely accessible | |
Connect-PIDataArchive -PIDataArchiveMachineName $TargetMachine |
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
$TargetMachine = "pida.cyber.io" | |
$NotepadExe = 'C:\Program Files\Notepad++\notepad++.exe' | |
# Get our new PSSession | |
$pss = New-PSSession -ComputerName $TargetMachine | |
# Per KB01062 there are recommended exclusions for PI Data Archive. | |
# Look at the AV exclusion script | |
Start-Process $NotepadExe .\Supporting6_AntivirusExclusions.ps1 | |
# Run the script to add exclusions | |
Invoke-Command -Session $pss -FilePath .\Supporting6_AntivirusExclusions.ps1 | |
$exclusions = Invoke-Command -Session $pss {Get-MpPreference | select ExclusionPath} | |
$exclusions.ExclusionPath | |
# Look at the Code Integrity Policy Script | |
Start-Process $NotepadExe .\Supporting6_NewCodeIntegrityPolicy.ps1 | |
Start-Process $NotepadExe .\Supporting6_MSBlockSiPolicy.xml | |
Start-Process $NotepadExe .\Supporting6_PublisherSiPolicy.xml | |
# Extract signers from CIPolicy XML | |
$policyConfig = ".\Supporting6_PublisherSiPolicy.xml" | |
[xml]$PolicyContents = Get-Content $policyConfig | |
$PolicyContents.SiPolicy.Signers.Signer ` | |
| Select Name, @{ | |
Name="Publisher"; | |
Expression={$_.CertPublisher.Value} | |
}, | |
@{ | |
Name="Root"; | |
Expression={$_.CertRoot.Value} | |
} -Unique ` | |
| FT -AutoSize | out-string -Width 4096 ` | |
| out-file Supporting6_PublisherList.txt | |
# View List of Publishers | |
Start-Process $NotepadExe .\Supporting6_PublisherList.txt | |
# Move the policy XML files over. | |
Copy-Item -Path .\Supporting6_MSBlockSiPolicy.xml ` | |
-ToSession $pss ` | |
-Destination C:\Users\hpaul\Documents\MSBlockSiPolicy.xml ` | |
-Force -Verbose | |
Copy-Item -Path .\Supporting6_PublisherSiPolicy.xml ` | |
-ToSession $pss ` | |
-Destination C:\Users\hpaul\Documents\PublisherSiPolicy.xml ` | |
-Force -Verbose | |
# Run the script to merge and deploy the policies | |
Invoke-Command -Session $pss -FilePath .\Supporting6_NewCodeIntegrityPolicy.ps1 | |
# !Place our malicious program after generating the policy! | |
Copy-Item -Path $home\Documents\Demo\Supporting6_test.nosig.exe ` | |
-ToSession $pss ` | |
-Destination C:\Users\hpaul\Documents\test.nosig.exe | |
# Look at script to enabling VBS | |
Start-Process $NotepadExe .\Supporting6_EnableVBS.ps1 | |
# Enable and restart to take effect | |
Invoke-Command -Session $pss .\Supporting6_EnableVBS.ps1 | |
Invoke-Command -Session $pss { Start-DscConfiguration .\EnableVBS -Wait -Verbose } | |
Invoke-Command -Session $pss { Restart-Computer } | |
Remove-PSSession -Session $pss | |
# Check if it has bounced back... | |
Test-NetConnection $TargetMachine -port 5985 | |
<# | |
Jump over to the PI Data Archive to test | |
#> | |
# Establish a new session | |
$pss = New-PSSession -ComputerName $TargetMachine | |
# Get Status with msinfo32 or Get-CimInstance below | |
Invoke-Command -Session $pss {Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard} | |
# Get audit events | |
Invoke-Command -Session $pss { | |
Get-WinEvent -ProviderName 'Microsoft-Windows-CodeIntegrity' ` | |
| Where-Object { $_.Id -eq 3077 } ` | |
| Format-List | |
} | |
# Note the Language Mode has changed | |
Invoke-Command -Session $pss { $ExecutionContext.SessionState.LanguageMode } | |
# Grab the binary analysis file. | |
Invoke-Command -Session $pss ` | |
{gc C:\Users\hpaul\Documents\AHA-Scraper\BinaryAnalysis.csv} | ` | |
Out-File $home\Documents\demo\Supporting4_CoreHardened.csv -Encoding utf8 | |
# Look at the visualization. | |
java -jar .\AHA\AHA-GUI.jar inputfile=Supporting4_CoreHardened.csv | |
Remove-PSSession -Session $pss |
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
<# | |
.SYNOPSIS | |
Installs specified modules from PSGallery. | |
.DESCRIPTION | |
This function is intented to install resource modules required by DSC baselines. It will also add NuGet and PSGallery if not already added. | |
.PARAMETER RequiredModules | |
String array of module names to pull from PSGallery | |
.EXAMPLE | |
.\Install-DscBaselinePrerequisites.ps1 | |
#> | |
param( | |
[string[]]$RequiredModules = @( | |
'xPSDesiredStateConfiguration' | |
) | |
) | |
# NuGet required to retrieve resources | |
if(Get-PackageProvider -ListAvailable -Name NuGet -ErrorAction SilentlyContinue) | |
{ | |
Write-Output "NuGet Package located" | |
} | |
else | |
{ | |
Write-Output "Attempting to install the prerequisite NuGet Package" | |
Install-PackageProvider -Name NuGet -Confirm -Verbose | |
} | |
if($(Get-PSRepository -Name PSGallery).InstallationPolicy -eq 'Trusted') | |
{ | |
Write-Output "PSGallery InstallationPolicy is already Trusted" | |
} | |
else | |
{ | |
Write-Output "Setting PSGallery InstallationPolicy to Trusted" | |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -Verbose | |
} | |
# Pull in required modules | |
Find-Module $RequiredModules | Install-Module -Verbose |
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
Configuration AttackSurfaceReduction | |
{ | |
param( | |
[string]$NodeName="localhost" | |
) | |
Import-DscResource -ModuleName xNetworking, PSDesiredStateConfiguration | |
Node $NodeName | |
{ | |
#region Networking | |
$InterfaceAlias = "Microsoft Hyper-V Network Adapter #2" | |
xNetBIOS DisableNetBIOS | |
{ | |
InterfaceAlias = $InterfaceAlias | |
Setting = 'Disable' | |
} | |
$FirewallProfiles = @( | |
'Private', | |
'Public', | |
'Domain' | |
) | |
Foreach($Profile in $FirewallProfiles) | |
{ | |
xFirewallProfile ("FirewallProfile_" + $Profile) | |
{ | |
Name = $Profile | |
Enabled = 'True' | |
DefaultInboundAction = 'Block' | |
DefaultOutboundAction = 'Block' | |
AllowInboundRules = 'True' | |
NotifyOnListen = 'True' | |
LogFileName = '%systemroot%\system32\LogFiles\Firewall\pfirewall.log' | |
LogMaxSizeKilobytes = 20480 | |
LogAllowed = 'False' | |
LogBlocked = 'True' | |
} | |
} | |
# Firewall - custom rules to enable | |
$PINetMgrProgram = ($env:piserver + "bin\pinetmgr.exe") | |
xFirewall PIDataArchive_ClientConnections_In | |
{ | |
Direction = 'Inbound' | |
Name = 'PI-Data-Archive-PINET-TCP-In' | |
DisplayName = 'PI Data Archive PINET (TCP-In)' | |
Description = 'Inbound rule for PI Data Archive to allow PINET traffic.' | |
Group = 'PI System' | |
Enabled = 'True' | |
Action = 'Allow' | |
Protocol = 'TCP' | |
Service = "PINetMgr" | |
Program = $PINetMgrProgram | |
LocalPort = '5450' | |
Ensure = 'Present' | |
} | |
xFirewall PIDataArchive_ClientConnections_Out | |
{ | |
Direction = 'Outbound' | |
Name = 'PI-Data-Archive-PINET-TCP-Out' | |
DisplayName = 'PI Data Archive PINET (TCP-Out)' | |
Description = 'Outbound rule for PI Data Archive to allow PINET traffic.' | |
Group = 'PI System' | |
Enabled = 'True' | |
Action = 'Allow' | |
Protocol = 'TCP' | |
Service = "PINetMgr" | |
Program = $PINetMgrProgram | |
RemotePort = '49152-65535' | |
Ensure = 'Present' | |
} | |
[string[]]$FirewallRulesEnabledByDefault = @( | |
"WINRM-HTTP-In-TCP", | |
"CoreNet-ICMP4-DUFRAG-In", | |
"CoreNet-IGMP-In", | |
"CoreNet-IGMP-Out", | |
"CoreNet-Teredo-In", | |
"CoreNet-Teredo-Out", | |
"CoreNet-IPHTTPS-In", | |
"CoreNet-IPHTTPS-Out", | |
"CoreNet-GP-NP-Out-TCP", | |
"CoreNet-GP-Out-TCP", | |
"CoreNet-DNS-Out-UDP", | |
"CoreNet-GP-LSASS-Out-TCP" | |
) | |
# Firewall - infrastructure rules to enable | |
ForEach($rule in $FirewallRulesEnabledByDefault) | |
{ | |
xFirewall $rule | |
{ | |
Name = $rule | |
Enabled = 'True' | |
Ensure = 'Present' | |
} | |
} | |
[string[]]$FirewallRulesDisabledByDefault = @( | |
"vm-monitoring-dcom", | |
"vm-monitoring-icmpv4", | |
"vm-monitoring-icmpv6", | |
"vm-monitoring-nb-session", | |
"vm-monitoring-rpc", | |
"SNMPTRAP-In-UDP", | |
"SNMPTRAP-In-UDP-NoScope", | |
"Wininit-Shutdown-In-Rule-TCP-RPC", | |
"Wininit-Shutdown-In-Rule-TCP-RPC-EPMapper", | |
"EventForwarder-In-TCP", | |
"EventForwarder-RPCSS-In-TCP", | |
"NETDIS-UPnPHost-In-TCP", | |
"NETDIS-UPnPHost-Out-TCP", | |
"NETDIS-NB_Name-In-UDP", | |
"NETDIS-NB_Name-Out-UDP", | |
"NETDIS-NB_Datagram-In-UDP", | |
"NETDIS-NB_Datagram-Out-UDP", | |
"NETDIS-WSDEVNTS-In-TCP", | |
"NETDIS-WSDEVNTS-Out-TCP", | |
"NETDIS-WSDEVNT-In-TCP", | |
"NETDIS-WSDEVNT-Out-TCP", | |
"NETDIS-SSDPSrv-In-UDP", | |
"NETDIS-SSDPSrv-Out-UDP", | |
"NETDIS-UPnP-Out-TCP", | |
"NETDIS-FDPHOST-In-UDP", | |
"NETDIS-FDPHOST-Out-UDP", | |
"NETDIS-LLMNR-In-UDP", | |
"NETDIS-LLMNR-Out-UDP", | |
"NETDIS-FDRESPUB-WSD-In-UDP", | |
"NETDIS-FDRESPUB-WSD-Out-UDP", | |
"Netlogon-NamedPipe-In", | |
"Netlogon-TCP-RPC-In", | |
"FPSSMBD-iWARP-In-TCP", | |
"RemoteTask-In-TCP", | |
"RemoteTask-RPCSS-In-TCP", | |
"WINRM-HTTP-Compat-In-TCP", | |
"Microsoft-Windows-PeerDist-HttpTrans-In", | |
"Microsoft-Windows-PeerDist-HttpTrans-Out", | |
"Microsoft-Windows-PeerDist-WSD-In", | |
"Microsoft-Windows-PeerDist-WSD-Out", | |
"Microsoft-Windows-PeerDist-HostedServer-In", | |
"Microsoft-Windows-PeerDist-HostedServer-Out", | |
"Microsoft-Windows-PeerDist-HostedClient-Out", | |
"RemoteDesktop-UserMode-In-TCP", | |
"RemoteDesktop-UserMode-In-UDP", | |
"RemoteDesktop-Shadow-In-TCP", | |
"RRAS-GRE-In", | |
"RRAS-GRE-Out", | |
"RRAS-L2TP-In-UDP", | |
"RRAS-L2TP-Out-UDP", | |
"RRAS-PPTP-In-TCP", | |
"RRAS-PPTP-Out-TCP", | |
"RVM-VDS-In-TCP", | |
"RVM-VDSLDR-In-TCP", | |
"RVM-RPCSS-In-TCP", | |
"MsiScsi-In-TCP", | |
"MsiScsi-Out-TCP", | |
"FPS-NB_Session-In-TCP", | |
"FPS-NB_Session-Out-TCP", | |
"FPS-SMB-In-TCP", | |
"FPS-SMB-Out-TCP", | |
"FPS-NB_Name-In-UDP", | |
"FPS-NB_Name-Out-UDP", | |
"FPS-NB_Datagram-In-UDP", | |
"FPS-NB_Datagram-Out-UDP", | |
"FPS-SpoolSvc-In-TCP", | |
"FPS-RPCSS-In-TCP", | |
"FPS-ICMP4-ERQ-In", | |
"FPS-ICMP4-ERQ-Out", | |
"FPS-ICMP6-ERQ-In", | |
"FPS-ICMP6-ERQ-Out", | |
"FPS-LLMNR-In-UDP", | |
"FPS-LLMNR-Out-UDP", | |
"RemoteEventLogSvc-In-TCP", | |
"RemoteEventLogSvc-NP-In-TCP", | |
"RemoteEventLogSvc-RPCSS-In-TCP", | |
"SPPSVC-In-TCP", | |
"PerfLogsAlerts-PLASrv-In-TCP", | |
"PerfLogsAlerts-DCOM-In-TCP", | |
"PerfLogsAlerts-PLASrv-In-TCP-NoScope", | |
"PerfLogsAlerts-DCOM-In-TCP-NoScope", | |
"SLBM-MUX-IN-TCP", | |
"RemoteSvcAdmin-In-TCP", | |
"RemoteSvcAdmin-NP-In-TCP", | |
"RemoteSvcAdmin-RPCSS-In-TCP", | |
"TPMVSCMGR-RPCSS-In-TCP-NoScope", | |
"TPMVSCMGR-Server-In-TCP-NoScope", | |
"TPMVSCMGR-Server-Out-TCP-NoScope", | |
"TPMVSCMGR-RPCSS-In-TCP", | |
"TPMVSCMGR-Server-In-TCP", | |
"TPMVSCMGR-Server-Out-TCP", | |
"MSDTC-In-TCP", | |
"MSDTC-Out-TCP", | |
"MSDTC-KTMRM-In-TCP", | |
"MSDTC-RPCSS-In-TCP", | |
"RemoteFwAdmin-In-TCP", | |
"RemoteFwAdmin-RPCSS-In-TCP", | |
"WMI-RPCSS-In-TCP", | |
"WMI-WINMGMT-In-TCP", | |
"WMI-WINMGMT-Out-TCP", | |
"WMI-ASYNC-In-TCP" | |
) | |
$FirewallRulesDisabledBySelection = @( | |
"AllJoyn-Router-In-TCP", | |
"AllJoyn-Router-Out-TCP", | |
"AllJoyn-Router-In-UDP", | |
"AllJoyn-Router-Out-UDP", | |
"WINRM-HTTP-In-TCP-PUBLIC", | |
"Microsoft-Windows-Unified-Telemetry-Client", | |
"CoreNet-ICMP6-DU-In", | |
"CoreNet-ICMP6-PTB-In", | |
"CoreNet-ICMP6-PTB-Out", | |
"CoreNet-ICMP6-TE-In", | |
"CoreNet-ICMP6-TE-Out", | |
"CoreNet-ICMP6-PP-In", | |
"CoreNet-ICMP6-PP-Out", | |
"CoreNet-ICMP6-NDS-In", | |
"CoreNet-ICMP6-NDS-Out", | |
"CoreNet-ICMP6-NDA-In", | |
"CoreNet-ICMP6-NDA-Out", | |
"CoreNet-ICMP6-RA-In", | |
"CoreNet-ICMP6-RA-Out", | |
"CoreNet-ICMP6-RS-In", | |
"CoreNet-ICMP6-RS-Out", | |
"CoreNet-ICMP6-LQ-In", | |
"CoreNet-ICMP6-LQ-Out", | |
"CoreNet-ICMP6-LR-In", | |
"CoreNet-ICMP6-LR-Out", | |
"CoreNet-ICMP6-LR2-In", | |
"CoreNet-ICMP6-LR2-Out", | |
"CoreNet-ICMP6-LD-In", | |
"CoreNet-ICMP6-LD-Out", | |
"CoreNet-IPv6-In", | |
"CoreNet-IPv6-Out", | |
"CoreNet-DHCPV6-In", | |
"CoreNet-DHCPV6-Out", | |
"CoreNet-DHCP-In", | |
"CoreNet-DHCP-Out", | |
"MDNS-In-UDP", | |
"MDNS-Out-UDP" | |
) | |
# Firewall - infrastructurs rules to disable | |
$FirewallRulesToDisable = $FirewallRulesDisabledByDefault + $FirewallRulesDisabledBySelection | |
ForEach($rule in $FirewallRulesToDisable) | |
{ | |
xFirewall $rule | |
{ | |
Name = $rule | |
Enabled = 'False' | |
Ensure = 'Present' | |
} | |
} | |
#endregion | |
#region Registry | |
$RegistryKey = 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\' | |
Registry "$RegistryKey\DisabledComponents" | |
{ | |
Ensure = 'Present' | |
Key = $RegistryKey | |
ValueName = 'DisabledComponents' | |
ValueData = 255 | |
ValueType = 'DWORD' | |
} | |
$RegistryKey = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient\' | |
Registry "$RegistryKey\EnableMulticast" | |
{ | |
Ensure = 'Present' | |
Key = $RegistryKey | |
ValueName = 'EnableMulticast' | |
ValueData = 0 | |
ValueType = 'DWORD' | |
} | |
#endregion | |
#region Windows Features | |
[string[]]$ApprovedFeatures = @( | |
'FileAndStorage-Services', | |
'Storage-Services', | |
'NET-Framework-45-Features', | |
'NET-Framework-45-Core', | |
'NET-WCF-Services45', | |
'NET-WCF-TCP-PortSharing45', | |
'EnhancedStorage', | |
'Windows-Defender-Features', | |
'Windows-Defender', | |
'PowerShellRoot', | |
'PowerShell', | |
'WoW64-Support' | |
) | |
$AllFeatures = Get-WindowsFeature | Select-Object -ExpandProperty Name | |
Foreach($Feature in $AllFeatures) | |
{ | |
if(!($Feature -in $ApprovedFeatures)) | |
{ | |
WindowsFeatureSet $( $Feature + '_Disable' ) | |
{ | |
Name = $Feature | |
Ensure = 'Absent' | |
} | |
} | |
} | |
#endregion | |
#region Windows Services | |
[String[]]$ServicesToDisable = @() | |
# Optional PI services to disable | |
$ServicesToDisable += @( | |
"PIAFLink", | |
"PIBaGen", | |
"pibatch", | |
"pibufss", | |
"PIDirectoryPublisher", | |
"pilogsrv", | |
"pilogsrvX64", | |
"pirecalc" | |
) | |
# Remaining OS Services not needed for PI Data Archive. | |
$ServicesToDisable += @( | |
"AppMgmt", | |
"DiagTrack", | |
"sacsvr", | |
"SNMPTRAP", | |
"seclogon", | |
"WinHttpAutoProxySvc" | |
) | |
# Services disabled by default | |
$ServicesToDisable += @( | |
"tzautoupdate", | |
"Browser", | |
"AppVClient", | |
"NetTcpPortSharing", | |
"CscService", | |
"RemoteAccess", | |
"SCardSvr", | |
"UevAgentService" | |
"WSearch" | |
) | |
# Services MS recommends disabling | |
$ServicesToDisable += @( | |
"XblAuthManager", | |
"XblGameSave" | |
) | |
# Services MS indicates as "OK to disable" | |
$ServicesToDisable += @( | |
"AxInstSV", | |
"bthserv", | |
"CDPUserSvc", | |
"PimIndexMaintenanceSvc" | |
"dmwappushservice", | |
"MapsBroker", | |
"lfsvc", | |
"SharedAccess", | |
"lltdsvc", | |
"wlidsvc", | |
"NgcSvc", | |
"NgcCtnrSvc", | |
"NcbService", | |
"PhoneSvc", | |
"PcaSvc", | |
"QWAVE", | |
"RmSvc", | |
"SensorDataService", | |
"SensrSvc", | |
"SensorService", | |
"ShellHWDetection", | |
"ScDeviceEnum", | |
"SSDPSRV", | |
"WiaRpc", | |
"OneSyncSvc", | |
"TabletInputService", | |
"upnphost", | |
"UserDataSvc", | |
"UnistoreSvc", | |
"WalletService", | |
"Audiosrv", | |
"AudioEndpointBuilder", | |
"FrameServer", | |
"stisvc", | |
"wisvc", | |
"icssvc", | |
"WpnService", | |
"WpnUserService" | |
) | |
# Services OK to disable if not a DC or print server | |
$ServicesToDisable += @('Spooler') | |
# Services OK to disable if not a print server | |
$ServicesToDisable += @('PrintNotify') | |
$InstalledServices = Get-Service | |
foreach($Service in $ServicesToDisable) | |
{ | |
if($InstalledServices.Name -contains $Service) | |
{ | |
Service $( 'DisabledService_' + $Service ) | |
{ | |
Name = $Service | |
StartupType = "Disabled" | |
State = "Stopped" | |
} | |
} | |
} | |
#endregion | |
} | |
} | |
AttackSurfaceReduction |
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
# PS script for WSH | |
$Program = "%piserver%bin\pinetmgr.exe" | |
$Service = "PINetMgr" | |
$LocalPort = "5450" | |
$RemotePort = "49152-65535" | |
$Protocol = "TCP" | |
$WSHRules = @( | |
@{ | |
Name = "Inbound service restriction rule for $Service" | |
Action = "Block" | |
Direction = "Inbound" | |
}, | |
@{ | |
Name = "Outbound service restriction rule for $Service" | |
Action = "Block" | |
Direction = "Outbound" | |
}, | |
@{ | |
Name = "Allow only TCP $LocalPort inbound to $Service" | |
Action = "Allow" | |
Direction = "Inbound" | |
Protocol = $Protocol | |
LocalPort = $LocalPort | |
}, | |
@{ | |
Name = "Allow only TCP $RemotePort outbound from $Service" | |
Action = "Allow" | |
Direction = "Outbound" | |
Protocol = $Protocol | |
RemotePort = $RemotePort | |
} | |
) | |
# Loop through the rules and apply. | |
foreach($Rule in $WSHRules) | |
{ | |
# Include the proper scope on each rule | |
$Rule += @{ | |
DisplayName = $Rule.Name | |
Program = $Program | |
Service = $Service | |
Enabled = "TRUE" | |
PolicyStore = "ConfigurableServiceStore" | |
} | |
New-NetFirewallRule @Rule | |
} |
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
' VB script for WSH for PINetMgr | |
' MSDN has documented examples | |
' Ref: Restricting Service, WFAS on MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366327(v=vs.85).aspx) | |
option explicit | |
' IP protocol | |
const NET_FW_IP_PROTOCOL_TCP = 6 | |
' Action | |
const NET_FW_ACTION_ALLOW = 1 | |
' Direction | |
const NET_FW_RULE_DIR_IN = 1 | |
const NET_FW_RULE_DIR_OUT = 2 | |
' Create the FwPolicy2 object. | |
Dim fwPolicy2 | |
Set fwPolicy2 = CreateObject("HNetCfg.FwPolicy2") | |
' Get the Service Restriction object for the local firewall policy. | |
Dim ServiceRestriction | |
Set ServiceRestriction = fwPolicy2.ServiceRestriction | |
' Put in block-all inbound and block-all outbound Windows Service Hardening (WSH) networking rules for the service | |
ServiceRestriction.RestrictService "PINetMgr", "%piserver%\bin\pinetmgr.exe", TRUE, FALSE | |
' Get the collection of Windows Service Hardening networking rules | |
Dim wshRules | |
Set wshRules = ServiceRestriction.Rules | |
' Add inbound WSH allow rule for service PINetMgr | |
Dim NewInboundRule | |
Set NewInboundRule = CreateObject("HNetCfg.FWRule") | |
NewInboundRule.Name = "Allow only TCP 5450 inbound to service" | |
NewInboundRule.ApplicationName = "%piserver%bin\pinetmgr.exe" | |
NewInboundRule.ServiceName = "PINetMgr" | |
NewInboundRule.Protocol = NET_FW_IP_PROTOCOL_TCP | |
NewInboundRule.LocalPorts = 5450 | |
NewInboundRule.Action = NET_FW_ACTION_ALLOW | |
NewInboundRule.Direction = NET_FW_RULE_DIR_IN | |
NewInboundRule.Enabled = true | |
' Add the inbound allow rule | |
wshRules.Add NewInboundRule | |
' Add outbound WSH allow rules for PINetMgr | |
Dim NewOutboundRule | |
Set NewOutboundRule = CreateObject("HNetCfg.FWRule") | |
NewOutboundRule.Name = "Allow outbound traffic from service" | |
NewOutboundRule.ApplicationName = "%piserver%bin\pinetmgr.exe" | |
NewOutboundRule.ServiceName = "PINetMgr" | |
NewOutboundRule.Protocol = NET_FW_IP_PROTOCOL_TCP | |
NewOutboundRule.RemotePorts = "49152-65535" | |
NewOutboundRule.Action = NET_FW_ACTION_ALLOW | |
NewOutboundRule.Direction = NET_FW_RULE_DIR_OUT | |
NewOutboundRule.Enabled = true | |
' Add the outbound allow rule | |
wshRules.Add NewOutboundRule |
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
Configuration PINetMgrWSH | |
{ | |
param( | |
$ComputerName="localhost", | |
$Service="PINetMgr", | |
$Program="%piserver%bin\pinetmgr.exe", | |
$LocalPort = "5450", | |
$RemotePort = "49152-65535", | |
[ValidateSet("TCP","UDP")] | |
$Protocol = "TCP" | |
) | |
Import-DscResource -ModuleName PSDesiredStateConfiguration | |
Node $ComputerName | |
{ | |
switch($Protocol) | |
{ | |
"TCP" {$ProtocolID = "6"} | |
"UDP" {$ProtocolID = "17"} | |
} | |
$ConfigurableServiceStore = "HKLM:\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System" | |
$Version = "v2.26" | |
$AllowInRuleName = "Allow only $Protocol $LocalPort inbound to $Service" | |
Registry $AllowInRuleName | |
{ | |
Ensure = 'Present' | |
Key = $ConfigurableServiceStore | |
ValueData = "$Version|Action=Allow|Active=TRUE|Dir=In|" + ` | |
"Protocol=$ProtocolID|" + ` | |
"LPort=$LocalPort|" + ` | |
"App=$Program|" + ` | |
"Svc=$Service|" + ` | |
"Name=$AllowInRuleName|" | |
ValueName = $AllowInRuleName | |
ValueType = 'String' | |
} | |
$AllowOutRuleName = "Allow only $Protocol $RemotePort outbound from $Service" | |
Registry $AllowOutRuleName | |
{ | |
Ensure = 'Present' | |
Key = $ConfigurableServiceStore | |
ValueData = "$Version|Action=Allow|Active=TRUE|Dir=Out|" + ` | |
"Protocol=$ProtocolID|" + ` | |
"RPort2_10=$RemotePort|" + ` | |
"App=$Program|" + ` | |
"Svc=$Service|" + ` | |
"Name=$AllowOutRuleName|" | |
ValueName = $AllowOutRuleName | |
ValueType = 'String' | |
} | |
$RestrictInRuleName = "Inbound service restriction rule for $Service" | |
Registry $RestrictInRuleName | |
{ | |
Ensure = 'Present' | |
Key = $ConfigurableServiceStore | |
ValueData = "$Version|Action=Block|Active=TRUE|Dir=In|" + ` | |
"App=$Program|" + ` | |
"Svc=$Service|" + ` | |
"Name=$RestrictInRuleName|" | |
ValueName = $RestrictInRuleName | |
ValueType = 'String' | |
} | |
$RestrictOutRuleName = "Outbound service restriction rule for $Service" | |
Registry $RestrictOutRuleName | |
{ | |
Ensure = 'Present' | |
Key = $ConfigurableServiceStore | |
ValueData = "$Version|Action=Block|Active=TRUE|Dir=Out|" + ` | |
"App=$Program|" + ` | |
"Svc=$Service|" + ` | |
"Name=$RestrictOutRuleName|" | |
ValueName = $RestrictOutRuleName | |
ValueType = 'String' | |
} | |
} | |
} | |
PINetMgrWSH |
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
# Tested with Server 2016 and Server 2012 R2, PS 4 and PS 5 | |
Configuration StrongCipherSettings | |
{ | |
param | |
( | |
$ComputerName = "localhost", | |
# TLS/SSL Security Considerations | |
# https://technet.microsoft.com/en-us/library/dn786446(v=ws.11).aspx | |
$schannelProtocols = @{ | |
"PCT 1.0"=$false; | |
"SSL 2.0"=$false; | |
"SSL 3.0"=$false; | |
"TLS 1.0"=$false; | |
"TLS 1.1"=$true; | |
"TLS 1.2"=$true | |
}, | |
$schannelCiphers = @{ | |
"NULL"=$false; | |
"DES 56/56"=$false; | |
"RC2 40/128"=$false; | |
"RC2 56/128"=$false; | |
"RC2 128/128"=$false; | |
"RC4 40/128"=$false; | |
"RC4 56/128"=$false; | |
"RC4 64/128"=$false; | |
"RC4 128/128"=$false; | |
"Triple DES 168"=$true; | |
"AES 128/128"=$true; | |
"AES 256/256"=$true | |
}, | |
[string[]]$cipherSuites = @( | |
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384", | |
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256", | |
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256", | |
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256", | |
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256", | |
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256", | |
"TLS_RSA_WITH_AES_256_CBC_SHA256", | |
"TLS_RSA_WITH_AES_128_CBC_SHA256", | |
"TLS_RSA_WITH_AES_256_CBC_SHA", | |
"TLS_RSA_WITH_AES_128_CBC_SHA" | |
) | |
) | |
Import-DSCResource -ModuleName 'xPSDesiredStateConfiguration' | |
Node $ComputerName | |
{ | |
# Value of 0 disables, 1 enables protocol or cipher | |
# https://technet.microsoft.com/en-us/library/dn786418(v=ws.11).aspx#BKMK_SchannelTR_Ciphers | |
$EnabledValue = "1" | |
$DisabledValue = "0" | |
$cryptographyKeyPath = 'HKLM:\System\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002\' | |
xRegistry $($cryptographyKeyPath + 'Functions') | |
{ | |
ValueName = 'Functions' | |
ValueType = 'MultiString' | |
Key = $cryptographyKeyPath | |
ValueData = $cipherSuites | |
Force = $true | |
} | |
$schannelKeyPath = "HKLM:\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\" | |
foreach ($cipher in $schannelCiphers.GetEnumerator()) | |
{ | |
if($cipher.Value) { $ValueData = $EnabledValue } | |
else { $ValueData = $DisabledValue } | |
$TargetPath = $($schannelKeyPath + 'Ciphers\' + $cipher.Name) | |
xRegistry $($TargetPath + '\Enabled') | |
{ | |
ValueName = 'Enabled' | |
ValueType = 'DWORD' | |
Key = $TargetPath | |
ValueData = $ValueData | |
Force = $true | |
} | |
} | |
foreach ($protocol in $schannelProtocols.GetEnumerator()) | |
{ | |
if($protocol.Value) { $ValueData = $EnabledValue } | |
else { $ValueData = $DisabledValue } | |
foreach($Role in @('Server','Client')) | |
{ | |
$TargetPath = $($schannelKeyPath + 'Protocols\' + $protocol.Name + '\' + $Role) | |
xRegistry $($TargetPath + '\Enabled') | |
{ | |
ValueName = 'Enabled' | |
ValueType = 'DWORD' | |
Key = $TargetPath | |
ValueData = $ValueData | |
Force = $true | |
} | |
} | |
} | |
} | |
} | |
StrongCipherSettings |
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
# Add PI Data Archive antivirus exceptions per KB01062 to Windows Defender in Windows 10 and Server 2016 | |
param( | |
[string]$ArchiveFolder = "C:\Program Files\PI\arc\", | |
[string]$ArchiveFileExtenstion = ".arc", | |
[string]$QueueFolder = "C:\Program Files\PI\queue\" | |
) | |
# PI Message logs | |
$Logs = ($env:PISERVER + "log\*.dat") | |
# Archive files | |
$Archives = ($ArchiveFolder + "*" + $ArchiveFileExtenstion) | |
# Annotation files associated with archives | |
$ArchiveAnnotations = ($Archives + ".ann") | |
# Archives for future data | |
$FutureArchives = ($ArchiveFolder + "future\*" + $ArchiveFileExtenstion) | |
$FutureArchiveAnnotations = ($FutureArchives + ".ann") | |
# Event queues | |
$Queues = ($QueueFolder + "*.dat") | |
$ExclusionPaths = @( | |
$Logs, | |
$Archives, | |
$ArchiveAnnotations, | |
$FutureArchives, | |
$FutureArchiveAnnotations, | |
$Queues | |
) | |
# Loop through adding the paths as | |
ForEach($ExclusionPath in $ExclusionPaths) | |
{ | |
Add-MpPreference -ExclusionPath $ExclusionPath -Verbose | |
} |
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
Configuration EnableVBS | |
{ | |
param( | |
[String]$NodeName="localhost" | |
) | |
Import-DscResource -ModuleName PSDesiredStateConfiguration | |
Node $NodeName | |
{ | |
#region Windows Defender | |
# Enable Device Guard | |
# https://docs.microsoft.com/en-us/windows/device-security/device-guard/deploy-device-guard-enable-virtualization-based-security | |
$DGRegistryKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard' | |
Registry "$DGRegistryKey\EnableVirtualizationBasedSecurity" | |
{ | |
Ensure = 'Present' | |
Key = $DGRegistryKey | |
ValueName = 'EnableVirtualizationBasedSecurity' | |
ValueData = 1 | |
ValueType = 'DWORD' | |
} | |
Registry "$DGRegistryKey\RequirePlatformSecurityFeatures" | |
{ | |
Ensure = 'Present' | |
Key = $DGRegistryKey | |
ValueName = 'RequirePlatformSecurityFeatures' | |
ValueData = 1 | |
ValueType = 'DWORD' | |
} | |
Registry "$DGRegistryKey\Locked" | |
{ | |
Ensure = 'Present' | |
Key = $DGRegistryKey | |
ValueName = 'Locked' | |
ValueData = 0 | |
ValueType = 'DWORD' | |
} | |
# Enable application control | |
$HVCIRegistryKey = $DGRegistryKey + '\Scenarios\HypervisorEnforcedCodeIntegrity' | |
Registry "$HVCIRegistryKey\Enabled" | |
{ | |
Ensure = 'Present' | |
Key = $HVCIRegistryKey | |
ValueName = 'Enabled' | |
ValueData = 1 | |
ValueType = 'DWORD' | |
} | |
Registry "$HVCIRegistryKey\Locked" | |
{ | |
Ensure = 'Present' | |
Key = $HVCIRegistryKey | |
ValueName = 'Locked' | |
ValueData = 0 | |
ValueType = 'DWORD' | |
} | |
# Enable Credential Guard | |
# https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard-manage | |
$LSARegistryKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\LSA' | |
Registry "$LSARegistryKey\LsaCfgFlags" | |
{ | |
Ensure = 'Present' | |
Key = $LSARegistryKey | |
ValueName = 'LsaCfgFlags' | |
ValueData = 1 | |
ValueType = 'DWORD' | |
} | |
} | |
} | |
EnableVBS |
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
# https://blogs.technet.microsoft.com/datacentersecurity/2016/09/20/overview-of-device-guard-in-windows-server-2016/ | |
$policyBase = $($home + '\Documents\PublisherSiPolicy.xml') | |
$policyMS = $($home + '\Documents\MSBlockSiPolicy.xml') | |
$policyConfig = $($home + '\Documents\SiPolicy.xml') | |
$policyBin = $($home + '\Documents\SiPolicy.bin') | |
$policyP7B = $($env:WinDir + '\System32\CodeIntegrity\SiPolicy.p7b') | |
<# | |
# The base policy is generated with New-CIPolicy | |
# This command takes significant time to scan the machine | |
# We will leverage an existing file for the live demo | |
New-CIPolicy -Level Publisher -Fallback Hash -UserPEs -FilePath $policyBase | |
#> | |
# Merge in Microsoft recommended policy to reduce available bypasses | |
# https://docs.microsoft.com/en-us/windows/security/threat-protection/device-guard/steps-to-deploy-windows-defender-application-control | |
Merge-CIPolicy -PolicyPaths $policyBase, $policyMS -OutputFilePath $policyConfig | |
# Alter Policy to Enforce | |
Set-RuleOption -FilePath $policyConfig -Option 3 -delete | |
# Convert the CI Policy to the binary format and deploy it | |
ConvertFrom-CIPolicy $policyConfig $policyBin | |
Copy-Item $policyBin $policyP7B -Verbose |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment