There seems to be some errors in the handling of account lockout thresholds.
- First, the variable
$SmallestLockoutThreshold is defined as the minimum value of all account lockout threshold (from the domain policy and other fine-grained password policies), as follows :
|
[int]$SmallestLockoutThreshold = $AccountLockoutThresholds | sort | Select -First 1 |
For each of these policies, a 0 value means that the lockout policy is disabled. However, if the lockout policy is disabled for a specific perimeter but not all accounts, the "minimum" value computed above is wrong (0), since it is hinted after that this value means no lockout policy for all accounts :
https://github.com/dafthack/DomainPasswordSpray/blob/94cb72506b9e2768196c8b6a4b7af63cebc47d88/DomainPasswordSpray.ps1#L385:L388
- As a consequence, some accounts are not tested password spraying on a domain where there is no lockout policy (on at least one perimeter). Indeed, the way the
$attemptsuntillockout variable is computed does not take the $SmallestLockoutThreshold=0 case into account :
|
$attemptsuntillockout = $SmallestLockoutThreshold - $userbadcount |
This value will never be greater than 0 (thus than 1), so the second part of the condition tested to add a specific user to the list of targets will never be True :
|
if (($timedifference -gt $observation_window) -or ($attemptsuntillockout -gt 1)) |
So, every account with a bad password attempt made in the last
$observation_window minutes is skipped.
To solve all these problems, I suggest you add some arbitrary high value in to the $AccountLockoutThresholds list instead of 0 when $objDeDomain.Properties.lockoutthreshold or $PSOLockoutThreshold is equal to 0.
Here :
|
$AccountLockoutThresholds += $objDeDomain.Properties.lockoutthreshold |
And here :
|
$AccountLockoutThresholds += $PSOLockoutThreshold |
There seems to be some errors in the handling of account lockout thresholds.
$SmallestLockoutThresholdis defined as the minimum value of all account lockout threshold (from the domain policy and other fine-grained password policies), as follows :DomainPasswordSpray/DomainPasswordSpray.ps1
Line 382 in 94cb725
For each of these policies, a 0 value means that the lockout policy is disabled. However, if the lockout policy is disabled for a specific perimeter but not all accounts, the "minimum" value computed above is wrong (0), since it is hinted after that this value means no lockout policy for all accounts :
https://github.com/dafthack/DomainPasswordSpray/blob/94cb72506b9e2768196c8b6a4b7af63cebc47d88/DomainPasswordSpray.ps1#L385:L388
$attemptsuntillockoutvariable is computed does not take the$SmallestLockoutThreshold=0case into account :DomainPasswordSpray/DomainPasswordSpray.ps1
Line 454 in 94cb725
This value will never be greater than 0 (thus than 1), so the second part of the condition tested to add a specific user to the list of targets will never be True :
DomainPasswordSpray/DomainPasswordSpray.ps1
Line 458 in 94cb725
So, every account with a bad password attempt made in the last
$observation_windowminutes is skipped.To solve all these problems, I suggest you add some arbitrary high value in to the
$AccountLockoutThresholdslist instead of0when$objDeDomain.Properties.lockoutthresholdor$PSOLockoutThresholdis equal to0.Here :
DomainPasswordSpray/DomainPasswordSpray.ps1
Line 344 in 94cb725
And here :
DomainPasswordSpray/DomainPasswordSpray.ps1
Line 370 in 94cb725