0

A site I made recently got hacked and defaced. They got into a self-made CMS for administering the website. They were able to retrieve my username and the hashed version of the password and posted it on facebook.

Now my question is, how did they enter the site using the hashed password? Don't they need to decrypt it first? Why didn't they post the decrypted version of the password on their facebook account (when I see a lot of other sites posted there with their human readable passwords displayed).

This is my authentication code:

SELECT * FROM Admin WHERE Username = '$_POST[Username]' // This finds the username

if ($row[Password] == md5($_POST[Password])) {
    Save Sessions here
}

Although I've added mysql_real_escape_string now to the SQL query because this might have been the vulnerability.

Any thoughts?

Sam
  • 7,252
  • 16
  • 46
  • 65
Nitro Chummy
  • 43
  • 1
  • 8
  • 2
    Maybe this is better suited for http://security.stackexchange.com/ – Luchian Grigore Nov 29 '12 at 02:19
  • Don't use md5, use some version of sha. – imreal Nov 29 '12 at 02:19
  • And yes, the lack of escaping is a big problem. Better than `mysql_real_escape_string` are prepared statements and parameterized queries. [This is a good place to start on that topic](http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection). – Michael Petrotta Nov 29 '12 at 02:21
  • This is an aside, but to make it harder to crack your hashed password (no matter whether you're using SHA or MD5), you should also use a salt and do multiple passes. – stevevls Nov 29 '12 at 02:22
  • Alright. Thanks for the tips! I'll try these. – Nitro Chummy Nov 29 '12 at 07:49

3 Answers3

2
SELECT * FROM Admin WHERE Username = '$_POST[Username]'

If this ^ is really your actual select statement, that screams SQL injection. It couldn't be much easier than that. Although you don't seem too shocked that they got your hash, so I'll assume the root of your question is about how they entered your site using nothing but the hash.

There are a few options here:

  • Rainbow tables
  • Creating a new user for themself in the database (sql injection, remember)
  • Changing the hash (sql injection)
  • Simple offline brute force or dictionary attack
  • Malicious code re-writing (unlikely since you've been perusing the code after the fact)
  • Probably other possibilities involving XSS or session hijacking (do you sanitize your input data? do you secure your sessions?)

Take your pick. Once a hacker has such a nice foothold as SQL injection, many new attack vectors open up.

Also, I have to wonder -- what in god's green earth was this hacker thinking posting their misadventures to facebook? Is this a friend or something? If so, maybe you should just ask them how they did it. If not... do I really need to say this... you've got your guy / gal -- justice time.

Chris Eberle
  • 47,994
  • 12
  • 82
  • 119
  • +1 for Creating a new user for themself in the database (sql injection, remember) and Changing the hash (sql injection) – tomdemuyt Nov 29 '12 at 02:30
  • But, doesn't mysql_query() prevent SQL Injections? No, the hacker is a group that just targets sites and find vulnerabilities. They have a Facebook page. Now, how do I know who it is with just a facebook page? For the justice time part. – Nitro Chummy Nov 29 '12 at 03:49
  • @NitroChummy Yes... but that doesn't help if you've *already been hacked* – Chris Eberle Nov 29 '12 at 04:03
  • Yes on which account Chris? mysql_query() preventing SQL Injections or finding someone out through their fb page? – Nitro Chummy Nov 29 '12 at 06:07
  • Just because you have an SQL injection doesn’t mean an attacker has full control over your database. In this case, the SQL injection is located in a SELECT statement, which means an attacker can only select data. So no insertion (“Creating a new user for themself in the database”) or update (“Changing the hash”) of data. – Gumbo Mar 22 '13 at 08:46
  • @Gumbo you... uh... don't really get sql injection do you? Select is only the first command. I can use this input: `myuser'; DROP TABLE USERS; --` to execute a second command. Or a third. Or whatever I want. I could own your DB. – Chris Eberle Mar 22 '13 at 15:00
  • @Chris It seems that *you* don’t really know platform specific SQL injections: PHP’s MySQL APIs don’t allow multiple statements with functions like `mysql_query`, `mysqli_query`, etc. – Gumbo Mar 22 '13 at 16:22
  • @Gumbo I wasn't making the assumption that `mysql_query` was being used since it wasn't directly in the question, but upon re-reading it I believe you're correct. – Chris Eberle Mar 23 '13 at 21:02
1

This has nothing to do with you actual password. It’s the SQL injection vulnerability alone that is exploitable to gain access. I’ll show you how.

Assuming your Admin table has only two columns, all you need is a UNION that injects both the username and a password hash that fits the provided password:

$_POST['Username'] = "' UNION SELECT 'Admin','5ebe2294ecd0e0f08eab7690d2a6ee69"
$_POST['Password'] = "secret"

Here the provided username is crafted in a way that it perfectly fits the conditions of the context the injection happens. This would be the resulting query:

SELECT * FROM Admin WHERE Username = '' UNION SELECT 'Admin','5ebe2294ecd0e0f08eab7690d2a6ee69'

The resulting set would be a single record with the injected username Admin and the MD5 hash 5ebe2294ecd0e0f08eab7690d2a6ee69.

So make sure that you’re protected against SQL injections.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • DAMN!!!! A mysql_real_escape_string would prevent that now right? And how could they have retrieved my saved hashed password? – Nitro Chummy Nov 29 '12 at 06:06
  • @NitroChummy Yes, it would have prevented it. And as already said, they wouldn’t have needed your actual password as they can provide their own password hash that the given password is tested against. But if they got it, with SQL injection can do a lot, even reading data in a blind fashion as long as your script acts differently whether you’ve entered a valid or an invalid username. You should definitely check your logs to see if there are any anomalies. – Gumbo Nov 29 '12 at 06:23
0

The problem could be that you hashed the password with md5 which is prone to collisions and obsolete. If they have your hashed password, they can find a string that produces the same hash, even though it is not your actual password.

Use a stronger hashing algorithm like SHA and a salt to prevent rainbow attacks.

imreal
  • 10,178
  • 2
  • 32
  • 48