# Password Spraying Attack & Defense

## **Setting Up the Environment**

To apply this scenario in your home lab, you need the following:&#x20;

✅ **Windows Server (Domain Controller - DC)**

✅ **Windows Client (Domain-Joined Machine)**

✅ **Ubuntu Machine (Elasticsearch & Kibana)**

✅ Ubuntu Machine (TheHive)

​Before initiating the attack, we must install Winlogbeat on the Windows server to collect logs and send them to Elasticsearch.​

Please review this for the installation: <https://faresbltagy.gitbook.io/footprintinglabs/weinnovate-training/build-elk-lab/set-up-winlogbeat-and-filebeat-for-log-collection>

​Below is the `winlogbeat.yaml` configuration file:​

<figure><img src="/files/llOLHEEDu1W75sT0xIMn" alt=""><figcaption></figcaption></figure>

Password spraying is a type of brute-force attack where an attacker tries a single, common password against multiple user accounts before moving on to another password and repeating the process. This technique is used to avoid account lockout policies that trigger after a certain number of failed login attempts.

Before initiating a Password Spraying attack simulation, it is essential to enable auditing for both successful and failed login attempts.

<figure><img src="/files/tI5hLb0xpOlKCTOJpLps" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/7X0cN7pT8unEkcjhCSOg" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/xm33Kcu84HObSjoEiJy9" alt=""><figcaption></figcaption></figure>

To conduct this attack and analyze the resulting logs, we will install and utilize the **`DomainPasswordSpray.ps1`** tool.

```powershell
Invoke-WebRequest -Uri https://raw.githubusercontent.com/dafthack/DomainPasswordSpray/refs/heads/master/DomainPasswordSpray.ps1 -OutFile DomainPasswordSpray.ps1 
Import-Module .\DomainPasswordSpray.ps1
```

​After installing the tool, let's proceed to execute the attack against the domain **`Main.local`**.​

<pre class="language-powershell"><code class="lang-powershell"><strong>Invoke-DomainPasswordSpray -Password Admin123! -UserList .\users.txt -Domain Main.local  -Force
</strong></code></pre>

<figure><img src="/files/SWAwjvwt8wPEUBYFKHLO" alt=""><figcaption></figcaption></figure>

Before analyzing the logs in ELK, let's first review the events that occurred from PowerShell.

```powershell
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625} -MaxEvents 20
```

<figure><img src="/files/uFFHX7Hl2Avx58mPbGW2" alt=""><figcaption></figcaption></figure>

```powershell
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625} -MaxEvents 10 | ForEach-Object { "Target User: $($_.Properties[5].Value)" }
```

<figure><img src="/files/6GQ86fAAtcPd5pkhJaZV" alt=""><figcaption></figcaption></figure>

Now, let's access the ELK logs and filter for event code 4625.​

<figure><img src="/files/VRC5NR6KiXkzcqUEyA1y" alt=""><figcaption></figcaption></figure>

​Let's add additional columns, such as 'hostname' and 'username', to enhance our data set.​

<figure><img src="/files/kHYCXybgR4YWNuApkThK" alt=""><figcaption></figcaption></figure>

We need to establish a threshold rule that triggers an alert when the count of unique usernames surpasses a specified limit within a defined timeframe, with grouping based on the hostname field.

<figure><img src="/files/l9PyuXOh2nd5IUoZtavP" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/1WQuj5oVlg3cPHE35Z4T" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/APWOzBqJRUyqrEpqidLQ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/0sCgcPnnuxkzP3BZqA0O" alt=""><figcaption></figcaption></figure>

Next, we need to scroll down to proceed with creating the rule.

<figure><img src="/files/zgwT5M5SYkDSOCnP9ZBA" alt=""><figcaption></figcaption></figure>

This rule triggers an alert when five authentication failure events occur for different usernames on the same hostname in five minutes.

<figure><img src="/files/esonU3AjhOCFKXtSLzjE" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/EZ9oXN2FZspueEcDMpPo" alt=""><figcaption></figcaption></figure>

This rule means:

* At each execution (every 1 minute), the rule analyzes data collected over the last 5 minutes (the look-back time).
* For example, if the rule runs at 5:21 PM, it will check data from 5:16 PM to 5:21 PM. Then, at 5:22 PM, it will check data from 5:17 PM to 5:22 PM, and so forth.

For password spray detection, the rule interval should be set to match or be shorter than the look-back time for continuous monitoring, ensuring no attacks are missed. However, if system resources are limited, increasing the interval to 5-10 minutes with a look-back time of 10-30 minutes balances performance and detection timeliness. For practice, let's configure the rule to run every minute with a loopback time of five minutes.

<figure><img src="/files/w3JobWBsuD17v942Bkff" alt=""><figcaption></figcaption></figure>

Next, let's rerun the attack and check if an alert was triggered.

<figure><img src="/files/NWcE4ckrxBOBVo5poI6B" alt=""><figcaption></figcaption></figure>

Let's proceed with reviewing the alerts.

<figure><img src="/files/FmSgtUkA5GQInE0mU591" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/GoQWcfjCcPJbvISxzC20" alt=""><figcaption></figcaption></figure>

These rules are not the final production-ready versions. When deploying them in real-world environments, they need to be continuously tuned to minimize false positives as much as possible.

To automatically forward this alert to Tines, a Gold license is required. However, since we do not have one, we cannot utilize Tines' webhook URL for this purpose. Instead, we will send an HTTP request to retrieve alerts from the ELK stack and schedule this request to run every 10 minutes to check for new alerts.

Before proceeding, we need to create an API key with the necessary privileges to retrieve alerts.

<figure><img src="/files/Mde22DUBUae3JTuDlq3F" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/hIe4JJx54NZhjbDJiuNy" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/oVk2ftvkWmuSmYmsR44V" alt=""><figcaption></figcaption></figure>

```json
{
  "superuser": {
    "cluster": [
      "all"
    ],
    "indices": [
      {
        "names": [
          "*"
        ],
        "privileges": [
          "all"
        ],
        "allow_restricted_indices": true
      },
      {
        "names": [
          "*"
        ],
        "privileges": [
          "monitor",
          "read",
          "view_index_metadata",
          "read_cross_cluster"
        ],
        "allow_restricted_indices": true
      }
    ],
    "applications": [
      {
        "application": "kibana-.kibana",
        "privileges": [
          "feature_alerting.all",
          "all"
        ],
        "resources": [
          "*"
        ]
      }
    ],
    "run_as": [
      "*"
    ],
    "metadata": {},
    "transient_metadata": {
      "enabled": true
    },
    "remote_indices": [
      {
        "names": [
          "*"
        ],
        "privileges": [
          "all"
        ],
        "allow_restricted_indices": false,
        "clusters": [
          "*"
        ]
      },
      {
        "names": [
          "*"
        ],
        "privileges": [
          "monitor",
          "read",
          "view_index_metadata",
          "read_cross_cluster"
        ],
        "allow_restricted_indices": true,
        "clusters": [
          "*"
        ]
      }
    ],
    "remote_cluster": [
      {
        "privileges": [
          "monitor_enrich",
          "monitor_stats"
        ],
        "clusters": [
          "*"
        ]
      }
    ]
  }
}
```

<figure><img src="/files/LoLIQeKJE5ewq4lEccuO" alt=""><figcaption></figcaption></figure>

We can retrieve the alerts triggered in ELK by accessing the following URL:

`https://192.168.204.146:9200/.kibana_alerting_cases/_search?_source=alert&filter_path=hits.hits._source.alert`

First, we will send a GET request to this URL using the previously generated API key.

```bash
curl -k -X GET "https://192.168.204.146:9200/.kibana_alerting_cases/_search?_source=alert&filter_path=hits.hits._source.alert" 
-H "Authorization: ApiKey Vi1BWmFaVUJQUXNLZV9FNWFsVnk6eUtOUDhNZlpRNC0xNzBQbWpBSDRkUQ==" | jq
```

<figure><img src="/files/IzSpyPcXSNsD3MFghici" alt=""><figcaption></figcaption></figure>

Let's begin our workflow on Tines by sending an HTTP request to retrieve alerts from this endpoint. However, before proceeding, we need to use Ngrok to expose the ELK stack publicly, allowing Tines to send HTTP requests to it.

```bash
ngrok http https://your-ip:9200/
```

<figure><img src="/files/3bfb1kb1eSBd9a0CAB2j" alt=""><figcaption></figcaption></figure>

We are now able to retrieve the alerts. Let's proceed.

<figure><img src="/files/CDr0tdJkPfYS2ZiZL9Bz" alt=""><figcaption></figcaption></figure>

Now, let's run the HTTP request.

<figure><img src="/files/tYLA3kOepIA63dPrdLNh" alt=""><figcaption></figcaption></figure>

Let's schedule this request to run every 10 minutes to check for new alerts.

<figure><img src="/files/NzD6xymCstC4oNpdrSUi" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Qt83JOMC1a8ecMJVJQRm" alt=""><figcaption></figcaption></figure>

We have received the alerts and can forward them to any desired destination. Now, let's utilize this alert to send a notification to our Telegram bot and create a case in TheHive.

To set up a Telegram bot, please refer to the following guide: [Telegram Bot Setup](https://faresbltagy.gitbook.io/footprintinglabs/weinnovate-training/soar/send-alerts-to-email-and-telegram-bot).

<figure><img src="/files/yWlRESBGcLH3OhpWAtSl" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/0FO8lMyI1WA6oiitbYIC" alt=""><figcaption></figcaption></figure>

Let's rerun the workflow to verify if any output is received in our Telegram bot.

<figure><img src="/files/eKP6UsEMSQjINVUCQPUP" alt=""><figcaption></figcaption></figure>

We also want to create a case in TheHive using the alert information.

<figure><img src="/files/9UWW1vmokByCc9fMoNHR" alt=""><figcaption></figcaption></figure>

We need to use Ngrok here as well because TheHive is hosted on our local machine. This allows us to expose TheHive's URL publicly, enabling Tines to send HTTP requests for case creation.

The following elements must be added to ensure the case is successfully created in TheHive.

```json
{
  "title": "<<get_alerts.body.hits.hits[0]._source.alert.name>>",
  "description": "<<get_alerts.body.hits.hits[0]._source.alert.params.description>>",
  "severity": 2,
  "type": "<<get_alerts.body.hits.hits[0]._source.alert.params.ruleSource.type>>",
  "source": "ELK",
  "sourceRef": "<<get_alerts.body.hits.hits[0]._source.alert.params.ruleId>>",
  "date ": "<<get_alerts.body.hits.hits[0]._source.alert.createdAt>>"
}
```

<figure><img src="/files/O2UKb07QZe1l4JaLK0sn" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/yX2zElsxq6WNRqqBcm7b" alt=""><figcaption></figcaption></figure>

WWe also require the API key to create a case on TheHive. To obtain it, please visit the following URL: <https://faresbltagy.gitbook.io/footprintinglabs/build-home-lab-soc-automation/automate-everything-with-shuffle>.

Now, let's rerun the workflow to verify whether the case is created successfully.

<figure><img src="/files/aYiX01vwlVyXlrfyzyGZ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/jxOvNVibfJxvBTIkex8P" alt=""><figcaption></figcaption></figure>

You may include a summary and MITRE tags to enhance the case's informativeness.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://faresbltagy.gitbook.io/footprintinglabs/home-lab-attack-and-defense-scenarios/password-spraying-attack-and-defense.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
