Enumerate-ADSecurityBaseline.ps1
<#PSScriptInfo .VERSION 1.0.1 .GUID 24ca6a33-e51f-4d26-b723-97318dec940a .AUTHOR kalichuza .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION Enumerates common AD weak point. #> <# .SYNOPSIS Performs a comprehensive Active Directory security baseline enumeration with checks for privileged users, password policies, shadow copy permissions, logging configurations, audit policies, and service accounts. .DESCRIPTION This script conducts various security checks in an Active Directory environment, including: - Enumerating privileged users and groups (Domain Admins, Enterprise Admins, Schema Admins, Administrators) - Evaluating the domain's password policy - Checking permissions on shadow copies and critical files - Gathering logging configurations for system, security, and PowerShell logs - Extracting Active Directory group policies related to auditing - Listing service accounts and their associated Service Principal Names (SPNs) The script can display results in the console or save them to a specified output file. It includes color-coded console output for ease of interpretation. .PARAMETER OutputFile (Optional) Path to a file where the results will be saved. If not specified, the results will only be displayed on the console. .PARAMETER SaveToFile (Optional) Switch to save results to a file. If enabled, you must provide an OutputFile. If not enabled, results will be output to the console only. .PARAMETER ExpectedUsers (Optional) An array of expected privileged user accounts. If any unexpected users are found in the privileged groups, a warning will be shown. Defaults to "ExpectedAdmin1" and "ExpectedAdmin2." .EXAMPLE .\AD-SecurityBaseline.ps1 This command runs the script with default settings, displaying the output in the console without saving to a file. .EXAMPLE .\AD-SecurityBaseline.ps1 -SaveToFile -OutputFile "C:\Reports\SecurityBaseline.txt" This command runs the script and saves the results to the specified file while still displaying them in the console. .EXAMPLE .\AD-SecurityBaseline.ps1 -ExpectedUsers @("AdminUser1", "AdminUser2") This command runs the script and checks for unexpected users in privileged groups, considering "AdminUser1" and "AdminUser2" as the expected users. .NOTES - The script requires the `ActiveDirectory` module to be installed and the user must have appropriate permissions to query AD groups and settings. - Ensure that PowerShell script block logging is configured for best practice monitoring. #> [CmdletBinding()] param ( [string]$OutputFile = "", [switch]$SaveToFile = $false, [string[]]$ExpectedUsers ) # Function to write output to console or file with color function Write-OutputData { param ( [string]$Data, [string]$ForegroundColor = "White" ) if ($SaveToFile -and $OutputFile) { Add-Content -Path $OutputFile -Value $Data } Write-Host $Data -ForegroundColor $ForegroundColor } # Function to display ASCII art in color function Show-AsciiArt { param ( [string]$Art ) Write-Host $Art -ForegroundColor Cyan } # Placeholder for the ASCII art (you can replace this with your own) $asciiArt = @" ########################################################## █████╗ ██████╗ ███████╗███╗ ██╗██╗ ██╗███╗ ███╗ ██╔══██╗██╔══██╗ ██╔════╝████╗ ██║██║ ██║████╗ ████║ ███████║██║ ██║ █████╗ ██╔██╗ ██║██║ ██║██╔████╔██║ ██╔══██║██║ ██║ ██╔══╝ ██║╚██╗██║██║ ██║██║╚██╔╝██║ ██║ ██║██████╔╝ ███████╗██║ ╚████║╚██████╔╝██║ ╚═╝ ██║ ╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ########################################################## "@ # Function to enumerate privileged users and groups with conditional checks function Get-PrivilegedUsersAndGroups { Write-OutputData "`n==== Enumerating Privileged Users and Groups ====" -ForegroundColor Yellow # Domain Admins group members $domainAdmins = Get-ADGroupMember -Identity 'Domain Admins' Write-OutputData "`nDomain Admins:" -ForegroundColor Cyan $domainAdmins | ForEach-Object { Write-OutputData $_.SamAccountName if ($ExpectedUsers -notcontains $_.SamAccountName) { Write-OutputData "Warning: Unexpected member detected in Domain Admins: $($_.SamAccountName)" -ForegroundColor Red } } # Enterprise Admins group members $enterpriseAdmins = Get-ADGroupMember -Identity 'Enterprise Admins' Write-OutputData "`nEnterprise Admins:" -ForegroundColor Cyan $enterpriseAdmins | ForEach-Object { Write-OutputData $_.SamAccountName if ($ExpectedUsers -notcontains $_.SamAccountName) { Write-OutputData "Warning: Unexpected member detected in Enterprise Admins: $($_.SamAccountName)" -ForegroundColor Red } } # Other admin groups like Schema Admins and Administrators $otherAdminGroups = @('Schema Admins', 'Administrators') foreach ($group in $otherAdminGroups) { $groupOutput = "`n${group}:" Write-OutputData $groupOutput -ForegroundColor Cyan $members = Get-ADGroupMember -Identity $group $members | ForEach-Object { Write-OutputData $_.SamAccountName if ($ExpectedUsers -notcontains $_.SamAccountName) { Write-OutputData "Warning: Unexpected member detected in ${group}: $($_.SamAccountName)" -ForegroundColor Red } } } } # Function to check Password Policies and flag weak settings function Get-PasswordPolicy { Write-OutputData "`n==== Password Policies ====" -ForegroundColor Yellow $domainPolicy = Get-ADDefaultDomainPasswordPolicy Write-OutputData "`nPassword Policy for the Domain:" -ForegroundColor Cyan Write-OutputData "MinimumPasswordLength: $($domainPolicy.MinPasswordLength)" Write-OutputData "MaximumPasswordAge: $($domainPolicy.MaxPasswordAge)" Write-OutputData "PasswordHistoryCount: $($domainPolicy.PasswordHistoryCount)" Write-OutputData "LockoutThreshold: $($domainPolicy.LockoutThreshold)" # Flag weak password settings if ($domainPolicy.MinPasswordLength -lt 12) { Write-OutputData "Warning: Minimum password length is less than 12 characters!" -ForegroundColor Red } } # Function to check for vulnerable permissions on Shadow Copy and VSS function Check-ShadowCopyPermissions { Write-OutputData "`n==== Checking Shadow Copy Permissions ====" -ForegroundColor Yellow $vssPermissions = Get-WmiObject -Class Win32_ShadowCopy | Select-Object DeviceObject,ID,InstallDate Write-OutputData "Shadow Copies:" -ForegroundColor Cyan $vssPermissions | ForEach-Object { Write-OutputData "Shadow Copy ID: $($_.ID), InstallDate: $($_.InstallDate), DeviceObject: $($_.DeviceObject)" } $shadowCopyAccess = Get-Acl -Path "C:\Windows\System32\config\SYSTEM" Write-OutputData "`nPermissions on SYSTEM file (shadow copy target):" -ForegroundColor Cyan $shadowCopyAccess.Access | ForEach-Object { Write-OutputData "Identity: $($_.IdentityReference), Permissions: $($_.FileSystemRights)" } } # Function to get Event Log configurations (PowerShell, System, Security) function Get-LoggingConfiguration { Write-OutputData "`n==== Logging Configuration ====" -ForegroundColor Yellow $logSettings = @('System', 'Security', 'Application', 'Microsoft-Windows-PowerShell/Operational') foreach ($log in $logSettings) { $logSize = Get-WinEvent -ListLog $log | Select-Object -ExpandProperty MaximumSizeInBytes Write-OutputData "`n$($log) Log:" -ForegroundColor Cyan Write-OutputData "Log Size (bytes): $logSize" } # PowerShell script block logging status $scriptBlockLogging = Get-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -ErrorAction SilentlyContinue if ($scriptBlockLogging) { Write-OutputData "`nPowerShell ScriptBlock Logging:" -ForegroundColor Cyan Write-OutputData "Enabled: $($scriptBlockLogging.EnableScriptBlockLogging)" } else { Write-OutputData "`nPowerShell ScriptBlock Logging: Not Configured" -ForegroundColor Cyan } } # Function to get Active Directory Group Policies related to auditing with cleaned-up XML output function Get-AuditPolicies { Write-OutputData "`n==== Auditing Policies ====" -ForegroundColor Yellow $auditSettings = Get-GPOReport -All -ReportType Xml Write-OutputData "Active Directory Auditing Policies (Cleaned):" -ForegroundColor Cyan $auditSettings = [xml]$auditSettings $auditSettings.GPO.Report.Policy | ForEach-Object { Write-OutputData "Policy Name: $($_.Name), Enabled: $($_.Enabled)" -ForegroundColor Cyan } } # Function to enumerate Service Accounts and Privileges function Get-ServiceAccounts { Write-OutputData "`n==== Service Accounts Enumeration ====" -ForegroundColor Yellow $serviceAccounts = Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Property SamAccountName,ServicePrincipalName Write-OutputData "Service Accounts:" -ForegroundColor Cyan $serviceAccounts | ForEach-Object { Write-OutputData "Account: $($_.SamAccountName), SPN: $($_.ServicePrincipalName)" } } # Main enumeration with ASCII art and color Write-OutputData "`nStarting AD Security Baseline Enumeration..." -ForegroundColor Green # Display the ASCII art Show-AsciiArt -Art $asciiArt # Check if saving to a file is requested if ($SaveToFile -and $OutputFile) { Write-OutputData "Results will be saved to: $OutputFile" -ForegroundColor Green } # Run enumeration functions Get-PrivilegedUsersAndGroups Get-PasswordPolicy Check-ShadowCopyPermissions Get-LoggingConfiguration Get-AuditPolicies Get-ServiceAccounts Write-OutputData "`nEnumeration complete." -ForegroundColor Green |