Como usar o PowerShell para auditar configurações de segurança
1. Introdução à auditoria de segurança com PowerShell
A auditoria de configurações de segurança é o processo sistemático de verificar se os sistemas estão configurados de acordo com políticas e padrões estabelecidos. Automatizar esse processo com PowerShell oferece vantagens significativas sobre ferramentas gráficas: repetibilidade, escalabilidade, capacidade de gerar relatórios padronizados e integração com pipelines de DevOps.
O PowerShell permite auditar centenas de máquinas em minutos, comparar configurações atuais com baselines de segurança (como CIS Benchmarks ou STIGs) e gerar relatórios detalhados sem intervenção manual.
Pré-requisitos:
- Execute o PowerShell como Administrador
- Habilite a execução de scripts: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
- Verifique se os módulos necessários estão disponíveis: Get-Module -ListAvailable
2. Coletando informações de políticas de segurança locais
O comando secedit e o módulo SecurityPolicy permitem exportar e analisar políticas de segurança locais.
Exportando a política de segurança atual:
secedit /export /cfg C:\Temp\secpol.inf
Get-Content C:\Temp\secpol.inf | Select-String "PasswordComplexity|MinimumPasswordLength|LockoutBadCount"
Analisando políticas de senha com PowerShell puro:
$policy = Get-CimInstance -ClassName Win32_AccountPolicy -Namespace root\rsop\computer
$policy | Select-Object Name, Value | Format-Table -AutoSize
Comparação com baseline de segurança:
$baseline = @{
"PasswordComplexity" = 1
"MinimumPasswordLength" = 14
"LockoutThreshold" = 5
}
$current = Get-CimInstance -ClassName Win32_AccountPolicy -Namespace root\rsop\computer
foreach ($item in $current) {
if ($baseline.ContainsKey($item.Name)) {
if ($item.Value -ne $baseline[$item.Name]) {
Write-Warning "Configuração fora do baseline: $($item.Name) = $($item.Value) (esperado: $($baseline[$item.Name]))"
}
}
}
3. Verificando permissões de arquivos e pastas críticas
O Get-Acl é a ferramenta principal para auditar permissões NTFS.
Auditando diretórios críticos:
$criticalPaths = @(
"C:\Windows\System32",
"C:\Windows\System32\config",
"C:\Program Files",
"C:\Program Files (x86)"
)
foreach ($path in $criticalPaths) {
$acl = Get-Acl -Path $path
Write-Host "=== $path ===" -ForegroundColor Cyan
$acl.Access | Where-Object { $_.FileSystemRights -match "FullControl|Modify" } |
Select-Object IdentityReference, FileSystemRights | Format-Table -AutoSize
}
Identificando proprietários inesperados:
Get-ChildItem C:\Windows\System32 -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.PSIsContainer -eq $false } |
ForEach-Object {
$owner = (Get-Acl $_.FullName).Owner
if ($owner -notlike "NT AUTHORITY\*" -and $owner -notlike "BUILTIN\*") {
[PSCustomObject]@{
Path = $_.FullName
Owner = $owner
}
}
} | Export-Csv C:\Temp\owners_anomalos.csv -NoTypeInformation
4. Auditando serviços e processos do Windows
Listando serviços vulneráveis ou desnecessários:
Get-Service | Where-Object {
$_.StartType -eq "Automatic" -and
$_.Status -eq "Running" -and
$_.Name -match "RemoteRegistry|Telnet|FTP"
} | Select-Object Name, DisplayName, Status | Format-Table -AutoSize
Verificando assinaturas digitais de processos:
Get-Process | Where-Object { $_.MainModule.FileName -ne $null } |
ForEach-Object {
$signature = Get-AuthenticodeSignature -FilePath $_.MainModule.FileName -ErrorAction SilentlyContinue
[PSCustomObject]@{
ProcessName = $_.ProcessName
PID = $_.Id
FilePath = $_.MainModule.FileName
Status = $signature.Status
SignerCertificate = $signature.SignerCertificate.Subject
}
} | Where-Object { $_.Status -ne "Valid" } | Export-Csv C:\Temp\processos_sem_assinatura.csv -NoTypeInformation
Detectando serviços com contas de alto privilégio:
Get-CimInstance -ClassName Win32_Service |
Where-Object { $_.StartName -match "LocalSystem|NetworkService|LocalService" } |
Select-Object Name, StartName, State | Format-Table -AutoSize
5. Análise de configurações de rede e firewall
Auditando regras de firewall ativas:
Get-NetFirewallRule | Where-Object { $_.Enabled -eq $true -and $_.Direction -eq "Inbound" } |
Select-Object DisplayName, Direction, Action, Profile | Format-Table -AutoSize
Verificando portas abertas e conexões ativas:
Get-NetTCPConnection |
Where-Object { $_.State -eq "Listen" } |
Select-Object LocalPort, OwningProcess |
Sort-Object LocalPort | Format-Table -AutoSize
Identificando regras de bloqueio ausentes:
$criticalPorts = @(22, 3389, 445, 135, 1433)
$existingRules = Get-NetFirewallRule | Where-Object { $_.Direction -eq "Inbound" -and $_.Action -eq "Block" }
foreach ($port in $criticalPorts) {
$ruleExists = $existingRules | Where-Object {
($_ | Get-NetFirewallPortFilter).LocalPort -eq $port
}
if (-not $ruleExists) {
Write-Warning "Porta $port sem regra de bloqueio explícita"
}
}
6. Verificando contas de usuário e grupos de segurança
Listando membros de grupos privilegiados:
$privilegedGroups = @("Administradores", "Administradores de Domínio", "Operadores de Contas", "Operadores de Backup")
foreach ($group in $privilegedGroups) {
try {
$members = Get-LocalGroupMember -Group $group -ErrorAction Stop
Write-Host "=== $group ===" -ForegroundColor Yellow
$members | Select-Object Name, PrincipalSource | Format-Table -AutoSize
} catch {
Write-Warning "Grupo $group não encontrado"
}
}
Auditando contas inativas e senhas expiradas:
Get-LocalUser | Where-Object { $_.Enabled -eq $true } |
ForEach-Object {
$user = $_
$lastLogon = (Get-CimInstance -ClassName Win32_UserProfile |
Where-Object { $_.SID -eq $user.SID }).LastUseTime
[PSCustomObject]@{
UserName = $user.Name
SID = $user.SID
PasswordExpired = $user.PasswordExpired
LastLogon = $lastLogon
DaysSinceLastLogon = if ($lastLogon) { (Get-Date) - $lastLogon | Select-Object -ExpandProperty Days } else { "Nunca" }
}
} | Where-Object { $_.DaysSinceLastLogon -gt 90 -or $_.DaysSinceLastLogon -eq "Nunca" } |
Export-Csv C:\Temp\contas_inativas.csv -NoTypeInformation
7. Gerando relatórios e dashboards de auditoria
Exportando resultados para CSV:
$report = @()
$report += Get-LocalUser | Select-Object Name, Enabled, PasswordExpired, LastLogon
$report += Get-Service | Select-Object Name, Status, StartType
$report += Get-NetFirewallRule | Select-Object DisplayName, Direction, Action, Enabled
$report | Export-Csv C:\Temp\auditoria_completa.csv -NoTypeInformation -Encoding UTF8
Gerando relatório HTML com formatação:
$htmlHeader = @"
<!DOCTYPE html>
<html>
<head>
<title>Relatório de Auditoria de Segurança</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
th { background-color: #4CAF50; color: white; padding: 8px; text-align: left; }
td { border: 1px solid #ddd; padding: 8px; }
tr:nth-child(even) { background-color: #f2f2f2; }
h2 { color: #333; border-bottom: 2px solid #4CAF50; padding-bottom: 5px; }
.warning { background-color: #ff9800; color: white; padding: 10px; margin: 10px 0; }
</style>
</head>
<body>
<h1>Relatório de Auditoria de Segurança</h1>
<p>Gerado em: $(Get-Date)</p>
"@
$htmlFooter = "</body></html>"
$usuarios = Get-LocalUser | Select-Object Name, Enabled, PasswordExpired | ConvertTo-Html -Fragment
$servicos = Get-Service | Where-Object { $_.Status -eq "Running" } | Select-Object Name, DisplayName | ConvertTo-Html -Fragment
$firewall = Get-NetFirewallRule | Where-Object { $_.Enabled -eq $true } | Select-Object DisplayName, Direction, Action | ConvertTo-Html -Fragment
$htmlBody = @"
<h2>Usuários Locais</h2>
$usuarios
<h2>Serviços em Execução</h2>
$servicos
<h2>Regras de Firewall Ativas</h2>
$firewall
"@
$htmlHeader + $htmlBody + $htmlFooter | Out-File C:\Temp\auditoria_seguranca.html -Encoding UTF8
Agendando auditoria recorrente com Task Scheduler:
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\auditoria.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00AM"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "AuditoriaSegurancaDiaria" -Action $action -Trigger $trigger -Principal $principal
Referências
-
Documentação oficial do PowerShell sobre segurança — Diretrizes oficiais da Microsoft para usar PowerShell com segurança, incluindo práticas de auditoria.
-
CIS Benchmarks para Windows Server — Referência completa de baselines de segurança para auditoria de configurações Windows.
-
Guia de auditoria de segurança com PowerShell (Microsoft Learn) — Visão geral da auditoria de segurança no Windows e como PowerShell pode ser usado para coletar logs.
-
PowerShell Security Auditing Scripts (GitHub - Microsoft) — Repositório oficial com scripts prontos para auditoria de configurações de segurança.
-
Tutorial: Automatizando auditoria de segurança com PowerShell (4sysops) — Tutorial prático mostrando como criar scripts de auditoria completos e agendá-los.
-
STIGs para Windows Server (DISA) — Padrões de configuração segura do Departamento de Defesa dos EUA, referência para auditoria avançada.