0

I was wondering what could of allowed a user to hack my site, they changed my username, personal info and password. Can someone give me some suggestions on what it could have been. I'm using PHP MySQL and HTMLPURIFIER.

Here is the login script.

<?php
if (isset($_POST['submitted'])) { // start of submit conditional.
    require_once (MYSQL);

    // Validate the username or email address:
    if (!empty($_POST['login']) && strlen($_POST['login']) <= 255) {
        $e = mysqli_real_escape_string($dbc, $purifier->purify(strip_tags($_POST['login'])));
    } else if(!empty($_POST['login']) && strlen($_POST['login']) >= 256) {
        $e = FALSE;
        echo '<p>Your username or email address cannot exceed 255 characters!</p>';
    } else {    
        $e = FALSE;
        echo '<p>You forgot to enter your username or email address!</p>';
    }

    // Validate the password:
    if (!empty($_POST['pass']) && strlen($_POST['pass']) <= 255) {
        $p = mysqli_real_escape_string($dbc, $_POST['pass']);
    } else if(!empty($_POST['pass']) && strlen($_POST['pass']) >= 256) {
        $p = FALSE;
        echo '<p>Your password cannot exceed 255 characters!</p>';
    } else {
        $p = FALSE;
        echo '<p>You forgot to enter your password!</p>';
    }

    if(($e != FALSE) && ($p != FALSE)) { // check pass
        $pass_salt = "SELECT users.password, users.salt FROM users JOIN contact_info ON contact_info.user_id = users.user_id WHERE (contact_info.email = '" . $e . "' OR users.username = '" . $e . "') AND users.active IS NULL";
        $ph = mysqli_query($dbc, $pass_salt) or trigger_error("Query: $pass_salt\n<br />MySQL Error: " . mysqli_error($dbc));

        while($row = mysqli_fetch_array($ph)){ 
            $password = $row['password'];
            $salt = $row['salt'];
        }

        if(!empty($salt)) {
            $sha512 = hash('sha512', $p . $salt);
        }

        if(!empty($password) == !empty($sha512)){
            $user_pass = TRUE;
        } else {
            $user_pass = FALSE;
        }
    }


    if(isset($user_pass) && ($user_pass == TRUE) && !empty($salt)) { // If everything's OK.
        // Query the database:
        $q = "SELECT users.user_id, users.first_name, users.user_level FROM users JOIN contact_info ON contact_info.user_id = users.user_id WHERE (contact_info.email = '" . $e . "' OR users.username = '" . $e . "') AND users.password = '" . $sha512 . "' AND users.active IS NULL";        
        $r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));


        if (@mysqli_num_rows($r) == 1) { // A match was made.

            // Register the values & redirect:
            $_SESSION = mysqli_fetch_array ($r, MYSQLI_ASSOC); 
            // check if user is logged in then update the old login date
            $u = "UPDATE users JOIN contact_info ON contact_info.user_id = users.user_id SET users.last_login = NOW(), users.deletion = 0, users.deletion_date = NULL WHERE (contact_info.email = '" . $e . "' OR users.username = '" . $e . "') AND users.password = '" . $sha512 . "' AND users.active IS NULL"; 
            // save the info to the database
            $r = mysqli_query ($dbc, $u);
            mysqli_free_result($r);
            mysqli_close($dbc);

            $url = BASE_URL . 'home/index.php'; // Define the URL:
            header("Location: $url");
            exit(); // Quit the script.

        } else { // No match was made.
            echo '<p>Either your username, email address or password entered do not match those on file or you have not yet activated your account.</p>';
        }

    } else { // If everything wasn't OK.
        echo '<p>Please try again.</p>';
    }

    mysqli_close($dbc);

} // end of submit conditional.
?>
asaf
  • 9
  • 2
  • Could you provide an example of your code? – Shoe Apr 07 '11 at 16:30
  • Which code would you like the login script? – asaf Apr 07 '11 at 16:33
  • @asaf, that a look at my answer. It argue about the using of SQL Injections and XSS which are the main vulnerabilities, in my honest opinion, you are having. Also it seems you are using PHP5, so PDO suggestion is really a good choice for you. – Shoe Apr 07 '11 at 16:39
  • "Please do a security audit for me." - Um, no thanks. – abelenky Apr 07 '11 at 18:06
  • possible duplicate of [Website Just Got Hacked Question?](http://stackoverflow.com/questions/5588323/website-just-got-hacked-question) – mario Apr 07 '11 at 22:48
  • @abelenky, Lame comment really. – Shoe Apr 08 '11 at 13:53

6 Answers6

2

You should be aware of SQL Injection. That is what came up to my mind first (noticing the use of MySql). To prevent this you have to sanitize users input by using mysql_real_escape_string() (different mysql_escape_string() which is considered as deprecated). Despite this solution I'd suggest you to use either PDO or Mysqli (I usually discourage this one) in order to just fix the SQL Injection problem by the usage of Prepared Statements.

Then you should be probably aware of XSS (cross-site-scripting) that could have "injected" in your code some sort of malicious Javascript script. You can fix this a little with htmlspecialchars() that make HTML tags (such as <script>) not considered as HTML tags.

Also take a look at this Vulnerability list for PHP.

P.S.

In order to make your code more readable and "right" I'd suggest you to change strlen($_POST['login']) >= 256 into strlen($_POST['login']) > 255 which is the same but makes the reader understand immediately that the real limit is not 256 but 255.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • HTMLpurifier should of took care of the XSS problem? – asaf Apr 07 '11 at 16:40
  • I don't know it, but i think so. I'd bet they used an SQL Injection thought, only really solvable by using PDO instead of Mysqli (or mysqli functions for prepared statements i personally don't like). – Shoe Apr 07 '11 at 16:42
  • @asaf, Did this answer solved your problem? – Shoe Apr 07 '11 at 16:48
  • I think `mysql_real_escape_string()` should prevent almost any kind of MySQL injections. Are there any cases that can be used to inject SQL on `mysql_real_escape_string()` but not on PDO? For the record, I recommend using PDO as well, because it makes writing secure queries a lot easier and tidier. – Kaivosukeltaja Apr 07 '11 at 16:59
  • Quoting here: "In other words, they can trick your program into running multiple, arbitrary SQL statements instead of just the one you wanted. Escaping quotes should prevent this. But using a prepared statement is more thorough." (http://stackoverflow.com/questions/1742066/why-is-pdo-better-for-escaping-mysql-queries-querystrings-than-mysql-real-escape) – Shoe Apr 07 '11 at 17:05
  • That's all true, but if all input fields are being escaped before using them in a query, I don't think that's how they got in in this case. – Kaivosukeltaja Apr 07 '11 at 17:17
  • @Kaivosukeltaja, Are you providing some more explanation? (Notice that this answer was posted before the actually copy and paste of his code) – Shoe Apr 07 '11 at 17:31
  • @Charliepiga, I'm not saying your answer is bogus. I'm only commenting on your claim that SQL injection can only be prevented with prepared statements, because I think properly building the query and escaping the values can be just as secure as using prepared statements. – Kaivosukeltaja Apr 07 '11 at 17:59
  • @Kaivosu, Just a misunderstanding by my side then. – Shoe Apr 08 '11 at 13:51
0

First, make sure they can't perform an SQL injection. This is probably what they did. This is normally caused from input fields that are executed. The person doing it just has to type in an SQL command.

You can see details on this here.

Oh, welcome to StackOverflow.com! I hope you enjoy the site!

Freesnöw
  • 30,619
  • 30
  • 89
  • 138
0

In addition to the DalexL answer, please check that you have a strong password to connect to your database.

Jonathan
  • 11,809
  • 5
  • 57
  • 91
  • A weak password can quite likely be the unlocked door that let the hacker in. A brute force attack can crack a short and/or dictionary based password in minutes. – Kaivosukeltaja Apr 07 '11 at 17:06
0

I'm pretty sure this didn't happen to the original poster, but deceptive companies have been known to send "bills" to companies with web sites. The fine print in the "bills" transferred the domain from the company to the deceptive company.

Here's one example: Domain Registry of America scam

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
0

If you allow users to upload images, you may have been a victim of a GIF exploit. If your server settings aren't secure, viewing a GIF with embedded PHP code in it will execute the code. Check if you can find any .gif.php (or .php.gif) files on your system, they may still be there if the hacker forgot to clean up after himself.

Kaivosukeltaja
  • 15,541
  • 4
  • 40
  • 70
0

If HTMLPURIFIER is implemented correctly for all db facing inputs then you should evaluate how you are transmitting your logins. Are you pre-hashing before submit on the client side.

I would assume that the reason is there is an input on a form that is unfiltered and it is letting some SQL injected code through.

PaulSCoder
  • 593
  • 5
  • 19