diff --git a/CHANGELOG.md b/CHANGELOG.md index 398c21b..9502385 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Extract-NTHashes.ps1 +### version 1.1.1 +**Updated:** +- UPNs of the accounts with passwords found in dictionary were moved into separate report (one UPN at a line) to enable further automation. + ### version 1.1.0 **Added:** - UPN retrieval (this will prolong the time needed to run the script significantly) diff --git a/Test-WeakADPasswords.ps1 b/Test-WeakADPasswords.ps1 index f461f71..99b5129 100644 --- a/Test-WeakADPasswords.ps1 +++ b/Test-WeakADPasswords.ps1 @@ -8,7 +8,7 @@ ################################################## ## Project: Elysium ## ## File: Test-WeakADPasswords.ps1 ## -## Version: 1.1.0 ## +## Version: 1.1.1 ## ## Support: support@cqre.net ## ################################################## @@ -146,7 +146,10 @@ function Get-UserUPN { Write-Verbose "Attempting to get UPN for $SamAccountName in domain $Domain" try { - $user = Get-ADUser -Identity $SamAccountName -Properties UserPrincipalName -Server $Domain -Credential $Credential + # Remove domain prefix if exists + $simplifiedSamAccountName = $SamAccountName -replace '^.*\\', '' + + $user = Get-ADUser -Identity $simplifiedSamAccountName -Properties UserPrincipalName -Server $Domain -Credential $Credential Write-Verbose "UPN found: $($user.UserPrincipalName)" return $user.UserPrincipalName } catch { @@ -155,6 +158,20 @@ function Get-UserUPN { } } +# Inside the foreach loop where accounts are processed: + +foreach ($line in $lines) { + $newReportContent += $line + + # Regex to match the SAMAccountName from the report line + if ($line -match "^\s*(\S+)\s*$") { + $samAccountName = $matches[1] + Write-Verbose "Looking up UPN for $samAccountName" + $upn = Get-UserUPN -SamAccountName $samAccountName -Domain $selectedDomain.DC -Credential $credential + $newReportContent += " UPN: $upn" + } +} + # Function to test for weak AD passwords function Test-WeakADPasswords { param ( @@ -191,28 +208,54 @@ function Test-WeakADPasswords { # Report generation with dynamic content and UPNs $reportPath = Join-Path -Path $reportPathBase -ChildPath "$($selectedDomain.Name)_WeakPasswordReport_$timestamp.txt" + $upnOnlyReportPath = Join-Path -Path $reportPathBase -ChildPath "$($selectedDomain.Name)_DictionaryPasswordUPNs_$timestamp.txt" + Write-Verbose "Generating report at $reportPath" $reportContent = @($header, ($testResults | Out-String).Trim(), $footer) -join "`r`n" $lines = $reportContent -split "`r`n" $newReportContent = @() + $upnReportContent = @() + + $collectingUPNs = $false foreach ($line in $lines) { $newReportContent += $line - if ($line -match "$($selectedDomain.Name)\\(.+)") { + # Start collecting UPNs after detecting the relevant section in the report + if ($line -match "Passwords of these accounts have been found in the dictionary:") { + $collectingUPNs = $true + continue + } + + # Stop collecting UPNs if a new section starts or end of section is detected + if ($collectingUPNs -and $line -match "^\s*$") { + $collectingUPNs = $false + } + + # Regex to match the SAMAccountName from the report line and collect UPNs if in the target section + if ($collectingUPNs -and $line -match "^\s*(\S+)\s*$") { $samAccountName = $matches[1] Write-Verbose "Looking up UPN for $samAccountName" $upn = Get-UserUPN -SamAccountName $samAccountName -Domain $selectedDomain.DC -Credential $credential $newReportContent += " UPN: $upn" + + # Collect UPNs only for accounts found in the dictionary section + if ($upn -ne "UPN not found") { + $upnReportContent += $upn + } } } $updatedReportContent = $newReportContent -join "`r`n" + $upnOnlyContent = $upnReportContent -join "`r`n" try { $updatedReportContent | Out-File -FilePath $reportPath -ErrorAction Stop Write-Host "Report saved to $reportPath" + + $upnOnlyContent | Out-File -FilePath $upnOnlyReportPath -ErrorAction Stop + Write-Host "UPN-only report saved to $upnOnlyReportPath" } catch { Write-Error ("Failed to save report: {0}" -f $_.Exception.Message) }