<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: detecting-password-spray-attacks
description: >-
  Detect password spray attacks through authentication log analysis identifying
  single-password-many-users patterns, low-and-slow timing evasion, lockout
  threshold manipulation, and spray tool fingerprinting.
domain: cybersecurity
subdomain: identity-access-management
tags:
  - password-spray
  - brute-force
  - authentication
  - detection-engineering
  - siem
  - sigma
  - active-directory
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1110.003"]
---

# Detecting Password Spray Attacks

## Overview

Password spraying tests a single password against many accounts to avoid lockout
thresholds, unlike brute-force which tests many passwords against one account.
Attackers use common passwords (Season+Year, Company+123) with timing intervals
matching lockout reset windows. Detection requires analyzing authentication failures
across accounts within time windows rather than per-account thresholds.

Mode: `[MODE: BLUE]` for detection engineering; `[MODE: RED]` for spray simulation.

MITRE ATT&CK: T1110.003 (Brute Force: Password Spraying)

## Prerequisites

- SIEM with authentication event ingestion (Event IDs 4625, 4771, 4776)
- Azure AD sign-in logs for cloud environments
- Python 3.10+ with `pandas`
- Network logs for external spray detection
- Account lockout policy documentation

## Key Concepts

### Spray Pattern Analysis

| Pattern | Description | Evasion Level |
|---------|-------------|---------------|
| Basic spray | One password, all users, fast | Low |
| Jitter spray | Random delays between attempts | Medium |
| Lockout-aware | Wait for reset window between passwords | High |
| IP rotation | Distribute across source IPs | High |
| Targeted spray | Only spray discovered valid usernames | Medium |
| Seasonal | Company-specific passwords (Summer2026!) | N/A |

### Sigma Detection Rules

```yaml
title: Password Spray — Single Password Multiple Users
id: a1b2c3d4-7890-1234-abcd-567890123456
status: experimental
description: Detects authentication failures across multiple users indicating password spray
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID:
      - 4625
      - 4771
  timeframe: 30m
  condition: selection | count(TargetUserName) by LogonType > 15
falsepositives:
  - Misconfigured service trying cached credentials
  - Vulnerability scanner with credential testing
level: high
tags:
  - attack.t1110.003
  - attack.credential_access
```

```yaml
title: Password Spray — Low and Slow
id: b2c3d4e5-8901-2345-bcde-678901234567
status: experimental
description: Detects low-velocity spray targeting many accounts over extended period
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4625
    SubStatus: '0xC000006A'
  timeframe: 24h
  condition: selection | count(TargetUserName) by IpAddress > 50
falsepositives:
  - Penetration testing (verify scope)
level: medium
tags:
  - attack.t1110.003
  - attack.credential_access
```

### Splunk Detection

```spl
# Password spray — many users, few passwords per user
index=wineventlog EventCode=4625 SubStatus=0xC000006A
| bin _time span=30m
| stats dc(TargetUserName) as unique_users count by src_ip _time
| where unique_users > 15 AND count/unique_users < 3
| sort -unique_users

# Spray with success detection (compromised account)
index=wineventlog (EventCode=4625 OR EventCode=4624)
| sort _time
| streamstats count(eval(EventCode=4625)) as spray_failures by src_ip
| where EventCode=4624 AND spray_failures > 10
| table _time TargetUserName src_ip spray_failures
```

## Workflow

### Step 1: Collect Authentication Logs

```bash
# Windows Event Logs
wevtutil qe Security /q:"*[System[(EventID=4625 or EventID=4624 or EventID=4771)]]" /c:10000 /f:json > /tmp/auth_events.json

# Azure AD
az monitor activity-log list --resource-type Microsoft.AAD --output json > /tmp/azure_auth.json
```

### Step 2: Analyze Spray Patterns

```bash
node scripts/agent.js --input /tmp/auth_events.json --output /tmp/spray_findings.json
node scripts/agent.js --input /tmp/auth_events.json --window 1800 --threshold 15
```

### Step 3: Identify Compromised Accounts

```bash
# Find successful logins from spray source IPs
node scripts/agent.js --input /tmp/auth_events.json --find-compromised
```

### Step 4: Respond

```powershell
# Force password reset for compromised accounts
Set-ADAccountPassword -Identity compromised_user -Reset
# Revoke active sessions
Revoke-AzureADUserAllRefreshToken -ObjectId USER_OBJECT_ID
```

## Verification

- [ ] SIEM detects spray patterns across 15+ users in 30-minute window
- [ ] Low-and-slow detection covers 24-hour analysis window
- [ ] Smart lockout configured (Azure AD) or granular lockout policy (AD)
- [ ] Common/breached passwords blocked via password filter
- [ ] Alerting includes source IP enrichment (geo, reputation)
- [ ] Compromised account auto-response triggers password reset
- [ ] Spray simulation tested quarterly to validate detection

## References

- [MITRE ATT&CK T1110.003](https://attack.mitre.org/techniques/T1110/003/)
- [Microsoft — Smart Lockout](https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-smart-lockout)
- [NIST SP 800-63B — Digital Identity Guidelines](https://pages.nist.gov/800-63-3/sp800-63b.html)
- [Spray Tool Detection Signatures](https://github.com/dafthack/MSOLSpray)
