Hardening/Enable-AuditPolicies.ps1
|
function Enable-AuditPolicies { <# .SYNOPSIS Configures Windows audit policies for security monitoring .DESCRIPTION Enables comprehensive audit policies for tracking security events including logon, account management, object access, policy changes, and privilege use .PARAMETER AuditLevel Audit level: Basic, Standard, or Comprehensive .PARAMETER IncludeFileAuditing Enable file and folder access auditing .PARAMETER IncludeRegistryAuditing Enable registry access auditing .EXAMPLE Enable-AuditPolicies -AuditLevel Standard Enable-AuditPolicies -AuditLevel Comprehensive -IncludeFileAuditing -IncludeRegistryAuditing .OUTPUTS PSCustomObject with audit configuration results #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter()] [ValidateSet('Basic', 'Standard', 'Comprehensive')] [string]$AuditLevel = 'Standard', [Parameter()] [switch]$IncludeFileAuditing, [Parameter()] [switch]$IncludeRegistryAuditing ) begin { Write-Host "=== WINDOWS AUDIT POLICIES CONFIGURATION ===" -ForegroundColor Cyan Write-Host "Audit Level: $AuditLevel" -ForegroundColor Yellow Write-Host "Start Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow # Check for admin privileges $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { throw "This function requires Administrator privileges!" } $results = [PSCustomObject]@{ ConfigurationDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" AuditLevel = $AuditLevel PoliciesConfigured = @() Errors = @() AuditCategories = @{ AccountLogon = @{} AccountManagement = @{} DetailedTracking = @{} LogonLogoff = @{} ObjectAccess = @{} PolicyChange = @{} PrivilegeUse = @{} System = @{} } } # Audit policy settings based on level $auditSettings = @{ Basic = @{ 'Account Logon' = @('Credential Validation') 'Account Management' = @('User Account Management', 'Security Group Management') 'Logon/Logoff' = @('Logon', 'Logoff', 'Account Lockout') 'Policy Change' = @('Audit Policy Change', 'Authentication Policy Change') 'System' = @('Security State Change', 'Security System Extension') } Standard = @{ 'Account Logon' = @('Credential Validation', 'Kerberos Authentication Service') 'Account Management' = @('User Account Management', 'Security Group Management', 'Computer Account Management') 'Detailed Tracking' = @('Process Creation', 'Process Termination') 'Logon/Logoff' = @('Logon', 'Logoff', 'Account Lockout', 'Special Logon') 'Object Access' = @('File System', 'Registry', 'Handle Manipulation') 'Policy Change' = @('Audit Policy Change', 'Authentication Policy Change', 'Authorization Policy Change') 'Privilege Use' = @('Sensitive Privilege Use') 'System' = @('Security State Change', 'Security System Extension', 'System Integrity') } Comprehensive = @{ 'Account Logon' = @('Credential Validation', 'Kerberos Authentication Service', 'Kerberos Service Ticket Operations') 'Account Management' = @('User Account Management', 'Security Group Management', 'Computer Account Management', 'Distribution Group Management', 'Application Group Management') 'Detailed Tracking' = @('Process Creation', 'Process Termination', 'DPAPI Activity', 'RPC Events', 'Plug and Play Events') 'Logon/Logoff' = @('Logon', 'Logoff', 'Account Lockout', 'Special Logon', 'Other Logon/Logoff Events', 'Network Policy Server') 'Object Access' = @('File System', 'Registry', 'Kernel Object', 'SAM', 'Handle Manipulation', 'File Share', 'Filtering Platform Packet Drop', 'Filtering Platform Connection') 'Policy Change' = @('Audit Policy Change', 'Authentication Policy Change', 'Authorization Policy Change', 'MPSSVC Rule-Level Policy Change', 'Filtering Platform Policy Change') 'Privilege Use' = @('Sensitive Privilege Use', 'Non Sensitive Privilege Use') 'System' = @('Security State Change', 'Security System Extension', 'System Integrity', 'IPsec Driver', 'Other System Events') } } foreach ($level in @($auditSettings.Keys)) { foreach ($category in @($auditSettings[$level].Keys)) { $auditSettings[$level][$category] = @($auditSettings[$level][$category] | ForEach-Object { @{ Name = $_; Guid = Get-AuditSubcategoryGuid -Name $_ } }) } } } process { try { $selectedSettings = $auditSettings[$AuditLevel] $totalCategories = ($selectedSettings.Keys | Measure-Object).Count $currentCategory = 0 foreach ($category in $selectedSettings.Keys) { $currentCategory++ Write-Host "`n[$currentCategory/$totalCategories] Configuring: $category" -ForegroundColor Cyan foreach ($subcategory in $selectedSettings[$category]) { try { if ($null -eq $subcategory.Guid) { Write-Warning " - Skipped: $($subcategory.Name) (no GUID in subcategory map)" continue } # Enable both Success and Failure auditing if ($PSCmdlet.ShouldProcess($subcategory.Name, "Enable audit policy")) { $result = & auditpol /set /subcategory:"$($subcategory.Guid)" /success:enable /failure:enable 2>&1 if ($LASTEXITCODE -eq 0) { $results.PoliciesConfigured += $subcategory.Name Write-Host " + $($subcategory.Name)" -ForegroundColor Green } else { $results.Errors += "Failed to configure: $($subcategory.Name) - $result" Write-Warning " - Failed: $($subcategory.Name)" } } } catch { $results.Errors += "Error configuring $($subcategory.Name) : $_" Write-Warning " - Error: $($subcategory.Name)" } } # Store category status $categoryKey = $category -replace '[/ ]', '' if ($results.AuditCategories.ContainsKey($categoryKey)) { $results.AuditCategories[$categoryKey] = @{ Configured = $true Subcategories = @($selectedSettings[$category] | ForEach-Object { $_.Name }) } } } # Configure Advanced Audit Policies Write-Host "`n[ADVANCED] Configuring advanced audit settings..." -ForegroundColor Cyan # Force audit policy subcategory settings try { $regPath = "HKLM:\System\CurrentControlSet\Control\Lsa" if ($PSCmdlet.ShouldProcess($regPath, "Enable advanced audit policy mode (SCENoApplyLegacyAuditPolicy)")) { Set-ItemProperty -Path $regPath -Name "SCENoApplyLegacyAuditPolicy" -Value 1 -Type DWord -Force Write-Host " + Advanced audit policy mode enabled" -ForegroundColor Green $results.PoliciesConfigured += "Advanced Audit Policy Mode" } } catch { $results.Errors += "Failed to enable advanced audit mode: $_" Write-Warning " - Failed to enable advanced audit mode" } # Increase Security event log size try { $logName = 'Security' if ($PSCmdlet.ShouldProcess($logName, "Set Security event log maximum size to 1GB")) { $log = Get-WinEvent -ListLog $logName # Set to 1GB $log.MaximumSizeInBytes = 1GB $log.SaveChanges() Write-Host " + Security log size increased to 1GB" -ForegroundColor Green $results.PoliciesConfigured += "Security Log Size: 1GB" } } catch { $results.Errors += "Failed to increase log size: $_" Write-Warning " - Failed to increase log size" } # Enable log retention try { if ($PSCmdlet.ShouldProcess("Security", "Configure Security log retention (archive full log, no overwrite)")) { wevtutil sl Security /rt:false /ab:true Write-Host " + Security log retention enabled" -ForegroundColor Green $results.PoliciesConfigured += "Security Log Retention" } } catch { $results.Errors += "Failed to configure log retention: $_" } # Configure Command Line Process Auditing if ($AuditLevel -in @('Standard', 'Comprehensive')) { Write-Host "`n[PROCESS] Enabling command line process auditing..." -ForegroundColor Cyan try { $regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" if ($PSCmdlet.ShouldProcess($regPath, "Enable command line process auditing")) { if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } Set-ItemProperty -Path $regPath -Name "ProcessCreationIncludeCmdLine_Enabled" -Value 1 -Type DWord -Force Write-Host " + Command line auditing enabled" -ForegroundColor Green $results.PoliciesConfigured += "Command Line Process Auditing" } } catch { $results.Errors += "Failed to enable command line auditing: $_" Write-Warning " - Failed to enable command line auditing" } } # File System Auditing if ($IncludeFileAuditing -or $AuditLevel -eq 'Comprehensive') { Write-Host "`n[FILE SYSTEM] Configuring file system auditing..." -ForegroundColor Cyan $pathsToAudit = @( "$env:SystemRoot\System32", "$env:ProgramFiles", "$env:USERPROFILE\Documents" ) $fileAuditApplied = $false foreach ($path in $pathsToAudit) { if (Test-Path $path) { try { if ($PSCmdlet.ShouldProcess($path, "Add file system audit rule (Everyone: Delete/ChangePermissions/TakeOwnership)")) { # Get current ACL $acl = Get-Acl $path # Create audit rule for Everyone - Track both Success and Failure $auditRule = New-Object System.Security.AccessControl.FileSystemAuditRule( (New-Object System.Security.Principal.SecurityIdentifier('S-1-1-0')), "Delete,DeleteSubdirectoriesAndFiles,ChangePermissions,TakeOwnership", "ContainerInherit,ObjectInherit", "None", "Success,Failure" ) # Add audit rule $acl.AddAuditRule($auditRule) Set-Acl -Path $path -AclObject $acl Write-Host " + Auditing enabled on: $path" -ForegroundColor Green $fileAuditApplied = $true } } catch { Write-Warning " - Failed to audit: $path" } } } if ($fileAuditApplied) { $results.PoliciesConfigured += "File System Auditing" } } # Registry Auditing if ($IncludeRegistryAuditing -or $AuditLevel -eq 'Comprehensive') { Write-Host "`n[REGISTRY] Configuring registry auditing..." -ForegroundColor Cyan $regKeysToAudit = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", "HKLM:\SYSTEM\CurrentControlSet\Services" ) $registryAuditApplied = $false foreach ($regKey in $regKeysToAudit) { if (Test-Path $regKey) { try { if ($PSCmdlet.ShouldProcess($regKey, "Add registry audit rule (Everyone: SetValue/CreateSubKey/Delete)")) { $acl = Get-Acl $regKey $auditRule = New-Object System.Security.AccessControl.RegistryAuditRule( (New-Object System.Security.Principal.SecurityIdentifier('S-1-1-0')), "SetValue,CreateSubKey,Delete", "ContainerInherit", "None", "Success,Failure" ) $acl.AddAuditRule($auditRule) Set-Acl -Path $regKey -AclObject $acl Write-Host " + Auditing enabled on: $regKey" -ForegroundColor Green $registryAuditApplied = $true } } catch { Write-Warning " - Failed to audit: $regKey" } } } if ($registryAuditApplied) { $results.PoliciesConfigured += "Registry Auditing" } } } catch { Write-Error "Error during audit policy configuration: $_" throw } } end { Write-Host "`n=== AUDIT CONFIGURATION COMPLETE ===" -ForegroundColor Green Write-Host "`nPolicies Configured: $($results.PoliciesConfigured.Count)" -ForegroundColor Cyan if ($results.Errors.Count -gt 0) { Write-Host "`nErrors: $($results.Errors.Count)" -ForegroundColor Red $results.Errors | ForEach-Object { Write-Host " - $_" -ForegroundColor Red } } Write-Host "`nAudit Summary:" -ForegroundColor Cyan Write-Host " Level: $($results.AuditLevel)" -ForegroundColor White Write-Host " Policies Enabled: $($results.PoliciesConfigured.Count)" -ForegroundColor White Write-Host " Security Log: 1GB" -ForegroundColor White # Verify current audit policy Write-Host "`nVerifying configuration..." -ForegroundColor Cyan $auditTable = Get-AuditPolicyTable -Force $verifiedPolicies = 0 $unverifiedPolicies = @() foreach ($category in $selectedSettings.Keys) { foreach ($subcategory in $selectedSettings[$category]) { if ($null -eq $subcategory.Guid) { continue } $guidKey = ($subcategory.Guid -replace '[{}]', '').ToLowerInvariant() if ($auditTable.ContainsKey($guidKey) -and $null -ne $auditTable[$guidKey].Value -and $auditTable[$guidKey].Value -ge 1 -and $auditTable[$guidKey].Value -le 3) { $verifiedPolicies++ } else { $unverifiedPolicies += $subcategory.Name } } } Write-Host " Verified: $verifiedPolicies subcategories with auditing enabled" -ForegroundColor White if ($unverifiedPolicies.Count -gt 0) { Write-Host " Unverified: $($unverifiedPolicies.Count)" -ForegroundColor Yellow foreach ($name in $unverifiedPolicies) { Write-Host " - $name" -ForegroundColor Yellow } } Write-Host "`nRecommendations:" -ForegroundColor Cyan Write-Host " 1. Monitor Security event log regularly" -ForegroundColor White Write-Host " 2. Set up log forwarding to SIEM if available" -ForegroundColor White Write-Host " 3. Review audit events daily for suspicious activity" -ForegroundColor White Write-Host " 4. Implement log retention policy" -ForegroundColor White Write-Host " 5. Test audit logging with known actions" -ForegroundColor White Write-Host "`nImportant Event IDs to monitor:" -ForegroundColor Yellow Write-Host " 4624 - Successful logon" -ForegroundColor White Write-Host " 4625 - Failed logon" -ForegroundColor White Write-Host " 4672 - Special privileges assigned" -ForegroundColor White Write-Host " 4720 - User account created" -ForegroundColor White Write-Host " 4740 - User account locked out" -ForegroundColor White Write-Host " 4688 - Process created" -ForegroundColor White return $results } } |