WackoPicko/Reflected-SQL-Injection

From aldeid
Jump to: navigation, search
You are here:
Reflected SQL Injection

Description

WackoPicko contains a reflected SQL injection in the username field of the login form. By introducing a tick into the username field it is possible to perform arbitrary queries in the database and obtain, for example, the usernames and passwords of all the users in the system.

Proof of Concept

Initial request is vulnerable to SQL injections:

SELECT *
FROM users
WHERE login LIKE '%s'
AND password = SHA1( CONCAT('%s', `salt`))

By injecting a login that closes the quote and concatenates a dash (#), it comments what is on the right of the dash symbol. Then, it is possible to login without password if you know the login:

Wackopicko-sql-injection-login-without-password.png

The request becomes (everything in yellow is considered as comments):

SELECT * 
FROM users
WHERE login LIKE  'bob'#'
AND password = SHA1( CONCAT('oops', 'salt'))

By fuzzing some logins, it is possible to enumerate valid users.

How to detect?

How to protect against it?

Code

In the following extract of /include/users.php, the first request is vulnerable to SQL injection attacks since only the password is sanitized.

function check_login($username, $pass, $vuln = False)
{
  if ($vuln)
  {
      $query = sprintf("SELECT * from `users` where `login` like '%s'
            and `password` = SHA1( CONCAT('%s', `salt`)) limit 1;",
            $username,
            mysql_real_escape_string($pass));
  }
  else
  {
      $query = sprintf("SELECT * from `users` where `login` like '%s'
            and `password` = SHA1( CONCAT('%s', `salt`)) limit 1;",
            mysql_real_escape_string($username),
            mysql_real_escape_string($pass));
  }
  $res = mysql_query($query);
  if ($res)
  {
      return mysql_fetch_assoc($res);
  }
  else
  {
      if ($vuln)
      {
    die(mysql_error());
      }
      else
      {
    return False;
      }
  }
}

As we can see in the "/users/login.php" script, user inputs are passed to the function without any sanitization:

if ($user = Users::check_login($_POST['username'], $_POST['password'], True))

Comments

Talk:WackoPicko/Reflected-SQL-Injection