Como usar o PowerShell para auditar permissões de arquivos e pastas

1. Introdução à auditoria de permissões no Windows

Auditar permissões de arquivos e pastas é uma prática fundamental para garantir a segurança da informação e a conformidade com regulamentações como LGPD, SOX e ISO 27001. Sem uma auditoria adequada, é impossível saber quem tem acesso a dados sensíveis, se há permissões excessivas concedidas ou se contas desativadas ainda possuem acesso a recursos críticos.

As ferramentas gráficas do Windows, como o Explorador de Arquivos e o Gerenciamento do Computador, são limitadas para auditorias em larga escala. Verificar permissões pasta por pasta manualmente é inviável em ambientes com centenas ou milhares de diretórios. O PowerShell surge como a solução ideal, oferecendo cmdlets poderosos como Get-Acl e Set-Acl para automatizar todo o processo de auditoria e correção de permissões.

2. Compreendendo a estrutura de ACLs com Get-Acl

O cmdlet Get-Acl é a porta de entrada para auditar permissões no Windows. Ele retorna um objeto do tipo System.Security.AccessControl.FileSecurity que contém todas as regras de acesso (Access Rules) aplicadas ao recurso.

# Obtendo a ACL de um arquivo específico
$acl = Get-Acl -Path "C:\Dados\contrato.pdf"
$acl.Access | Format-Table IdentityReference, FileSystemRights, AccessControlType, IsInherited

A saída mostra colunas essenciais:
- IdentityReference: o usuário ou grupo (ex: DOMINIO\joao, BUILTIN\Administrators)
- FileSystemRights: o tipo de permissão (FullControl, Modify, ReadAndExecute, etc.)
- AccessControlType: Allow (permitir) ou Deny (negar)
- IsInherited: True se a permissão veio da pasta pai, False se foi definida diretamente

Para pastas, a estrutura é semelhante, mas inclui propriedades adicionais como AccessRule.PropagationFlags e AccessRule.InheritanceFlags, que controlam como as permissões se propagam para subpastas e arquivos.

3. Gerando relatórios de permissões para múltiplos caminhos

Para auditar uma árvore completa de diretórios, combinamos Get-ChildItem com Get-Acl e exportamos os resultados para um arquivo CSV.

# Script para gerar relatório completo de permissões de uma pasta compartilhada
$reportPath = "C:\Relatorios\permissoes_$(Get-Date -Format yyyyMMdd).csv"

$results = Get-ChildItem -Path "D:\Compartilhado" -Recurse -Directory | ForEach-Object {
    $acl = Get-Acl -Path $_.FullName
    foreach ($rule in $acl.Access) {
        [PSCustomObject]@{
            Caminho         = $_.FullName
            Usuario         = $rule.IdentityReference
            Direitos        = $rule.FileSystemRights
            Tipo            = $rule.AccessControlType
            Herdado         = $rule.IsInherited
            HeredePara      = if ($rule.InheritanceFlags -ne "None") { $rule.InheritanceFlags } else { "NaoPropaga" }
        }
    }
}

$results | Export-Csv -Path $reportPath -NoTypeInformation -Encoding UTF8
Write-Host "Relatório gerado em: $reportPath"

Este script percorre todas as subpastas recursivamente e extrai cada regra de acesso individualmente. O resultado é um CSV detalhado que pode ser aberto no Excel para análise.

4. Identificando permissões inseguras ou excessivas

Um dos usos mais críticos da auditoria é detectar contas com privilégios excessivos. O script abaixo localiza pastas onde o grupo "Everyone" ou "Usuários" tem acesso de modificação ou controle total.

# Detectando permissões inseguras (Everyone com FullControl ou Modify)
$pastasRisco = Get-ChildItem -Path "D:\Compartilhado" -Recurse -Directory | ForEach-Object {
    $acl = Get-Acl -Path $_.FullName
    $regrasPerigosas = $acl.Access | Where-Object {
        $_.IdentityReference -match "Everyone|Usuarios" -and
        $_.FileSystemRights -match "FullControl|Modify|Write" -and
        $_.AccessControlType -eq "Allow"
    }
    if ($regrasPerigosas) {
        [PSCustomObject]@{
            Caminho = $_.FullName
            Contas  = ($regrasPerigosas.IdentityReference -join "; ")
            Direitos = ($regrasPerigosas.FileSystemRights -join "; ")
        }
    }
}

$pastasRisco | Export-Csv -Path "C:\Relatorios\pastas_risco.csv" -NoTypeInformation
$pastasRisco | Format-Table -AutoSize

Também é possível filtrar permissões explícitas (não herdadas) para identificar regras que foram adicionadas manualmente:

# Listando apenas permissões explícitas (não herdadas)
Get-Acl -Path "D:\Compartilhado\Financeiro" | Select-Object -ExpandProperty Access |
    Where-Object { $_.IsInherited -eq $false } |
    Format-Table IdentityReference, FileSystemRights

5. Comparando permissões entre ambientes (baseline)

Para detectar mudanças não autorizadas, podemos capturar um snapshot das permissões e compará-lo com um snapshot posterior.

# Função para capturar snapshot de permissões
function Get-PermissionSnapshot {
    param([string]$Path)

    Get-ChildItem -Path $Path -Recurse -Directory | ForEach-Object {
        $acl = Get-Acl -Path $_.FullName
        foreach ($rule in $acl.Access) {
            [PSCustomObject]@{
                Caminho   = $_.FullName
                Usuario   = $rule.IdentityReference
                Direitos  = $rule.FileSystemRights
                Tipo      = $rule.AccessControlType
            }
        }
    }
}

# Capturar baseline e snapshot atual
$baseline = Get-PermissionSnapshot -Path "D:\Dados" | Export-Clixml -Path "C:\Snapshots\baseline.xml"
$atual = Get-PermissionSnapshot -Path "D:\Dados"

# Comparar com snapshot anterior
$comparacao = Compare-Object -ReferenceObject (Import-Clixml "C:\Snapshots\baseline.xml") -DifferenceObject $atual -Property Caminho, Usuario, Direitos, Tipo

if ($comparacao) {
    Write-Host "Mudanças detectadas nas permissões!" -ForegroundColor Red
    $comparacao | Group-Object SideIndicator | ForEach-Object {
        if ($_.Name -eq "=>") { Write-Host "Novas permissões adicionadas:" }
        if ($_.Name -eq "<=") { Write-Host "Permissões removidas:" }
        $_.Group | Format-Table Caminho, Usuario, Direitos -AutoSize
    }
} else {
    Write-Host "Nenhuma alteração detectada." -ForegroundColor Green
}

6. Automatizando a correção de permissões com Set-Acl

Após identificar permissões problemáticas, podemos corrigi-las programaticamente. O processo envolve modificar o objeto ACL e aplicar as alterações com Set-Acl.

# Removendo permissão de "Everyone" com controle total de uma pasta específica
$path = "D:\Compartilhado\Publico"
$acl = Get-Acl -Path $path

$regraRemover = $acl.Access | Where-Object {
    $_.IdentityReference -eq "Everyone" -and
    $_.FileSystemRights -eq "FullControl" -and
    $_.AccessControlType -eq "Allow"
}

foreach ($regra in $regraRemover) {
    $acl.RemoveAccessRule($regra)
}

Set-Acl -Path $path -AclObject $acl
Write-Host "Permissão insegura removida de: $path"

Para adicionar uma nova permissão:

# Adicionando permissão de leitura para um grupo específico
$path = "D:\Compartilhado\RH"
$acl = Get-Acl -Path $path

$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "DOMINIO\GrupoRH",           # Conta ou grupo
    "ReadAndExecute",            # Direitos
    "ContainerInherit,ObjectInherit",  # Herança para subpastas e arquivos
    "None",                      # Flags de propagação
    "Allow"                      # Tipo: Allow ou Deny
)

$acl.AddAccessRule($rule)
Set-Acl -Path $path -AclObject $acl

Para aplicar correções em lote:

# Removendo Everyone de todas as subpastas
Get-ChildItem -Path "D:\Compartilhado" -Recurse -Directory | ForEach-Object {
    $acl = Get-Acl -Path $_.FullName
    $regrasEveryone = $acl.Access | Where-Object { $_.IdentityReference -eq "Everyone" }

    foreach ($regra in $regrasEveryone) {
        $acl.RemoveAccessRule($regra)
    }

    Set-Acl -Path $_.FullName -AclObject $acl
    Write-Host "Corrigido: $($_.FullName)"
}

7. Auditoria avançada: logs de eventos e herança

Os logs de auditoria do Windows fornecem informações sobre quem realmente acessou os recursos. Para habilitar a auditoria, é necessário configurar a Política de Auditoria no Windows (Event ID 4663 para acesso a objetos, 4656 para handle aberto).

# Consultando logs de auditoria de acesso a arquivos
$eventos = Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    ID        = 4663
    StartTime = (Get-Date).AddDays(-7)
} | Where-Object {
    $_.Properties[6].Value -match "D:\\Compartilhado"
}

$eventos | Select-Object TimeCreated,
    @{N="Usuario";E={$_.Properties[1].Value}},
    @{N="Arquivo";E={$_.Properties[6].Value}},
    @{N="Acesso";E={$_.Properties[10].Value}} |
    Format-Table -AutoSize

Para verificar herança quebrada em pastas:

# Detectando pastas com herança desabilitada (permissões explícitas sem herança)
$pastasHerancaQuebrada = Get-ChildItem -Path "D:\Compartilhado" -Recurse -Directory | ForEach-Object {
    $acl = Get-Acl -Path $_.FullName
    if (-not $acl.AreAccessRulesProtected) {
        # A herança está habilitada, mas precisamos verificar se há regras explícitas
        $regrasExplicitas = $acl.Access | Where-Object { $_.IsInherited -eq $false }
        if ($regrasExplicitas) {
            [PSCustomObject]@{
                Caminho = $_.FullName
                RegrasExplicitas = ($regrasExplicitas.IdentityReference -join "; ")
            }
        }
    }
}

$pastasHerancaQuebrada | Format-Table -AutoSize

8. Boas práticas e considerações finais

Ao auditar permissões em grandes volumes de dados, algumas práticas são essenciais:

Performance: Para pastas com milhares de itens, use -Directory para focar apenas em pastas e evite processar arquivos individuais quando não necessário. Considere usar -Depth em vez de -Recurse para limitar a profundidade da varredura.

Backup de ACLs: Antes de qualquer modificação em massa, salve as ACLs originais:

# Backup de todas as ACLs de uma estrutura
Get-ChildItem -Path "D:\Compartilhado" -Recurse -Directory | ForEach-Object {
    $acl = Get-Acl -Path $_.FullName
    $acl | Export-Clixml -Path "C:\BackupACLs\$($_.Name)_acl.xml"
}

Relatórios periódicos: Automatize a geração de relatórios com o Agendador de Tarefas do Windows, executando scripts semanalmente para manter a conformidade contínua.

Integração com compliance: Exporte os relatórios em formatos padronizados (CSV, XML) para alimentar ferramentas de GRC (Governance, Risk and Compliance) como ServiceNow, Archer ou sistemas de SIEM.

A auditoria de permissões com PowerShell não é apenas uma tarefa técnica — é uma prática de governança que protege dados críticos, evita vazamentos e demonstra conformidade em auditorias externas. Com os scripts apresentados, você tem um kit completo para implementar um programa robusto de gerenciamento de acesso a arquivos e pastas no Windows.

Referências