Skip to content

MySQL Credential Brute-Force

4 min read Created Mar 26, 2026 Last updated Jul 10, 2026

MySQL credential brute-force is viable when the service is network-exposed and no lockout policy is enforced. MySQL has no built-in account lockout by default: failed authentication attempts do not block the account. This makes it straightforward to test large credential lists without triggering a lockout. Prioritize credentials recovered from other services on the same host or network before falling back to generic wordlists.

Before running a full wordlist, check these first:

  • Try root with an empty password and root:root manually
  • Test credentials recovered from config files or other services during enumeration
  • Check enumeration results for the MySQL version and deployment stack context

Repurposing already-found credentials is faster and quieter than a full brute-force run.

Brute-Force with hydra

Test a single username against a password list. Hydra reports each confirmed hit with the host, login, and password fields. On a hit, stop the attack immediately and move to credential verification before continuing further enumeration.

┌──(kali㉿kali)-[~]
└─$ hydra -l root -P /usr/share/wordlists/rockyou.txt mysql://$TARGET_IP:${PORT:-3306}
[3306][mysql] host: 192.168.1.100   login: root   password: password123

Test multiple usernames at once with a username list. This is useful when enumeration has not confirmed a specific account name. Hydra will try every password against every username in sequence. The output format is the same: look for the login and password fields when a pair succeeds.

┌──(kali㉿kali)-[~]
└─$ hydra -L /usr/share/seclists/Usernames/top-usernames-shortlist.txt -P /usr/share/wordlists/rockyou.txt mysql://$TARGET_IP:${PORT:-3306} -t 4

Keep thread count low with -t 4. MySQL handles concurrent connections well but aggressive threading increases detection risk and can cause connection errors on resource-constrained targets. If the target has a low max_connections value, hydra will start producing connection refused errors mid-run. Drop to -t 2 or add a delay with -W 1 if errors appear. Consistent connection timeouts rather than auth failures usually mean a firewall is rate-limiting or silently dropping packets from your source IP.

Target Common MySQL Usernames

MySQL deployments commonly use predictable account names beyond root. Build a targeted username list before reaching for a full wordlist. Application accounts like wordpress, drupal, and joomla are created automatically by CMS installers and often retain weak or default credentials long after installation. Accounts like replication and monitor are frequently configured with simple passwords by administrators who treat them as low-value service accounts. The backup and dbadmin accounts are common on shared hosting environments and legacy applications. Start with this focused list: it takes seconds to test and hits more often than you expect.

mysql-users.txt:

root
mysql
admin
app
webapp
wordpress
drupal
joomla
backup
replication
monitor
readonly
dbadmin
sa

Verify and Check Privileges After a Hit

Once valid credentials are found, connect and immediately check the privilege level. The query below returns the current user context, all grants on that account, and the secure_file_priv variable. These three outputs together tell you what the account can do on the filesystem and what databases it can reach.

┌──(kali㉿kali)-[~]
└─$ mysql -h $TARGET_IP -P ${PORT:-3306} -u $USER -p$PASSWORD -e "SELECT USER(); SHOW GRANTS FOR CURRENT_USER(); SHOW VARIABLES LIKE 'secure_file_priv';"

FILE privilege in the grants combined with an empty secure_file_priv is the highest-value result: it enables file read and webshell deployment covered in the next exploitation pages. If secure_file_priv is set to a specific directory path, FILE operations are restricted to that path only. GRANT ALL PRIVILEGES or WITH GRANT OPTION indicates a DBA-level account: you can create new accounts, read all databases, and use SELECT INTO OUTFILE to write files to permitted paths. A read-only account with SELECT on a single database still has value. Dump credential tables, application configuration data, and any columns that store API keys, tokens, or password hashes. Session tokens stored in the database are also worth extracting if the application uses database-backed sessions.

When brute-force produces no hits, consider the attack surface. Some deployments bind MySQL to localhost only and expose it externally through a bastion host. If you have code execution on the target already, attempt the brute-force from there instead. On Debian-based systems, check /etc/mysql/debian.cnf if you have a file read from another service. This file often contains a debian-sys-maint account with a cleartext password that has broad privileges and is rarely monitored.

References