How does an attacker get access to hashed passwords?

There are any number of ways:

  • SQL injection
  • Leaked backups
  • Disgruntled employees leaking them
  • Any kind of breach of the server that allows code execution.

As you can see there are many, many ways this could happened - as phihag mention in comments, more than half of the OWASP top 10 could lead to leaked hashes - so they can not be easily tabulated in a post.

This does not mean that it is inevitable that hackers gets the hashes, but you should still use a good hashing algorithm to protect yourself and your users just in case. Since a backup may be lost or your server hacked without you ever noticing, having properly hashed passwords should be the only thing that allows you to sleep at night. This strategy is known as "defence in depth", or just simply "plan for the worst".


There are many methods. Here are some I can think of off the top of my head. Now I might be a little wrong with the syntax as I haven't bothered to test it out right now, but in general, these are things you'd do in order to get that data.

Note that, with the below exploits, I am not necessarily providing examples which steal hashes (with the exception of SQLi), but examples of how the exploits can work. The attacker would use exploits below to further compromise a system.

  1. SQL injection

    Example:
    a OR 1=1'; exec sp_msforeachtable "SELECT * FROM ?";--

    You could also use sp_msforeachdb, like so:

    a'; exec sp_msforeachdb 'USE ?;exec sp_msforeachTable "SELECT * FROM !","!"';--

    The -- is there to comment out parts of the SQL statement that may interfere with your injection. These are just very basic examples. It really depends on the format of the query.

  2. OS Injection. ; cat /etc/passwd; rm -rf /*
  3. LDAP Injection. *, (cn = *)(|(password =*))
  4. Insecure Direct Object Reference leading to Local / Remote File Inclusion vulnerability.

    /etc/passwd%00 (note: passwords, of course, aren't stored here; finding valid usernames when people reuse passwords is the key here, or using the usernames to aid in escalation of privileges)

    %00 is a "null terminator" used to avoid anything coming after it, so you don't try to include something that doesn't exist, e.g.: /etc/passwd.txt. This could also be \000, \x00, \z, \u0000, \0, or \00 depending on the language you're using.

  5. Hacking a developer / user with access to the databases.
  6. Exploiting the database server, or web server through some other means.

One addition to Mark Buffalo:
7. Man-in-the-Middle attack. Watching unencrypted traffic can often reveal a password hash. In a pass-the-hash scenario, systems will trust the hash and the password and let an attacker simply copy the hash without cracking it.