Username Enumeration

ENUMERATION

The first step in trying to discover authentication vulnerabilities is having a list of valid usernames. Even having a list of passwords would be useless without the right usernames to pair them with. After all, how can you impersonate someone if you don't know who they are?

Here are just a few ways to use enumeration to try to obtain some usernames for a system.

DUPLICATE USERNAME ERROR MESSAGES

Ever try to sign up for a service with a great username only to find that it's been taken?

While these error messages may seem harmless, the knowledge of which usernames exist and which ones do not in a particular environment can be helpful to a hacker.

If you're able to access a sign-up page for your target system, you could use any error messages of this type to help you make a list of usernames that are taken. The problem is that it would take a really long time to do this manually and just trying to guess usernames without having a list of potential names you want to test would not be very efficient.

This is where automation comes in handy.

USERNAME ENUMERATION WITH FFUF

Fuff is a pretty versatile tool since a lot of the power of fuzzing comes from the word lists used. For this reason, FFUF can be effective at enumerating usernames when using a wordlist designed for this purpose.

Check out this example of an FFUF command on a Linux terminal running the FFUF program to fuzz a login portal on a web app.

ffuf -w /usr/share/wordlists/SecLists/Usernames/Names/names.txt -X POST -d "username=FUZZ&email=x&password=x&cpassword=x" -H "Content-Type: application/x-www-form-urlencoded" -u http://MACHINE_IP/customers/signup -mr "username already exists"

Let's break down what this is showing.

The -w argument specifies the wordlist file's location on the local machine that will be used for this fuzzing attempt. In this case, the selected wordlist is called names.txt and is a wordlist of common usernames used for fuzzing.

The -X argument sets the request method. HTTP and HTTPS use methods to specify what kind of request is being made to the server. You can read more about HTTP request methods here. In this instance, POST is being used which is a request method. According to Wikipedia: "the POST request method requests that a web server accept the data enclosed in the body of the request message, most likely for storing it. It is often used when uploading a file or when submitting a completed web form."

The -d argument sets the data that will be sent. In this case, we want to fuzz the username, so instead of specifying a username to send as a request to fill out this field, we put username=FUZZ. This tells ffuf to insert a word from our previously referenced wordlist file as an attempt to see if that username exists.

Since we only care about finding existing usernames, we can fill the rest of the data in the form with whatever we want. With this comment, the email and password values will be filled with the value "x" simply for the purpose of not triggering an error message that could appear if a required field isn't filled out before submitting.

The -H argument adds additional headers to the request sent to the server. With Content-Type we are telling the server what kind of media is being sent. Here, we are telling the server that we are sending form data with application/x-www-form-urlencoded which is one of two ways to specify form data entry as a content type. To learn more about headers, check out this article.

-u specifies the URL where we are sending the request and the -mr argument sets the text on the result we are looking for to validate that we've found a valid username. Since we know in this case that attempting to enter a previously used username gives us a message of "username already exists," we can simply set that as our -mr value so that anytime this message pops up, the program can record the word the fuzzer used to trigger it as a valid username.