Update Test-WeakADPasswords.ps1 to first prodution version.
This commit is contained in:
@@ -8,20 +8,34 @@
|
|||||||
##################################################
|
##################################################
|
||||||
## Project: Elysium ##
|
## Project: Elysium ##
|
||||||
## File: Test-WeakADPasswords.ps1 ##
|
## File: Test-WeakADPasswords.ps1 ##
|
||||||
## Version: 0.1 ##
|
## Version: 1.0 ##
|
||||||
## Support: support@cqre.net ##
|
## Support: support@cqre.net ##
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
|
# Current timestamp for both report generation and header
|
||||||
|
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
|
||||||
|
|
||||||
|
# Define Header and Footer for the report with dynamic date
|
||||||
|
$header = @"
|
||||||
|
=========== Elysium Report ==========
|
||||||
|
Report Generated: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
"@
|
||||||
|
$footer = "`r`n==== End of Report ===="
|
||||||
|
|
||||||
# Import settings
|
# Import settings
|
||||||
Write-Host "Loading settings..."
|
Write-Host "Loading settings..."
|
||||||
$ElysiumSettings = @{}
|
$ElysiumSettings = @{}
|
||||||
$settingsPath = "ElysiumSettings.txt"
|
$settingsPath = "ElysiumSettings.txt"
|
||||||
|
|
||||||
|
# Ensure the settings file exists
|
||||||
if (-not (Test-Path $settingsPath)) {
|
if (-not (Test-Path $settingsPath)) {
|
||||||
Write-Error "Settings file not found at $settingsPath"
|
Write-Error "Settings file not found at $settingsPath"
|
||||||
return
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Load settings from file
|
||||||
Get-Content $settingsPath | ForEach-Object {
|
Get-Content $settingsPath | ForEach-Object {
|
||||||
if (-not [string]::IsNullOrWhiteSpace($_) -and -not $_.StartsWith("#")) {
|
if (-not [string]::IsNullOrWhiteSpace($_) -and -not $_.StartsWith("#")) {
|
||||||
$keyValue = $_ -split '=', 2
|
$keyValue = $_ -split '=', 2
|
||||||
@@ -31,80 +45,54 @@ Get-Content $settingsPath | ForEach-Object {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Required modules
|
||||||
|
$requiredModules = @("DSInternals", "ActiveDirectory")
|
||||||
|
|
||||||
|
# Check each required module and import
|
||||||
|
foreach ($module in $requiredModules) {
|
||||||
|
if (-not (Get-Module -ListAvailable -Name $module)) {
|
||||||
|
Write-Error "Required module '$module' is not installed. Please install it to proceed."
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
Import-Module $module
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify the existence of the Weak Password Hashes file
|
||||||
$WeakHashesSortedFilePath = Join-Path -Path $ElysiumSettings["InstallationPath"] -ChildPath $ElysiumSettings["WeakPasswordsDatabase"]
|
$WeakHashesSortedFilePath = Join-Path -Path $ElysiumSettings["InstallationPath"] -ChildPath $ElysiumSettings["WeakPasswordsDatabase"]
|
||||||
if (-not (Test-Path $WeakHashesSortedFilePath)) {
|
if (-not (Test-Path $WeakHashesSortedFilePath)) {
|
||||||
Write-Error "Weak password hashes file not found at '$WeakHashesSortedFilePath'."
|
Write-Error "Weak password hashes file not found at '$WeakHashesSortedFilePath'."
|
||||||
return
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if required modules are available and install them if necessary
|
# Ensure the report directory exists
|
||||||
$requiredModules = @("DSInternals", "ActiveDirectory")
|
|
||||||
foreach ($module in $requiredModules) {
|
|
||||||
if (-not (Get-Module -ListAvailable -Name $module)) {
|
|
||||||
$userConsent = Read-Host "Module '$module' is not installed. Do you want to install it now? (Y/N)"
|
|
||||||
if ($userConsent -eq 'Y') {
|
|
||||||
try {
|
|
||||||
Write-Host "Installing module '$module'..."
|
|
||||||
Install-Module -Name $module -Force -Scope CurrentUser
|
|
||||||
Write-Host "Module '$module' installed successfully."
|
|
||||||
} catch {
|
|
||||||
Write-Error "Failed to install module '$module'. Error: $_"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Write-Host "Skipping module installation. Script may not function correctly without the required modules."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Import required modules
|
|
||||||
Import-Module DSInternals
|
|
||||||
Import-Module ActiveDirectory
|
|
||||||
|
|
||||||
# Get the variables from settings
|
|
||||||
$WeakHashesSortedFilePath = $ElysiumSettings["WeakPasswordsDatabase"]
|
|
||||||
# Get the report path from settings
|
|
||||||
$reportPathBase = $ElysiumSettings["ReportPathBase"]
|
$reportPathBase = $ElysiumSettings["ReportPathBase"]
|
||||||
if ($null -eq $reportPathBase) {
|
|
||||||
Write-Error "Report path is not defined in the settings."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if the report directory exists, create it if it doesn't
|
|
||||||
if (-not (Test-Path -Path $reportPathBase)) {
|
if (-not (Test-Path -Path $reportPathBase)) {
|
||||||
Write-Host "Report directory does not exist. Creating directory at $reportPathBase..."
|
|
||||||
New-Item -Path $reportPathBase -ItemType Directory
|
New-Item -Path $reportPathBase -ItemType Directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Extract domain details from settings
|
||||||
# Function to extract domain details from settings
|
|
||||||
function Get-DomainDetailsFromSettings {
|
function Get-DomainDetailsFromSettings {
|
||||||
param (
|
param (
|
||||||
[hashtable]$ElysiumSettings
|
[hashtable]$Settings
|
||||||
)
|
)
|
||||||
|
|
||||||
Write-Host "Extracting domain details from settings..."
|
|
||||||
$domainDetails = @{}
|
$domainDetails = @{}
|
||||||
$domainCounter = 1
|
$counter = 1
|
||||||
|
|
||||||
while ($true) {
|
while ($true) {
|
||||||
$domainNameKey = "Domain${domainCounter}Name"
|
$nameKey = "Domain${counter}Name"
|
||||||
$domainDCKey = "Domain${domainCounter}DC"
|
$dcKey = "Domain${counter}DC"
|
||||||
$domainDAKey = "Domain${domainCounter}DA"
|
$daKey = "Domain${counter}DA"
|
||||||
|
if ($Settings.ContainsKey($nameKey)) {
|
||||||
if ($ElysiumSettings.ContainsKey($domainNameKey)) {
|
$domainDetails["$counter"] = @{
|
||||||
$domainDetails["$domainCounter"] = @{
|
Name = $Settings[$nameKey]
|
||||||
"Name" = $ElysiumSettings[$domainNameKey]
|
DC = $Settings[$dcKey]
|
||||||
"DC" = $ElysiumSettings[$domainDCKey]
|
DA = $Settings[$daKey]
|
||||||
"DA" = $ElysiumSettings[$domainDAKey]
|
|
||||||
}
|
}
|
||||||
$domainCounter++
|
$counter++
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $domainDetails
|
return $domainDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,26 +100,18 @@ function Get-DomainDetailsFromSettings {
|
|||||||
function Test-WeakADPasswords {
|
function Test-WeakADPasswords {
|
||||||
param (
|
param (
|
||||||
[hashtable]$DomainDetails,
|
[hashtable]$DomainDetails,
|
||||||
[string]$WeakHashesSortedFilePath
|
[string]$FilePath
|
||||||
)
|
)
|
||||||
|
|
||||||
Write-Host "Starting the test for weak AD passwords..."
|
|
||||||
|
|
||||||
# Display domain options to the user
|
|
||||||
Write-Host "Select a domain to test:"
|
|
||||||
$sortedDomains = $DomainDetails.Keys | Sort-Object
|
|
||||||
foreach ($domain in $sortedDomains) {
|
|
||||||
$domainName = $DomainDetails[$domain].Name
|
|
||||||
Write-Host ($domain + ": " + $domainName)
|
|
||||||
}
|
|
||||||
|
|
||||||
# User selects a domain
|
# User selects a domain
|
||||||
$selectedDomainKey = Read-Host "Enter the number of the domain"
|
Write-Host "Select a domain to test:"
|
||||||
$selectedDomain = $DomainDetails[$selectedDomainKey]
|
$DomainDetails.GetEnumerator() | ForEach-Object { Write-Host "$($_.Key): $($_.Value.Name)" }
|
||||||
|
$selection = Read-Host "Enter the number of the domain"
|
||||||
|
$selectedDomain = $DomainDetails[$selection]
|
||||||
|
|
||||||
if ($null -eq $selectedDomain) {
|
if (-not $selectedDomain) {
|
||||||
Write-Error "Invalid selection. Exiting."
|
Write-Error "Invalid selection."
|
||||||
return $null
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prompt for DA password
|
# Prompt for DA password
|
||||||
@@ -139,69 +119,22 @@ function Test-WeakADPasswords {
|
|||||||
$DApassword = Read-Host "Enter password for DA account ($DAUsername) of $($selectedDomain.Name)" -AsSecureString
|
$DApassword = Read-Host "Enter password for DA account ($DAUsername) of $($selectedDomain.Name)" -AsSecureString
|
||||||
|
|
||||||
# Preparing credentials for the domain
|
# Preparing credentials for the domain
|
||||||
$credentials = New-Object System.Management.Automation.PSCredential($selectedDomain.DA, $DApassword)
|
$credentials = New-Object System.Management.Automation.PSCredential ($selectedDomain["DA"], $DApassword)
|
||||||
|
|
||||||
Write-Host "Enumerating accounts from the domain controller $($selectedDomain.DC)..."
|
# Performing the test
|
||||||
$accounts = Get-ADReplAccount -All -Server $selectedDomain.DC -Credential $credentials
|
Write-Host "Testing password quality for $($selectedDomain.Name)..."
|
||||||
|
$testResults = Get-ADReplAccount -All -Server $selectedDomain["DC"] -Credential $credentials |
|
||||||
|
Test-PasswordQuality -WeakPasswordHashesFile $FilePath -Verbose
|
||||||
|
|
||||||
Write-Host "Testing password quality..."
|
# Report generation with dynamic content
|
||||||
$testResults = $accounts | Test-PasswordQuality -WeakPasswordHashesFile $WeakHashesSortedFilePath
|
$reportPath = Join-Path -Path $reportPathBase -ChildPath "$($selectedDomain.Name)_WeakPasswordReport_$timestamp.txt"
|
||||||
|
$reportContent = @($header, ($testResults | Out-String).Trim(), $footer) -join "`r`n"
|
||||||
# Debug: Print selected domain details
|
$reportContent | Out-File -FilePath $reportPath
|
||||||
Write-Host "Selected domain details: Name=$($selectedDomain.Name), DC=$($selectedDomain.DC), DA=$($selectedDomain.DA)"
|
Write-Host "Report saved to $reportPath"
|
||||||
|
|
||||||
# Generate report name and path
|
|
||||||
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
|
|
||||||
$reportName = $selectedDomain.Name + "_WeakPasswordReport_" + $timestamp + ".txt"
|
|
||||||
$reportPath = Join-Path -Path $reportPathBase -ChildPath $reportName
|
|
||||||
|
|
||||||
Write-Host "Report will be saved as: $reportName"
|
|
||||||
|
|
||||||
# Return a hashtable with report path and weak accounts
|
|
||||||
return @{
|
|
||||||
"ReportPath" = $reportPath;
|
|
||||||
"WeakAccounts" = $testResults.WeakPasswords;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to export weak password report
|
# Main script logic
|
||||||
function Export-WeakPasswordReport {
|
$domainDetails = Get-DomainDetailsFromSettings -Settings $ElysiumSettings
|
||||||
param (
|
Test-WeakADPasswords -DomainDetails $domainDetails -FilePath $WeakHashesSortedFilePath
|
||||||
[array]$WeakAccounts,
|
|
||||||
[string]$ReportPath
|
|
||||||
)
|
|
||||||
|
|
||||||
Write-Host "Exporting weak password report to $ReportPath"
|
|
||||||
|
|
||||||
# Handle empty weak accounts array
|
|
||||||
if ($null -eq $WeakAccounts -or $WeakAccounts.Count -eq 0) {
|
|
||||||
"No weak passwords found." | Out-File $ReportPath
|
|
||||||
} else {
|
|
||||||
$WeakAccounts | Out-File $ReportPath
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Weak password report generated at $ReportPath"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main script execution
|
|
||||||
try {
|
|
||||||
$domainDetails = Get-DomainDetailsFromSettings -ElysiumSettings $ElysiumSettings
|
|
||||||
$results = Test-WeakADPasswords -DomainDetails $domainDetails -WeakHashesSortedFilePath $WeakHashesSortedFilePath
|
|
||||||
|
|
||||||
# Check if results were returned before proceeding
|
|
||||||
if ($results) {
|
|
||||||
# Generate the report
|
|
||||||
Export-WeakPasswordReport -WeakAccounts $results.WeakAccounts -ReportPath $results.ReportPath
|
|
||||||
|
|
||||||
# Check if there are weak accounts
|
|
||||||
if ($results.WeakAccounts) {
|
|
||||||
Write-Host "Weak passwords found. Report generated at $($results.ReportPath)"
|
|
||||||
} else {
|
|
||||||
Write-Host "No weak passwords found. Empty report generated at $($results.ReportPath)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
Write-Error "An error occurred: $_"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Script execution completed."
|
Write-Host "Script execution completed."
|
||||||
|
Reference in New Issue
Block a user