PowerShell 技能连载 - Windows 安全基线审计

适用于 Windows Server 2016+ 及 PowerShell 5.1+

很多安全事件的根源并不是零日漏洞,而是基础配置疏忽——弱密码策略、高危端口暴露、补丁长期未更新。定期执行安全基线检查是运维最基本也是最有效的防线。本文用 PowerShell 编写一套轻量审计脚本,覆盖密码策略、防火墙、RDP、补丁和服务五大维度,最终汇总为一份 HTML 审计报告。

账户与密码策略

密码策略是安全基线的第一道门。如果系统允许空密码或密码永不过期,攻击者可以轻松暴力破解。同时管理员组成员过多、Guest 账户处于启用状态,也会显著增加横向移动的风险。下面这段代码通过 net accounts 获取当前密码策略,并检查本地管理员组和 Guest 账户的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function Get-SecurityBaselineAccount {
$result = @()
$pwdPolicy = net accounts | Out-String

# 密码最短期限:防止用户改完密码后立刻改回旧密码
$result += [PSCustomObject]@{
Category = "密码策略"; Check = "密码最短期限"
Value = if ($pwdPolicy -match '密码最短期限:\s*(\d+)') { $Matches[1] + " 天" } else { "未知" }
Expected = "≥ 1 天"
}
# 密码最长期限:长期不换密码会增加凭据泄露的风险
$result += [PSCustomObject]@{
Category = "密码策略"; Check = "密码最长期限"
Value = if ($pwdPolicy -match '密码最长期限:\s*(\d+)') { $Matches[1] + " 天" } else { "未知" }
Expected = "≤ 90 天"
}
# 最小密码长度:14 位以下容易被暴力破解
$result += [PSCustomObject]@{
Category = "密码策略"; Check = "最小密码长度"
Value = if ($pwdPolicy -match '最小密码长度:\s*(\d+)') { $Matches[1] + " 字符" } else { "未知" }
Expected = "≥ 14 字符"
}
# 管理员组成员应尽量精简,避免权限滥用
$adminMembers = Get-LocalGroupMember -SID "S-1-5-32-544" -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "账户安全"; Check = "本地管理员组成员数"
Value = "$($adminMembers.Count) 个"; Expected = "尽量精简"
}
# Guest 账户启用后任何人可匿名访问系统资源
$guest = Get-LocalUser -Name "Guest" -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "账户安全"; Check = "Guest 账户状态"
Value = if ($guest.Enabled) { "已启用 (风险)" } else { "已禁用" }; Expected = "已禁用"
}
return $result
}

执行后输出类似如下结果,可以看到最小密码长度仅为 7 字符,不满足基线要求,需要重点关注:

1
2
3
4
5
6
7
Category  Check              Value        Expected
-------- ----- ----- --------
密码策略 密码最短期限 1 天 ≥ 1 天
密码策略 密码最长期限 42 天 ≤ 90 天
密码策略 最小密码长度 7 字符 ≥ 14 字符
账户安全 本地管理员组成员数 3 个 尽量精简
账户安全 Guest 账户状态 已禁用 已禁用

防火墙与高危端口检测

防火墙是系统级的网络屏障,任何一个配置文件被关闭都会让对应网络场景下的所有端口暴露。FTP(21)、Telnet(23)、SMB(445)、RDP(3389)、VNC(5800/5900)等高危端口如果监听在 0.0.0.0 上,攻击面会大幅增加。下面这段代码检查三个防火墙配置文件的启用状态,并扫描当前对外开放的高危端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Get-SecurityBaselineNetwork {
$result = @()

# 逐个检查域、专用、公用三个防火墙配置文件
foreach ($profile in @("Domain", "Private", "Public")) {
$fw = Get-NetFirewallProfile -Name $profile -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "防火墙"; Check = "$profile 配置文件"
Value = if ($fw.Enabled) { "已启用" } else { "已禁用 (风险)" }
Expected = "已启用"
}
}
# 扫描监听在所有网卡上的高危端口
$listeningPorts = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue |
Where-Object { $_.LocalAddress -eq "0.0.0.0" -or $_.LocalAddress -eq "::" } |
Select-Object LocalPort, OwningProcess -Unique

$highRiskPorts = @(21, 23, 445, 3389, 5800, 5900)
$riskyPorts = $listeningPorts | Where-Object { $_.LocalPort -in $highRiskPorts }

$result += [PSCustomObject]@{
Category = "网络"; Check = "高危端口开放"
Value = if ($riskyPorts) {
"发现 $($riskyPorts.Count) 个: $($riskyPorts.LocalPort -join ', ')"
} else { "无" }
Expected = "无"
}
return $result
}

下面的执行结果显示 Public 配置文件的防火墙已关闭,同时 445(SMB)和 3389(RDP)对外开放,存在较高的被利用风险:

1
2
3
4
5
6
Category  Check           Value                 Expected
-------- ----- ----- --------
防火墙 Domain 配置文件 已启用 已启用
防火墙 Private 配置文件 已启用 已启用
防火墙 Public 配置文件 已禁用 (风险) 已启用
网络 高危端口开放 发现 2 个: 445, 3389 无

RDP 安全配置

RDP 是远程管理 Windows 服务器的常用方式,但如果不加限制就会成为暴力破解的入口。需要关注两个关键点:RDP 是否开启,以及是否启用了网络级别身份验证(NLA)。NLA 在建立连接之前就要求身份验证,能有效防御未认证的拒绝服务攻击和凭据窃取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Get-SecurityBaselineRDP {
$result = @()

# 通过注册表检查 RDP 是否启用(0 = 启用,1 = 禁用)
$rdp = Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" `
-Name "fDenyTSConnections" -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "RDP 安全"; Check = "RDP 状态"
Value = if ($rdp.fDenyTSConnections -eq 0) { "已启用" } else { "已禁用" }
Expected = "按需启用"
}

# NLA 未启用时连接建立前不做身份验证,存在安全风险
$nla = Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
-Name "UserAuthentication" -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "RDP 安全"; Check = "NLA(网络级别身份验证)"
Value = if ($nla.UserAuthentication -eq 1) { "已启用" } else { "未启用 (风险)" }
Expected = "已启用"
}
return $result
}

执行结果示例中 RDP 已启用且 NLA 也已启用,处于合规状态。如果 NLA 未启用,攻击者可在身份验证之前消耗服务器资源,建议立刻启用:

1
2
3
4
Category  Check                    Value    Expected
-------- ----- ----- --------
RDP 安全 RDP 状态 已启用 按需启用
RDP 安全 NLA(网络级别身份验证) 已启用 已启用

补丁状态检查

未及时安装补丁是导致系统被入侵的常见原因。这段代码检查最近一次补丁安装的日期、Windows Update 服务状态,以及当前有多少重要更新待安装。补丁超过 30 天未更新或存在待安装的重要更新,都说明更新策略可能存在问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Get-SecurityBaselineUpdates {
$result = @()
# 获取最近安装的补丁,按时间降序排列
$recentUpdates = Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5
$latestUpdate = $recentUpdates | Select-Object -First 1
$result += [PSCustomObject]@{
Category = "系统更新"; Check = "最新补丁日期"
Value = if ($latestUpdate.InstalledOn) {
$latestUpdate.InstalledOn.ToString("yyyy-MM-dd")
} else { "未知" }
Expected = "30 天内"
}
# 检查 Windows Update 服务是否正常运行
$wuService = Get-Service -Name wuauserv -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "系统更新"; Check = "Windows Update 服务"
Value = "$($wuService.Status)"; Expected = "Running"
}
# 通过 COM 对象查询待安装的重要更新
$updateSession = New-Object -ComObject Microsoft.Update.Session
$searchResult = $updateSession.CreateUpdateSearcher().Search(
"IsInstalled=0 and Type='Software' and AutoSelectOnWebSites=1"
)
$result += [PSCustomObject]@{
Category = "系统更新"; Check = "待安装重要更新"
Value = "$($searchResult.Updates.Count) 个"; Expected = "0 个"
}
return $result
}

以下执行结果显示还有 3 个重要更新待安装,建议尽快安排补丁窗口完成更新:

1
2
3
4
5
Category  Check               Value        Expected
-------- ----- ----- --------
系统更新 最新补丁日期 2025-03-10 30 天内
系统更新 Windows Update 服务 Running Running
系统更新 待安装重要更新 30

危险服务检查

某些服务在大多数生产环境中并不需要,反而会增大攻击面。Telnet 明文传输凭据,远程注册表允许远程修改注册表,SSDP 和 UPnP 可能被用于网络发现和反射攻击。下面逐一检查这些服务的运行状态,并统计系统级自启动项数量——自启动项过多可能意味着恶意软件的持久化驻留。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function Get-SecurityBaselineServices {
$result = @()
# 常见高危服务列表:名称 => 服务标识
$dangerousServices = @{
"Telnet" = "tlntsvr"
"远程注册表" = "RemoteRegistry"
"SSDP 发现" = "ssdpsrv"
"UPnP 设备主机" = "upnphost"
}
foreach ($svc in $dangerousServices.GetEnumerator()) {
$service = Get-Service -Name $svc.Value -ErrorAction SilentlyContinue
$result += [PSCustomObject]@{
Category = "服务检查"; Check = "$($svc.Key) ($($svc.Value))"
Value = if ($service) {
"$($service.Status), 启动类型: $($service.StartType)"
} else { "未安装" }
Expected = "未安装或已禁用"
}
}
# 系统级自启动项过多可能意味着恶意软件持久化
$startupItems = Get-CimInstance -ClassName Win32_StartupCommand |
Where-Object { $_.Location -eq "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" }
$result += [PSCustomObject]@{
Category = "启动项"; Check = "系统级自启动项"
Value = "$($startupItems.Count) 个"; Expected = "审查后保留必要项"
}
return $result
}

执行结果显示远程注册表服务处于自动启动且正在运行,在生产环境中建议禁用:

1
2
3
4
5
6
7
Category  Check                         Value                         Expected
-------- ----- ----- --------
服务检查 Telnet (tlntsvr) 未安装 未安装或已禁用
服务检查 远程注册表 (RemoteRegistry) Running, 启动类型: Automatic 未安装或已禁用
服务检查 SSDP 发现 (ssdpsrv) Stopped, 启动类型: Manual 未安装或已禁用
服务检查 UPnP 设备主机 (upnphost) Stopped, 启动类型: Manual 未安装或已禁用
启动项 系统级自启动项 4 个 审查后保留必要项

生成 HTML 审计报告

将前面所有检查函数汇总为一份带风险标记的 HTML 报告。不合规的行以红色背景高亮显示,便于快速定位问题。报告顶部汇总检查总数和风险项数量,帮助管理层一眼掌握整体安全态势。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function New-SecurityBaselineReport {
param(
[string]$OutputPath = ".\SecurityBaseline_$(Get-Date -Format 'yyyyMMdd').html"
)

# 依次调用各维度的检查函数,汇总所有结果
$allChecks = @(Get-SecurityBaselineAccount) + @(Get-SecurityBaselineNetwork) +
@(Get-SecurityBaselineRDP) +
@(Get-SecurityBaselineUpdates) + @(Get-SecurityBaselineServices)

$totalChecks = $allChecks.Count
$riskItems = ($allChecks | Where-Object {
$_.Value -match "风险|FAIL|未启用"
}).Count

$html = @"
<!DOCTYPE html><html><head><title>安全基线审计报告</title>
<style>
body{font-family:Microsoft YaHei;margin:20px}
table{border-collapse:collapse;width:100%}
th,td{border:1px solid #ddd;padding:8px;text-align:left}
th{background-color:#4CAF50;color:white}
.risk{background-color:#ffcccc}
</style></head><body>
<h1>安全基线审计报告 - $(Get-Date -Format 'yyyy-MM-dd')</h1>
<p>检查项: $totalChecks | 风险项: <span style="color:red">$riskItems</span></p>
<table><tr><th>类别</th><th>检查项</th><th>当前值</th><th>期望值</th></tr>
"@
foreach ($item in $allChecks) {
$class = if ($item.Value -match "风险|FAIL|未启用") {
' class="risk"'
} else { "" }
$html += "<tr$class><td>$($item.Category)</td><td>$($item.Check)</td>" +
"<td>$($item.Value)</td><td>$($item.Expected)</td></tr>"
}
$html += "</table></body></html>"
$html | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "报告已生成: $OutputPath"
}

执行后在当前目录生成 HTML 文件,浏览器打开即可看到完整的审计表格。不合规的行以红色背景标出:

1
报告已生成: .\SecurityBaseline_20250331.html
1
2
3
4
5
6
7
8
检查项: 19 | 风险项: 4

| 类别 | 检查项 | 当前值 | 期望值 |
|----------|-----------------------------|-------------------------------|-----------------|
| 密码策略 | 最小密码长度 | 7 字符 | ≥ 14 字符 |
| 防火墙 | Public 配置文件 | 已禁用 (风险) | 已启用 |
| 网络 | 高危端口开放 | 发现 2 个: 445, 3389 ||
| 服务检查 | 远程注册表 (RemoteRegistry) | Running, 启动类型: Automatic | 未安装或已禁用 |

建议在运维流程中定期执行 New-SecurityBaselineReport,并将历次报告归档对比,跟踪风险项的变化趋势。安全基线不是一次性的工作,而是持续改进的过程。

PowerShell REST API高级集成技术

OAuth2认证流程

1
2
3
4
5
6
7
8
9
10
11
12
13
$tokenParams = @{
Uri = 'https://login.microsoftonline.com/tenant/oauth2/v2.0/token'
Method = 'POST'
Body = @{
client_id = $clientId
scope = 'https://graph.microsoft.com/.default'
client_secret = $secret
grant_type = 'client_credentials'
}
}

$token = Invoke-RestMethod @tokenParams
$headers = @{Authorization = "Bearer $($token.access_token)"}

分页数据获取

1
2
3
4
5
6
$result = while ($true) {
$response = Invoke-RestMethod -Uri $url -Headers $headers
$response.value
if (-not $response.'@odata.nextLink') { break }
$url = $response.'@odata.nextLink'
}

错误重试机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Invoke-RetryRequest {
param(
[scriptblock]$Action,
[int]$MaxRetries = 3
)

$attempt = 0
do {
try {
return & $Action
}
catch {
$attempt++
if ($attempt -ge $MaxRetries) { throw }
Start-Sleep -Seconds (2 * $attempt)
}
} while ($true)
}

最佳实践

  1. 令牌缓存与自动刷新
  2. 请求速率限制处理
  3. 异步批量数据处理
  4. 响应数据验证机制

安全规范

  • 敏感信息加密存储
  • 使用HTTPS严格模式
  • 限制API权限范围
  • 定期轮换访问凭证

PowerShell 技能连载 - 供应链安全漏洞扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function Invoke-SupplyChainScan {
param(
[Parameter(Mandatory=$true)]
[string]$ImageName,
[string]$OutputFormat = 'table',
[string]$SeverityLevel = 'HIGH,CRITICAL'
)

# 安装Trivy漏洞扫描器
if (-not (Get-Command trivy -ErrorAction SilentlyContinue)) {
winget install aquasecurity.trivy
}

try {
# 执行容器镜像扫描
$result = trivy image --format $OutputFormat --severity $SeverityLevel $ImageName

# 生成HTML报告
$htmlReport = "$env:TEMP\scan_report_$(Get-Date -Format yyyyMMddHHmmss).html"
trivy image --format template --template "@contrib/html.tpl" -o $htmlReport $ImageName

[PSCustomObject]@{
ScanTarget = $ImageName
VulnerabilitiesFound = $result.Count
CriticalCount = ($result | Where-Object { $_ -match 'CRITICAL' }).Count
HighCount = ($result | Where-Object { $_ -match 'HIGH' }).Count
HTMLReportPath = $htmlReport
}
}
catch {
Write-Error "漏洞扫描失败:$_"
}
}

核心功能:

  1. 集成Trivy进行容器镜像漏洞扫描
  2. 支持多种输出格式(table/json/html)
  3. 自动生成带严重等级分类的报告
  4. 包含依赖组件版本检查

应用场景:

  • CI/CD流水线安全门禁
  • 第三方组件入仓检查
  • 生产环境镜像定期审计

PowerShell 技能连载 - 零信任架构下的设备健康检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function Invoke-DeviceHealthCheck {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$DeviceName
)

$healthReport = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
Device = $DeviceName
TPMEnabled = $false
SecureBoot = $false
AntivirusStatus = 'Unknown'
ComplianceScore = 0
}

try {
# 检查TPM状态
$tpm = Get-Tpm -ErrorAction Stop
$healthReport.TPMEnabled = $tpm.TpmPresent

# 验证安全启动状态
$healthReport.SecureBoot = Confirm-SecureBootUEFI

# 获取反病毒状态
$avStatus = Get-MpComputerStatus
$healthReport.AntivirusStatus = $avStatus.AMServiceEnabled ? 'Active' : 'Inactive'

# 计算合规分数
$compliance = 0
if($healthReport.TPMEnabled) { $compliance += 30 }
if($healthReport.SecureBoot) { $compliance += 30 }
if($healthReport.AntivirusStatus -eq 'Active') { $compliance += 40 }
$healthReport.ComplianceScore = $compliance
}
catch {
Write-Warning "设备健康检查失败: $_"
}

$healthReport | Export-Clixml -Path "$env:TEMP/DeviceHealth_$DeviceName.xml"
return $healthReport
}

核心功能

  1. TPM芯片状态验证
  2. 安全启动模式检测
  3. 反病毒服务状态监控
  4. 自动化合规评分

应用场景

  • 零信任架构准入控制
  • 远程办公设备安全审计
  • 合规性基线验证
  • 安全事件响应前置检查

PowerShell 技能连载 - 基于Azure Functions的无服务器安全检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function Invoke-SecurityScan {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$ResourceGroup,

[ValidateSet('Critical','High','Medium')]
[string]$SeverityLevel = 'High'
)

$securityReport = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
ScannedResources = @()
SecurityFindings = @()
}

# 获取Azure安全中心警报
$alerts = Get-AzSecurityAlert -ResourceGroupName $ResourceGroup |
Where-Object { $_.Severity -eq $SeverityLevel }

# 自动化响应流程
$alerts | ForEach-Object {
$securityReport.ScannedResources += [PSCustomObject]@{
ResourceID = $_.ResourceId
AlertType = $_.AlertType
CompromiseEntity = $_.CompromisedEntity
}

# 触发自动化修复动作
if($_.AlertType -eq 'UnusualResourceDeployment') {
Start-AzResourceDelete -ResourceId $_.ResourceId -Force
$securityReport.SecurityFindings += [PSCustomObject]@{
Action = 'DeletedSuspiciousResource'
ResourceID = $_.ResourceId
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
}
}
}

# 生成安全态势报告
$securityReport | ConvertTo-Json -Depth 3 |
Out-File -FilePath "$env:TEMP/AzureSecReport_$(Get-Date -Format yyyyMMdd).json"
return $securityReport
}

核心功能

  1. 实时获取Azure安全中心高等级警报
  2. 异常资源部署自动隔离机制
  3. JSON格式安全态势报告生成
  4. 多严重级别安全事件过滤

典型应用场景

  • 云环境异常操作实时响应
  • 自动化安全基线维护
  • 多云订阅安全状态聚合
  • 合规审计日志自动生成

PowerShell 技能连载 - 供应链安全漏洞扫描工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function Invoke-SupplyChainScan {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$ScanPath,

[ValidateSet('Critical','High','Medium','Low')]
[string]$SeverityLevel = 'Critical'
)

$report = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
ScannedComponents = @()
SecurityFindings = @()
}

# 组件哈希校验
Get-ChildItem $ScanPath -Recurse -Include *.dll,*.exe,*.psm1 | ForEach-Object {
$fileHash = (Get-FileHash $_.FullName -Algorithm SHA256).Hash
$signature = Get-AuthenticodeSignature $_.FullName

$component = [PSCustomObject]@{
FileName = $_.Name
FilePath = $_.FullName
SHA256 = $fileHash
IsSigned = $signature.Status -eq 'Valid'
Publisher = $signature.SignerCertificate.Subject
}
$report.ScannedComponents += $component

if (-not $component.IsSigned) {
$report.SecurityFindings += [PSCustomObject]@{
Severity = 'High'
Description = "未签名的组件: $($_.Name)"
Recommendation = "要求供应商提供数字签名版本或验证组件来源"
}
}
}

# 依赖包漏洞扫描
$nugetPackages = Get-ChildItem $ScanPath -Recurse -Include packages.config
$nugetPackages | ForEach-Object {
[xml]$config = Get-Content $_.FullName
$config.packages.package | ForEach-Object {
$cveData = Invoke-RestMethod "https://api.cvecheck.org/v1/search?id=$($_.id)"
if ($cveData.vulnerabilities | Where-Object { $_.severity -ge $SeverityLevel }) {
$report.SecurityFindings += [PSCustomObject]@{
Severity = $SeverityLevel
Description = "存在漏洞的依赖包: $($_.id) v$($_.version)"
Recommendation = "升级到最新安全版本 $($cveData.latestVersion)"
}
}
}
}

$report | Export-Csv -Path "$ScanPath\SupplyChainReport_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
return $report
}

核心功能

  1. 软件组件供应链安全扫描
  2. 依赖包漏洞自动化检测
  3. 数字签名验证机制
  4. CVE漏洞数据库集成

典型应用场景

  • 开发环境第三方组件安全检查
  • 软件构建流水线安全审计
  • 供应商交付物合规验证
  • 企业软件资产安全基线报告生成

PowerShell 技能连载 - 零信任架构下的设备健康检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function Invoke-DeviceHealthCheck {
param(
[string[]]$ComputerNames = $env:COMPUTERNAME
)

$securityBaseline = @{
SecureBootEnabled = $true
TPMPresent = $true
BitLockerStatus = 'FullyEncrypted'
AntivirusStatus = 'Enabled'
FirewallProfile = 'Domain'
}

$results = @()

foreach ($computer in $ComputerNames) {
try {
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer
$tpm = Get-CimInstance -ClassName Win32_Tpm -ComputerName $computer -ErrorAction Stop
$bitlocker = Get-BitLockerVolume -MountPoint $osInfo.SystemDrive -ErrorAction Stop

$healthStatus = [PSCustomObject]@{
ComputerName = $computer
LastBootTime = $osInfo.LastBootUpTime
SecureBoot = [bool](Confirm-SecureBootUEFI)
TPMVersion = $tpm.SpecVersion
BitLockerProtection = $bitlocker.ProtectionStatus
DefenderStatus = (Get-MpComputerStatus).AntivirusEnabled
FirewallStatus = (Get-NetFirewallProfile -Name Domain).Enabled
ComplianceScore = 0
}

# 计算合规分数
$healthStatus.ComplianceScore = [math]::Round((
($healthStatus.SecureBoot -eq $securityBaseline.SecureBootEnabled) +
($healthStatus.TPMVersion -match '2.0') +
($healthStatus.BitLockerProtection -eq 'On') +
($healthStatus.DefenderStatus -eq $true) +
($healthStatus.FirewallStatus -eq $true)
) / 5 * 100, 2)

$results += $healthStatus
}
catch {
Write-Warning "$computer 健康检查失败: $_"
}
}

$results | Format-Table -AutoSize
}

核心功能:

  1. 自动化验证设备安全基线配置
  2. 检测TPM 2.0和SecureBoot状态
  3. 评估BitLocker加密状态
  4. 生成设备合规性评分

应用场景:

  • 零信任网络接入前检查
  • 远程办公设备安全审计
  • 合规性自动化报告生成

PowerShell JEA安全架构解析

JEA端点配置

1
2
3
4
5
6
7
8
# 创建会话配置文件
$sessionParams = @{
Path = '.JEAConfig.pssc'
SessionType = 'RestrictedRemoteServer'
RunAsVirtualAccount = $true
RoleDefinitions = @{ 'CONTOSO\SQLUsers' = @{ RoleCapabilities = 'SqlReadOnly' } }
}
New-PSSessionConfigurationFile @sessionParams

角色能力定义

1
2
3
4
5
6
7
8
9
# 创建角色能力文件
$roleCapability = @{
Path = 'Roles\SqlReadOnly.psrc'
VisibleCmdlets = 'Get-Sql*'
VisibleFunctions = 'ConvertTo-Query'
VisibleProviders = 'FileSystem'
ScriptsToProcess = 'Initialize-SqlEnv.ps1'
}
New-PSRoleCapabilityFile @roleCapability

会话沙箱验证

1
2
3
4
5
6
# 连接JEA端点并验证权限
$session = New-PSSession -ConfigurationName JEAConfig
Invoke-Command -Session $session {
Get-Command -Name * # 仅显示白名单命令
Get-ChildItem C:\ # 触发权限拒绝
}

典型应用场景

  1. 数据库只读访问控制
  2. 第三方供应商操作审计
  3. 生产环境故障诊断隔离
  4. 跨域资源受限访问

安全加固要点

  • 虚拟账户生命周期控制
  • 转录日志完整性校验
  • 模块白名单签名验证
  • 会话超时熔断机制

PowerShell 技能连载 - 基于ATT&CK框架的进程行为分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function Invoke-ProcessBehaviorAnalysis {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
[string]$ComputerName = $env:COMPUTERNAME
)

$techniques = Invoke-RestMethod -Uri 'https://attack.mitre.org/api/techniques/'
$processes = Get-CimInstance -ClassName Win32_Process -ComputerName $ComputerName

$report = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
SuspiciousProcesses = @()
MITRETechniques = @()
}

$processes | ForEach-Object {
$behaviorScore = 0
$matchedTechs = @()

# 检测隐藏进程
if ($_.ParentProcessId -ne 1 -and -not (Get-Process -Id $_.ParentProcessId -ErrorAction SilentlyContinue)) {
$behaviorScore += 20
$matchedTechs += 'T1055' # Process Injection
}

# 检测异常内存操作
if ($_.WorkingSetSize -gt 1GB) {
$behaviorScore += 15
$matchedTechs += 'T1056' # Memory Allocation
}

if ($behaviorScore -gt 25) {
$report.SuspiciousProcesses += [PSCustomObject]@{
ProcessName = $_.Name
ProcessId = $_.ProcessId
Score = $behaviorScore
CommandLine = $_.CommandLine
}
$report.MITRETechniques += $matchedTechs | Select-Object @{n='TechniqueID';e={$_}}, @{n='Description';e={$techniques.techniques.Where{$_.id -eq $_}.name}}
}
}

$report | ConvertTo-Json -Depth 3 | Out-File "$env:TEMP/ProcessAnalysis_$(Get-Date -Format yyyyMMdd).json"
return $report
}

核心功能

  1. ATT&CK技术特征匹配
  2. 进程行为异常评分
  3. 自动化威胁检测
  4. JSON报告生成

典型应用场景

  • 企业终端安全监控
  • 红队攻击痕迹分析
  • 蓝队防御策略验证
  • 安全事件快速响应

PowerShell 技能连载 - 无服务器环境下的零信任检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function Invoke-ServerlessHealthCheck {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$ResourceGroup
)

# 获取函数应用运行环境信息
$context = Get-AzContext
$functions = Get-AzFunctionApp -ResourceGroupName $ResourceGroup

$report = [PSCustomObject]@{
Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
FunctionApps = @()
SecurityFindings = @()
}

# 检查TLS版本配置
$functions | ForEach-Object {
$config = Get-AzFunctionAppSetting -Name $_.Name -ResourceGroupName $ResourceGroup

$appReport = [PSCustomObject]@{
AppName = $_.Name
RuntimeVersion = $_.Config.NetFrameworkVersion
HTTPSOnly = $_.Config.HttpsOnly
MinTLSVersion = $config['minTlsVersion']
}
$report.FunctionApps += $appReport

if ($appReport.MinTLSVersion -lt '1.2') {
$report.SecurityFindings += [PSCustomObject]@{
Severity = 'High'
Description = "函数应用 $($_.Name) 使用不安全的TLS版本: $($appReport.MinTLSVersion)"
Recommendation = '在应用设置中将minTlsVersion更新为1.2'
}
}
}

# 生成安全报告
$report | Export-Clixml -Path "$env:TEMP/ServerlessSecurityReport_$(Get-Date -Format yyyyMMdd).xml"
return $report
}

核心功能

  1. Azure Functions运行环境自动检测
  2. TLS安全配置合规检查
  3. 零信任架构下的安全基线验证
  4. 自动化XML报告生成

典型应用场景

  • 无服务器架构安全审计
  • 云环境合规自动化核查
  • 持续安全监控(CSM)实现
  • DevOps流水线安全卡点集成
PowerShell 技术 QQ 群