0x00 前言简述
最近单位在做等保测评,由本人从事安全运维方面的工作(PS:曾经做过等保等方面的安全服务),所以自然而然的与信安的测评人员一起对接相关业务系统的检查,在做主机系统测评检查时发现了系统中某些配置不符合等保要求,需要对不满足要求的主机做进一步整改,好在我们众多的系统基本都是运行在虚拟机上搭建的kubernetes集群中,这样一来就可以尽可能减少加固系统给应用带来的影响,我们可以一台一台加固更新。
在这样环境的驱动下不得不将通宵熬夜,我准备好了枸杞和保温杯,当然也把测试环境也准备了一套,并将以前写的安全加固脚本进行重新整理,根据当前业务服务器系统版本进行更新和测试。(我还年轻,我还可加班!)
我们企业内部主要有WindowsServer2019
、CentOS7
、以及Ubuntu20.04
三类操作系统,可以看出操作系统版本都还是比较新的,所以在下面的安全配置核查脚本以及安全加固脚本主要针对上述的三个版本的操作系统。
Linux 系统中采用Shell脚本、WiindowsServer系统中采用的是PowerShell脚本进行编写, 注意脚本会有一定更新建议通过下面的项目地址获取最新的脚本
。
Github 项目地址: https://github.com/WeiyiGeek/SecOpsDev/blob/master/OS-%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F 【 】,欢迎大家 Star 与 Fork 。
原文链接: 完整的Windows与Linux服务器系统安全加固实践和基线检测脚本(等保2.0)( https://mp.weixin.qq.com/s/CDGzTzrAk9vJtbH4BisSlw )
WindowsSever 2019 安全配置策略基线配置核查效果图
WindowsSever2019 主机测评项安全加固效果图
温馨提示: 下面脚本有点长,需要有一定的耐心哟。
0x01 WindowServer2019 配置核查与安全加固
Windows 加固项目地址: https://github.com/WeiyiGeek/SecOpsDev/tree/master/OS-%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows
Windows Server 安全配置策略基线加固项
- 系统账号策略
- 系统事件审核策略
- 系统组策略安全选项策略
- 注册表相关安全策略
- 防火墙服务相关安全策略
- 针对于系统暂无办法通过注册表以及组策略配置的安全加固项
- 从微软安全中心拉取服务器安全补丁列表信息与本地已打补丁做比较
废话不多,上才艺(脚本 )
Windows Server 安全配置策略基线检测脚本
Link: https://github.com/WeiyiGeek/SecOpsDev/blob/master/OS-%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/WindowsSecurityBaseLine.ps1
[Cmdletbinding()]
param(
[Parameter(Mandatory=$true)][String]$Executor,
[Boolean]$MsrcUpdate
)
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
Function F_IsCurrentUserAdmin
{
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
function F_Logging {
param (
[Parameter(Mandatory=$true)]$Msg,
[ValidateSet("Info","Warning","Error")]$Level
)
switch ($Level) {
Info {
Write-Host "[INFO] ${Msg}" -ForegroundColor Green;
}
Warning {
Write-Host "[WARN] ${Msg}" -ForegroundColor Yellow;
}
Error {
Write-Host "[ERROR] ${Msg}" -ForegroundColor Red;
}
Default {
Write-Host "[*] F_Logging 日志 Level 等级错误`n Useage: F_Logging -Level [Info|Warning|Error] -Msg '测试输出字符串'" -ForegroundColor Red;
}
}
}
function F_Tools {
param (
[Parameter(Mandatory=$true)][String]$Key,
[Parameter(Mandatory=$true)]$Value,
[Parameter(Mandatory=$true)]$DefaultValue,
[String]$Msg,
[String]$Operator
)
if ( $Operator -eq "eq" ) {
if ( $Value -eq $DefaultValue ) {
$Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
return $Result
} else {
$Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
return $Result
}
} elseif ($Operator -eq "ne" ) {
if ( $Value -ne $DefaultValue ) {
$Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
return $Result
} else {
$Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
return $Result
}
} elseif ($Operator -eq "le") {
if ( $Value -le $DefaultValue ) {
$Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
return $Result
} else {
$Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
return $Result
}
} elseif ($Operator -eq "ge") {
if ( $Value -ge $DefaultValue ) {
$Result = @{"$($Key)"="[合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准."}
Write-Host "$($Key)"=" [合格项]|$($Value)|$($DefaultValue)|$($Msg)-【符合】等级保护标准." -ForegroundColor White
return $Result
} else {
$Result = @{"$($Key)"="[异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准."}
Write-Host "$($Key)"=" [异常项]|$($Value)|$($DefaultValue)|$($Msg)-【不符合】等级保护标准." -ForegroundColor red
return $Result
}
}
}
function F_GetRegPropertyValue {
param (
[Parameter(Mandatory=$true)][String]$Key,
[Parameter(Mandatory=$true)][String]$Name,
[Parameter(Mandatory=$true)][String]$Operator,
[Parameter(Mandatory=$true)]$DefaultValue,
[Parameter(Mandatory=$true)][String]$Msg
)
try {
$Value = Get-ItemPropertyValue -Path "Registry::$Key" -ErrorAction Ignore -WarningAction Ignore -Name $Name
$Result = F_Tools -Key "Registry::$($Name)" -Value $Value -Operator $Operator -DefaultValue $DefaultValue -Msg $Msg
return $Result
} catch {
$Result = @{"Registry::$($Name)"="[异常项]|$($Key)中$($Name)不存在该项|$($DefaultValue)|$($Msg)"}
Write-Host $Result.Values -ForegroundColor Red
return $Result
}
}
Function F_UrlRequest {
param (
[Parameter(Mandatory=$true)][String]$Msrc_api
)
Write-Host "[-] $($Msrc_api)" -ForegroundColor Gray
$Response=Invoke-WebRequest -Uri "$($Msrc_api)"
Return ConvertFrom-Json -InputObject $Response
}
$SysInfo = @{}
$Item = 'Hostname','OSName','OSVersion','OSManufacturer','OSConfiguration','OS Build Type','RegisteredOwner','RegisteredOrganization','Product ID','Original Install Date','System Boot Time','System Manufacturer','System Model','System Type','Processor(s)','BIOS Version','Windows Directory','System Directory','Boot Device','System Locale','Input Locale','Time Zone','Total Physical Memory','Available Physical Memory','Virtual Memory: Max Size','Virtual Memory: Available','Virtual Memory: In Use','Page File Location(s)','Domain','Logon Server','Hotfix(s)','Network Card(s)'
Function F_SysInfo {
$Computer = systeminfo.exe /FO CSV /S $env:COMPUTERNAME |Select-Object -Skip 1 | ConvertFrom-CSV -Header $Item
foreach( $key in $Item) {
$SysInfo += @{"$($key)"=$Computer.$key}
}
$SysInfo += @{"WindowsProductName"="$($SysInfo.OSName)"}
$SysInfo.OsVersion=($Sysinfo.OSVersion -split " ")[0]
$SysInfo += @{"CsSystemType"=($Sysinfo."System Type" -split " ")[0]}
$SysInfo += @{"PSVersion"=$PSVersionTable.PSEdition+"-"+$PSVersionTable.PSVersion}
$Flag = $SysInfo.WindowsProductName -match "Windows 8.1|Windows 10|Server 2008|Server 2012|Server 2016|Server 2019"
$ProductName = "$($Matches.Values)"
if ( $ProductName.Contains("Windows")) {
$SysInfo += @{"ProductType"="Client"}
$SysInfo += @{"ProductName"=$ProductName}
$SysInfo += @{"WindowsVersion"=Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name ReleaseId}
} else {
$SysInfo += @{"ProductType"="Server"}
$SysInfo += @{"ProductName"=$ProductName}
}
$ComputerType = get-wmiobject win32_computersystem
if ($ComputerType.Manufacturer -match "VMware"){
$SysInfo += @{"ComputerType"="虚拟机 - $($ComputerType.Model)"}
} else {
$SysInfo += @{"ComputerType"="物理机 - $($ComputerType.Model)"}
}
return $SysInfo
}
$SysNetAdapter = @{}
function F_SysNetAdapter {
$Adapter = Get-NetAdapter | Sort-Object -Property LinkSpeed
foreach ( $Item in $Adapter) {
$IPAddress = (Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $Item.ifIndex).IPAddress
$SysNetAdapter += @{"$($Item.MacAddress)"="$($Item.Status) | $($Item.Name) | $($IPAddress) | $($Item.LinkSpeed) | $($Item.InterfaceDescription)"}
}
return $SysNetAdapter
}
$SysDisk = @{}
function F_SysDisk {
$Disk = Get-Disk
foreach ( $Item in $Disk) {
$SysDisk += @{"$($Item.SerialNumber)"="$($Item.Number) | $($Item.FriendlyName) | $($Item.HealthStatus)| $($Item.Size / [math]::Pow(1024,3)) GB | $($Item.PartitionStyle) |$($Item.OperationalStatus)"}
}
$Drive = Get-PSDrive -PSProvider FileSystem | Sort-Object -Property Name
$Drive | % {
$Free = [Math]::Round( $_.Free / [math]::pow(1024,3),2 )
$Used = [Math]::Round( $_.Used / [math]::pow(1024,3),2 )
$Total = [Math]::Ceiling($Free + $Used)
$SysDisk += @{"FileSystem::$($_.Name)"="$($_.Name) | Free: $($Free) GB | Used: $($Used) GB | Total: $($Total) GB"}
}
return $SysDisk
}
$SysAccount = @{}
Function F_SysAccount {
$Account = Get-WmiObject -Class Win32_UserAccount | Select-Object Name,AccountType,Caption,SID
Write-Host "* 当前系统存在的 $($Account.Length) 名账户 : $($Account.Name)" -ForegroundColor Green
if($Acount.Length -ge 4 -and ($Account.sid | Select-String -Pattern "^((?!(-500|-501|-503|-504)).)*$")) {
$Result = @{"SysAccount"="[异常项]-系统中存在其他账号请检查: $($Account.Name)"}
$SysAccount += $Result
}else{
$Result = @{"SysAccount"="[合格项]-系统中无多余其他账号";}
$SysAccount += $Result
}
return $SysAccount
}
$SysAccountPolicy = @{
"MinimumPasswordAge" = @{operator="le";value=1;msg="密码最短留存期"}
"MaximumPasswordAge" = @{operator="le";value=90;msg="密码最长留存期"}
"MinimumPasswordLength" = @{operator="ge";value=14;msg="密码长度最小值"}
"PasswordComplexity" = @{operator="eq";value=1;msg="密码必须符合复杂性要求策略"}
"PasswordHistorySize" = @{operator="ge";value=3;msg="强制密码历史个记住的密码"}
"LockoutBadCount" = @{operator="le";value=6;msg="账户登录失败锁定阈值次数"}
"ResetLockoutCount" = @{operator="ge";value=15;msg="账户锁定时间(分钟)"}
"LockoutDuration" = @{operator="ge";value=15;msg="复位账户锁定计数器时间(分钟)"}
"RequireLogonToChangePassword" = @{operator="eq";value=0;msg="下次登录必须更改密码"}
"ForceLogoffWhenHourExpire" = @{operator="eq";value=0;msg="强制过期"}
"NewAdministratorName" = @{operator="ne";value='"Administrator"';msg="当前系统默认管理账号登陆名称策略"}
"NewGuestName" = @{operator="ne";value='"Guest"';msg="当前系统默认来宾用户登陆名称策略"}
"EnableAdminAccount" = @{operator="eq";value=1;msg="管理员账户停用与启用策略"}
"EnableGuestAccount" = @{operator="eq";value=0;msg="来宾账户停用与启用策略"}
"ClearTextPassword" = @{operator="eq";value=0;msg="指示是否使用可逆加密来存储密码 (除非应用程序要求超过保护密码信息的需要)"}
"LSAAnonymousNameLookup" = @{operator="eq";value=0;msg="启用时此设置允许匿名用户查询本地LSA策略 (0关闭)"}
"CheckResults" = @()
}
Function F_SysAccountPolicy {
$Count = $Config.Count
for ($i=0;$i -lt $Count; $i++){
$Line = $Config[$i] -split " = "
if ($SysAccountPolicy.ContainsKey("$($Line[0])")) {
$Result = F_Tools -Key "SysAccountPolicy::$($Line[0])" -Value $Line[1] -Operator $SysAccountPolicy["$($Line[0])"].Operator -DefaultValue $SysAccountPolicy["$($Line[0])"].Value -Msg "系统账号策略配置-$($SysAccountPolicy["$($Line[0])"].Msg)"
$SysAccountPolicy['CheckResults'] += $Result
}
if ( $Line[0] -eq "[Event Audit]" ) { break;}
}
return $SysAccountPolicy['CheckResults']
}
$SysEventAuditPolicy = @{
AuditSystemEvents = @{operator="eq";value=3;msg="审核系统事件"}
AuditLogonEvents = @{operator="eq";value=3;msg="审核登录事件"}
AuditObjectAccess = @{operator="eq";value=3;msg="审核对象访问"}
AuditPrivilegeUse = @{operator="ge";value=2;msg="审核特权使用"}
AuditPolicyChange = @{operator="eq";value=3;msg="审核策略更改"}
AuditAccountManage = @{operator="eq";value=3;msg="审核账户管理"}
AuditProcessTracking = @{operator="ge";value=2;msg="审核过程追踪"}
AuditDSAccess = @{operator="ge";value=2;msg="审核目录服务访问"}
AuditAccountLogon = @{operator="eq";value=3;msg="审核账户登录事件"}
CheckResults = @()
}
function F_SysEventAuditPolicy {
$Count = $Config.Count
for ($i=0;$i -lt $Count; $i++){
$Line = $Config[$i] -split " = "
if ( $Line[0] -eq "[Registry Values]" ) { break;}
if ($SysEventAuditPolicy.ContainsKey("$($Line[0])")) {
$Result = F_Tools -Key "SysEventAuditPolicy::$($Line[0])" -Value $Line[1] -Operator $SysEventAuditPolicy["$($Line[0])"].Operator -DefaultValue $SysEventAuditPolicy["$($Line[0])"].Value -Msg "系统账号策略配置-$($SysEventAuditPolicy["$($Line[0])"].Msg)"
$SysEventAuditPolicy['CheckResults'] += $Result
}
}
return $SysEventAuditPolicy['CheckResults']
}
$SysUserPrivilegePolicy = @{
SeShutdownPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="操作系统本地关机策略"}
SeRemoteShutdownPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="操作系统远程关机策略"}
SeProfileSingleProcessPrivilege = @{operator="eq";value='*S-1-5-32-544';msg="取得文件或其他对象的所有权限策略"}
SeNetworkLogonRight = @{operator="eq";value='*S-1-5-32-544,*S-1-5-32-545,*S-1-5-32-551';msg="从网络访问此计算机策略"}
CheckResults = @()
}
Function F_SysUserPrivilegePolicy {
$Hash = $SysUserPrivilegePolicy.Clone()
foreach ( $Name in $Hash.keys) {
if ( $Name.Equals("CheckResults")){ continue; }
$Line = ($Config | Select-String $Name.toString()) -split " = "
$Result = F_Tools -Key "SysUserPrivilegePolicy::$($Line[0])" -Value $Line[1] -Operator $SysUserPrivilegePolicy["$($Line[0])"].Operator -DefaultValue $SysUserPrivilegePolicy["$($Line[0])"].Value -Msg "策略组用户权限配置-$($SysUserPrivilegePolicy["$($Line[0])"].Msg)"
$SysUserPrivilegePolicy['CheckResults'] += $Result
}
return $SysUserPrivilegePolicy['CheckResults']
}
$SysSecurityOptionPolicy = @{
LimitBlankPasswordUse = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse=4,1";msg="帐户-使用空密码的本地帐户只允许进行控制台登录(启用)"}
DontDisplayLastUserName = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName=4,1";msg="交互式登录-不显示上次登录用户名值(启用)"}
DontDisplayUserName = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayUserName=4,1";msg="交互式登录: 登录时不显示用户名"}
DontDisplayLockedUserId = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLockedUserId=4,3";msg="交互式登录: 锁定会话时显示用户信息(不显示任何信息)"}
DisableCAD = @{operator="eq";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableCAD=4,0";msg="交互式登录-无需按CTRL+ALT+DEL值(禁用)"}
InactivityTimeoutSecs = @{operator="le";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs=4,600";msg="交互式登录-计算机不活动限制值为600秒或更少"}
MaxDevicePasswordFailedAttempts = @{operator="le";value="MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\MaxDevicePasswordFailedAttempts=4,10";msg="交互式登录: 此策略设置确定可导致计算机重启的失败登录尝试次数"}
LegalNoticeCaption = @{operator="eq";value='MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeCaption=1,"安全登陆"';msg="交互式登录: 试图登录的用户的消息标题"}
LegalNoticeText = @{operator="eq";value='MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText=7,请谨慎的操作服务器中数据,您所有操作将被记录审计';msg="交互式登录: 试图登录的用户的消息文本"}
EnablePlainTextPassword = @{operator="eq";value="MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnablePlainTextPassword=4,0";msg="Microsoft网络客户端-将未加密的密码发送到第三方 SMB 服务器(禁用)"}
AutoDisconnect = @{operator="eq";value="MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\AutoDisconnect=4,15";msg="Microsoft网络服务器-暂停会话前所需的空闲时间数量值为15分钟"}
NoLMHash = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash=4,1";msg="网络安全-在下一次改变密码时不存储LAN管理器哈希值(启用)"}
RestrictAnonymousSAM = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymousSAM=4,1";msg="网络访问-不允许SAM账户的匿名枚举值为(启用)"}
RestrictAnonymous = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymous=4,1";msg="网络访问-不允许SAM账户和共享的匿名枚举值为(启用)"}
ClearPageFileAtShutdown = @{operator="eq";value="MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\ClearPageFileAtShutdown=4,0";msg="关机-设置确定是否可以在无需登录 Windows 的情况下关闭计算机(禁用)"}
"CheckResults" = @()
}
Function F_SysSecurityOptionPolicy {
$Hash = $SysSecurityOptionPolicy.Clone()
foreach ( $Name in $Hash.keys) {
if ( $Name.Equals("CheckResults")){ continue; }
$Flag = $Config | Select-String $Name.toString()
$Value = $SysSecurityOptionPolicy["$($Name)"].Value -split ","
if ( $Flag ) {
$Line = $Flag -split ","
$Result = F_Tools -Key "SysSecurityOptionPolicy::$($Name)" -Value $Line[1] -Operator $SysSecurityOptionPolicy["$($Name)"].Operator -DefaultValue $Value[1] -Msg "策略组安全选项配置-$($SysSecurityOptionPolicy["$($Name)"].Msg)"
$SysSecurityOptionPolicy['CheckResults'] += $Result
} else {
$Result = @{"SysSecurityOptionPolicy::$($Name)"="[异常项]|未配置|$($Value[1])|策略组安全选项配置-$($SysSecurityOptionPolicy["$($Name)"].Msg)-【不符合】等级保护标准."}
$SysSecurityOptionPolicy['CheckResults'] += $Result
}
}
return $SysSecurityOptionPolicy['CheckResults']
}
$SysRegistryPolicy = @{
ScreenSaveActive = @{regname="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaveActive";operator="eq";value=1;msg="系统基配核查-屏幕自动保护程序策略"}
ScreenSaverIsSecure = @{regname="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaverIsSecure";operator="eq";value=1;msg="系统基配核查-屏幕恢复时使用密码保护策略"}
ScreenSaveTimeOut = @{regname="HKEY_CURRENT_USER\Control Panel\Desktop";name="ScreenSaveTimeOut";operator="le";value=600;msg="系统基配核查-屏幕保护程序启动时间策略"}
DisableAutoplay = @{regname="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";name="DisableAutoplay";regtype="DWord";operator="eq";value=1;msg="禁止全部驱动器自动播放"}
NoDriveTypeAutoRun = @{regname="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";name="NoDriveTypeAutoRun";regtype="DWord";operator="eq";value=255;msg="禁止全部驱动器自动播放"}
restrictanonymous = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa";name="restrictanonymous";operator="eq";value=1;msg="系统网络基配核查-关闭默认共享盘策略"}
restrictanonymoussam = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa";name="restrictanonymoussam";regtype="DWord";operator="eq";value=1;msg="不允许SAM账户的匿名枚举值为(启用)"}
AutoShareWks = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters";name="AutoShareWks";regtype="DWord";operator="eq";value=0;msg="关闭禁用默认共享策略-Server2012"}
AutoShareServer = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters";name="AutoShareServer";regtype="DWord";operator="eq";value=0;msg="关闭禁用默认共享策略-Server2012"}
EventlogSystemMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\System";name="MaxSize";operator="ge";value=41943040;msg="系统基日志配核查-系统日志查看器大小设置策略"}
EventlogApplicationMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application";name="MaxSize";operator="ge";value=41943040;msg="系统日志基配核查-应用日志查看器大小设置策略"}
EventlogSecurityMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Security";name="MaxSize";operator="ge";value=41943040;msg="系统日志基配核查-安全日志查看器大小设置策略"}
EventlogPSMaxSize = @{regname="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Windows PowerShell";name="MaxSize";operator="ge";value=31457280;msg="系统日志基配核查-PS日志查看器大小设置策略"}
DomainEnableFirewall = @{regname='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="开启域网络防火墙"}
StandardEnableFirewall = @{regname='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\StandardProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="开启专用网络防火墙"}
PPEnableFirewall = @{regname='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters\FirewallPolicy\PublicProfile';name='EnableFirewall';regtype="DWord";operator="eq";value=1;msg="开启公用网络防火墙"}
CheckResults=@()
}
Function F_SysRegistryPolicy {
$Registry= $SysRegistryPolicy.Clone()
foreach ( $item in $Registry.keys) {
if ( $item -eq "CheckResults" ){ continue;}
$Result = F_GetRegPropertyValue -Key $SysRegistryPolicy.$item.regname -Name $SysRegistryPolicy.$item.name -Operator $SysRegistryPolicy.$item.operator -DefaultValue $SysRegistryPolicy.$item.value -Msg $SysRegistryPolicy.$item.msg
$SysRegistryPolicy['CheckResults'] += $Result
}
return $SysRegistryPolicy['CheckResults']
}
$SysProcessServicePolicy = @{"CheckResults"=@()}
function F_SysProcessServicePolicy {
$SysAutoStart = Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
$SysAutoStart.GetValueNames() | % {
$res += "$($_)#$($SysAutoStart.GetValue($_)) "
}
$Result = @{"SysProcessServicePolicy::SysAutoStart"=$res}
$SysProcessServicePolicy['CheckResults'] += $Result
$UserAutoStart = Get-Item -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
$UserAutoStart.GetValueNames() | % {
$res += "$($_)#$($SysAutoStart.GetValue($_)) "
}
$Result = @{"SysProcessServicePolicy::UserAutoStart"=$res}
$SysProcessServicePolicy['CheckResults'] += $Result
$RDPStatus = (Get-Service -Name "TermService").Status
if ($RDPStatus -eq "Running" ) {
$Result = F_GetRegPropertyValue -Key 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server' -Name 'fDenyTSConnections' -Operator "eq" -DefaultValue 0 -Msg "是否将远程桌面服务禁用"
} else {
$Result = @{"SysProcessServicePolicy::RDPStatus"="当前系统【未启用】远程桌面服务."}
}
$SysProcessServicePolicy['CheckResults'] += $Result
$Result = F_GetRegPropertyValue -Key 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer' -Name 'Enabled' -Operator "eq" -DefaultValue 1 -Msg "是否启用NTP服务同步时钟策略"
$SysProcessServicePolicy['CheckResults'] += $Result
$RDP1 = Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\' | % {$_.GetValue("PortNumber")}
$RDP2 = Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp\' | % {$_.GetValue("PortNumber")}
if ( $RDP1 -eq $RDP2 -and $RDP2 -ne "3389") {
$Result = @{"SysProcessServicePolicy::RDPPort"="[合格项]|$RDP1|除3389以外的端口|系统基础配置核查-默认的远程桌面端口已修改-【符合】等级保护标准."}
} else {
$Result = @{"SysProcessServicePolicy::RDPPort"="[异常项]|$RDP1|除3389以外的端口|系统基础配置核查-默认的远程桌面端口未修改-【不符合】等级保护标准."}
}
$SysProcessServicePolicy['CheckResults'] += $Result
}
$Msrc_api = "https://api.msrc.microsoft.com/sug/v2.0/zh-CN/affectedProduct?%24orderBy=releaseDate+desc&%24filter=productFamilyId+in+%28%27100000010%27%29+and+severityId+in+%28%27100000000%27%2C%27100000001%27%29+and+%28releaseDate+gt+2020-01-14T00%3A00%3A00%2B08%3A00%29+and+%28releaseDate+lt+2021-05-22T23%3A59%3A59%2B08%3A00%29"
$SysWSUSList = @{}
$SysWSUSListId = @()
$AvailableWSUSList = @{}
function F_SysSecurityPolicy {
if ( $MsrcUpdate -or ! (Test-Path -Path .\WSUSList.json) ) {
$MSRC_JSON = F_UrlRequest -Msrc_api $Msrc_api
$MSRC_JSON.value | % {
$id = $_.id;
$product = $_.product;
$articleName = $_.kbArticles.articleName | Get-Unique;
$fixedBuildNumber = $_.kbArticles.fixedBuildNumber | Get-Unique;
$severity = $_.severity;
$impact = $_.impact;
$baseScore = $_.baseScore;
$cveNumber = $_.cveNumber | Get-Unique;
$releaseDate = $_.releaseDate
$SysWSUSList += @{"$($id)"=@{"product"=$product;"articleName"=$articleName;"fixedBuildNumber"=$fixedBuildNumber;"severity"=$severity;"impact"=$impact;"baseScore"=$baseScore;"cveNumber"=$cveNumber;"releaseDate"=$releaseDate}}
}
while ($MSRC_JSON.'@odata.nextLink'.length) {
$MSRC_JSON = F_UrlRequest -Msrc_api $MSRC_JSON.'@odata.nextLink'
$MSRC_JSON.value | % {
$id = $_.id;
$product = $_.product;
$articleName = $_.kbArticles.articleName | Get-Unique;
$fixedBuildNumber = $_.kbArticles.fixedBuildNumber | Get-Unique;
$severity = $_.severity;
$impact = $_.impact;
$baseScore = $_.baseScore;
$cveNumber = $_.cveNumber | Get-Unique;
$releaseDate = $_.releaseDate
$SysWSUSList += @{"$($id)"=@{"product"=$product;"articleName"=$articleName;"fixedBuildNumber"=$fixedBuildNumber;"severity"=$severity;"impact"=$impact;"baseScore"=$baseScore;"cveNumber"=$cveNumber;"releaseDate"=$releaseDate }}
}
}
Write-Host "[-] 已从 Microsoft 安全响应中心获取更新 $($MSRC_JSON.'@odata.count') 条补丁信息!" -ForegroundColor Green
Write-Host "[-] 正在将获取的更新 $($MSRC_JSON.'@odata.count') 条补丁信息写入到本地 WSUSList.json 文件之中!" -ForegroundColor Green
$SysWSUSList | ConvertTo-Json | Out-File WSUSList.json -Encoding utf8
$SysWSUSListId = $SysWSUSList.keys
$SysWSUSList.keys | ConvertTo-Json | Out-File WSUSListId.json -Encoding utf8
} else {
if (Test-Path -Path .\WSUSList.json) {
$SysWSUSList = Get-Content -Raw -Encoding UTF8 .\WSUSList.json | ConvertFrom-Json
$SysWSUSListId = Get-Content -Raw -Encoding UTF8 .\WSUSListId.json | ConvertFrom-Json
Write-Host "[-] 已从本地 WSUSList.json 文件获得 $($SysWSUSListId.count) 条补丁信息!" -ForegroundColor Green
} else {
Write-Host "[-] 本地未能找到存放补丁信息的 WSUSList.json 文件! 请采用 -Update True 标记从Microsoft 安全响应中心获取更新" -ForegroundColor Red
break
exit
}
}
$AvailableWSUSListId = @()
if ($SysInfo.ProductType -eq "Client") {
Write-Host "[-] Desktop Client" -ForegroundColor Gray
foreach ($KeyName in $SysWSUSListId) {
if(($SysWSUSList."$KeyName".product -match $SysInfo.ProductName) -and ($SysWSUSList."$KeyName".product -match $SysInfo.WindowsVersion) -and ($SysWSUSList."$KeyName".product -match ($SysInfo.CsSystemType -split " ")[0])) {
if (($SysWSUSList."$KeyName".fixedBuildNumber -match $SysInfo.OsVersion) -or ($SysWSUSList."$KeyName".fixedBuildNumber.length -eq 0 )) {
$AvailableWSUSList."$KeyName" = $SysWSUSList."$KeyName"
$AvailableWSUSListId += "$KeyName"
}
}
}
} else {
Write-Host "[-] Windows Server" -ForegroundColor Gray
foreach ($KeyName in $SysWSUSListId) {
if(($SysWSUSList."$KeyName".product -match $SysInfo.ProductName) -and ($SysWSUSList."$KeyName".product -match $SysInfo.ProductName)) {
$AvailableWSUSList."$KeyName" = $SysWSUSList."$KeyName"
$AvailableWSUSListId += "$KeyName"
}
}
}
Write-Host $SysInfo.ProductName $SysInfo.WindowsVersion ($SysInfo.CsSystemType -split " ")[0] $SysInfo.OsVersion
Write-Host "[-] 已从梳理出适用于当前 $($SysInfo.ProductType) 系统版本的 $($AvailableWSUSList.count) 条补丁信息!`n" -ForegroundColor Green
$InstallWSUSList = @{}
$msg = @()
foreach ($id in $AvailableWSUSListId) {
if( $SysInfo.'Hotfix(s)' -match $AvailableWSUSList."$id".articleName ) {
$InstallWSUSList."$id" = $SysWSUSList."$id"
$msg += "[+]" + $SysWSUSList."$id".product + $SysWSUSList."$id".fixedBuildNumber + " " + $SysWSUSList."$id".articleName + "(" + $SysWSUSList."$id".cveNumber + ")" + $SysWSUSList."$id".severity + $SysWSUSList."$id".baseScore + "`n"
}
}
Write-Host "[-] $($SysInfo.'Hotfix(s)') ,共 $($AvailableWSUSList.count) 条漏洞补丁信息!`n$($msg)" -ForegroundColor Green
$NotInstallWSUSList = @{}
$msg = @()
foreach ($id in $AvailableWSUSListId) {
if(-not($InstallWSUSList."$id")) {
$NotInstallWSUSList."$id" = $SysWSUSList."$id"
$msg += "[+]" + $SysWSUSList."$id".product + $SysWSUSList."$id".fixedBuildNumber + " " + $SysWSUSList."$id".articleName + "(" + $SysWSUSList."$id".cveNumber + ")" + $SysWSUSList."$id".severity + $SysWSUSList."$id".baseScore + "`n"
}
}
Write-Host "[-] 未安装 $($NotInstallWSUSList.count) 条漏洞补丁信息,共 $($AvailableWSUSList.count) 条漏洞补丁信息!`n$($msg)" -ForegroundColor red
}
$OtherCheck = @{}
function F_OtherCheckPolicy {
$Product = Get-WmiObject -Class Win32_Product | Select-Object -Property Name,Version,IdentifyingNumber | Sort-Object Name | Out-String
$OtherCheck += @{"Product"="$($Product)"}
$Recent = (Get-ChildItem ~\AppData\Roaming\Microsoft\Windows\Recent).Name
$OtherCheck += @{"Recent"="$($Recent)"}
return $OtherCheck
}
function Main() {
$ScanStartTime = Get-date -Format 'yyyy-M-d H:m:s'
F_Logging -Level Info -Msg "#################################################################################"
F_Logging -Level Info -Msg "- @Desc: Windows Server 安全配置策略基线检测脚本 [将会在Github上持续更新-star]"
F_Logging -Level Info -Msg "- @Author: WeiyiGeek"
F_Logging -Level Info -Msg "- @Blog: https://www.weiyigeek.top"
F_Logging -Level Info -Msg "- @Github: https://github.com/WeiyiGeek/SecOpsDev/tree/master/OS-操作系统/Windows"
F_Logging -Level Info -Msg "#################################################################################`n"
F_Logging -Level Info -Msg "[*] Windows Server 安全配置策略基线检测脚本已启动."
F_Logging -Level Info -Msg "[*] 脚本执行: $($Executor), 是否在线拉取微软安全中心的服务器安全补丁列表信息: $($MsrcUpdate)`n"
F_Logging -Level Info -Msg "[-] 正在检测当前运行的PowerShell终端是否管理员权限...`n"
$flag = F_IsCurrentUserAdmin
if (!($flag)) {
F_Logging -Level Error -Msg "[*] 脚本执行发生错误,请使用管理员权限运行该脚本..例如: Start-Process powershell -Verb runAs...."
F_Logging -Level Warning -Msg "[*] 正在退出执行该脚本......"
return
}
F_Logging -Level Info -Msg "[*] PowerShell 管理员权限检查通过...`n"
F_Logging -Level Info -Msg "[-] 正在导出当前系统策略配置文件 config.cfg......`n"
secedit /export /cfg config.cfg /quiet
start-sleep 3
if ( -not(Test-Path -Path config.cfg)) {
F_Logging -Level Error -Msg "[*] 当前系统策略配置文件 config.cfg 不存在,请检查......`n"
F_Logging -Level Warning -Msg "[*] 正在退出执行该脚本......"
return
} else {
Copy-Item -Path config.cfg -Destination config.cfg.bak -Force
}
$Config = Get-Content -path config.cfg
F_Logging -Level Info -Msg "[-] 当前系统信息一览"
$SysInfo = F_SysInfo
$SysInfo
F_Logging -Level Info -Msg "[-] 当前系统网络信息一览"
$SysNetAdapter = F_SysNetAdapter
$SysNetAdapter
F_Logging -Level Info -Msg "[-] 当前系统磁盘信息一览"
$SysDisk = F_SysDisk
$SysDisk
F_Logging -Level Info -Msg "[-] 当前系统账户信息一览"
$SysAccount = F_SysAccount
$SysAccount
F_Logging -Level Info -Msg "[-] 当前系统安全策略信息一览"
$SysAccountPolicy.CheckResults = F_SysAccountPolicy
$SysEventAuditPolicy.CheckResults = F_SysEventAuditPolicy
$SysUserPrivilegePolicy.CheckResults = F_SysUserPrivilegePolicy
$SysSecurityOptionPolicy.CheckResults = F_SysSecurityOptionPolicy
$SysRegistryPolicy.CheckResults = F_SysRegistryPolicy
$SysProcessServicePolicy.CheckResults = F_SysProcessServicePolicy
F_Logging -Level Info -Msg "[-] 当前系统杂类信息一览"
$OtherCheck = F_OtherCheckPolicy
$OtherCheck.Values
F_Logging -Level Info -Msg "[-] 当前系统安全补丁情况信息一览"
F_SysSecurityPolicy
$ScanEndTime = Get-date -Format 'yyyy-M-d H:m:s'
F_Logging -Level Info -Msg "- Windows Server 安全配置策略基线检测脚本已执行完毕......`n开始时间:${ScanStartTime}`n完成时间: ${ScanEndTime}"
}
Main
Windows Server 安全配置策略基线加固脚本
Link: https://github.com/WeiyiGeek/SecOpsDev/blob/master/OS-%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/WindowsSecurityReinforce.ps1
至此,Windows 安全基线配置核查和安全加固脚本分享完毕。
文章来源:
原创首发平台地址: https://www.anquanke.com/post/id/259603
博客地址: Linux与Windows服务器操作系统安全防御实践指南 ( https://blog.weiyigeek.top/2020/10-13-585.html )
文章书写不易,如果您觉得这篇文章还不错的,请给这篇专栏 【点个赞、投个币、收个藏、关个注,转个发】(人间五大情),这将对我的肯定,谢谢!。
本文章来源 我的Blog站点 或 WeiyiGeek 公众账号 以及 我的BiliBili专栏 (技术交流、友链交换请邮我哟
),谢谢支持!(๑′ᴗ‵๑) ❤
欢迎各位志同道合的朋友一起学习交流,如文章有误请留下您宝贵的知识建议,通过邮箱【master#weiyigeek.top】联系我哟!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)