# Username enumeration via response timing

## Exploitation

### Username Enumeration

Intercepting a login request with invalid credentials, we are able to see that the server takes some time to get back to us. After a certain number of requests, the server returns `You have made too many incorrect login attempts. Please try again in 30 minute(s).` (as shown below) This indicates that the server has some soft of Web Application Firewall inplace to mitigate against brute force attacks.

![](/files/hmps8whq0LvXQFoB0rrX)

There are usually 4 possible HTTP headers that can aid in bypassing an IP filter.

* X-Forwarded-For
* X-Originating-IP
* X-Remote-IP
* X-Remote-Addr

Adding `X-Forwarded-For` and giving it a random value bypasses the WAF as shown below. We are able to get a response. However, we would have to keep iterating the value of this field to keep bypassing and conduct a brute force attack.

![](/files/Zvaowt6bYxetbeZQli6W)

{% hint style="info" %}
Additionally, I noticed that the server takes longer to respond to a request containing the right username and a **long** wrong password. However, the server instantly responds to a request containing the wrong username and a **long** wrong password.

This implies that the server checks the username then the password. We can abuse this and perform username enumeration by sending requests with long passwords accompanied by our username list. If the username is wrong, we would get a quick response. Else, we would get a slow response confirming our username. Pretty cool ngl!
{% endhint %}

Now that we have an understanding of what goes on in the background, we can now move on to enumerating the usernames. Send the request to Intruder, mark the `X-Forwarded-For` & `username` field, modify the password to be any long value and switch the attack type to `Pitch Fork` as shown below.

![](/files/hikOyiQibVKulg52gzWE)

Under the payloads tab, select payload set 1 and set the type to `number`. We will be using this payload type to randomize/iterate our `X-Forwarded-For` field. Under payload options, set the following.

```jsx
Type = Sequential
From = 10
To = 100
Base = Decimal
Max Fraction Digits = 0
```

![](/files/xUUpRH3oYJjI2ir9Qm9q)

Next select the 2nd payload set and paste the username list for brute force. Once done, hit start attack and wait for the attack to complete.

![](/files/DGOTsSPv84RfCPaK0dRY)

Meanwhile, enable the `Response received` and the `Response completed` column on the attack window for further analysis later on.

![](/files/QkwDwRSFFZMXM6gWeCSo)

Once sorted by Response Received, as suspected there is a request which yielded a slow response time from the server. The username appears to be `applications` as shown below.

```jsx
username = applications
```

![](/files/Jev78y8umWjGTcjUjy3g)

### Password Enumeration

Now that we have the username, we can remove the "long password" technique and rerun the brute force attack with just the `X-Forwarded-For` increment to bypass the WAF.

Decrease the password length and mark its field instead of the username field.

![](/files/Pvedq6pHYOBX1CrWdAe5)

Replace the list under payload set 2 with the password list and hit start attack.

![](/files/009IFGQgGyNclDSaH8hS)

Once the attack is completed, we are able to see one request with a status code `302` which signifies a redirect after a successful login 😉

![](/files/vs7WdDzQJ3N3ucS5d8Ji)

We are able to infer the password from this response. `password = monitor`

```jsx
Username = applications
Password = monitor
```

Logging in with these credentials solves the lab!

![](/files/XCREapLlSDE61Ja7H5IW)

![](/files/VGEZKa7AUE9bKQhLU6n4)

✅


---

# 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://repo.4pfsec.com/portswigger-labs/authentication/username-enumeration-via-response-timing.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.
