UMassCTF 2024
Web/Future Router
Challenge Overview
Description : Mr. Krabs just got a brand new router in the mail for him to use in the Krusty Krab. There was no mailing address so he’s tasked you with figuring out where the router is from and finding a flag!
We were given access to a website at this link.
So here is an image how the website looks like

The site features three main routes:
- Dashboard –>
/dash - cURL –>
/cURL - FuTuR3 r0UT3R Customer Service –>
/customerservice



Vulnerability Identification
So let’s analyse every route.
dash–> Upon exploring the Dashboard route, we discovered information about three devices, each with ahostnameandportspecified.Hostname:patricks-rock,
Port - Service,
http:80Hostname:spongebobs-spatula,
Port - Service,
http:80Hostname:squidwards-clarinet,
Port - Service,
http:80
Attempts to access these devices via our browser were unsuccessful. However, we speculated that one of these devices might contain the email address mentioned in the challenge description. For now, we set this aside for further investigation.
cURL–> The cURL route presented a simple tool for fetching URLs and displaying their responses.
For example if we pass www.google.com as input displays the response from the specified URL.

We quickly realized that we could leverage this tool to read local files by utilizing the file:// protocol. This allowed us to access sensitive system files such as /etc/passwd, indicating a potential security vulnerability.

At this moment I thought we have to find a flag.txt on the machine by hit and trial in every directory possible.
But then I tried accessing /proc/self/cmdline as my second approach and we can see it is a python gunicorn gateway application.
1 | # cmdline |
Hence I tried reading the app.py in the current working directory using file:///proc/self/cwd/app.py
1 | # app.py |
The source code is hidden somehow and we have to find the way to read it as mentioned in the comments of the app.py
When I tried to access /proc/self/environ it gave me the name of directory –> /planktonsrouter1ba8b69e
1 | # environ |
As it is using blueprints we can read the source code through file:///planktonsrouter1ba8b69e/blueprints/routes.py
1 | # routes.py |
We noticed a Python file mentioned in the comment ../karen/customerservice.py. However, while we were solving, we found the file name using an alternative approach.
Exploring the /proc directory, we experimented with different process IDs (PIDs).
In /proc/1/cmdline we can see a bash script being run entrypoint.sh
1 | # entrypoint.sh |
1 | import asyncio, os, re |
For now, let’s set aside this file and explore another functionality: /customerservice.
This route hosts a websocket application. Despite attempting various inputs such as hi or hello, we encountered no success. This outcome was unsurprising upon reviewing the source code.

After analyzing the source code, we observed that the input is initially decoded using the xor_decrypt function before being passed into the handle_input() function.
If the message contains hello after decryption, the application responds with the welcome message.
Let’s proceed with a test.
So here is our script
1 | import asyncio |
And bingo we get the welcome message in response

Upon further analysis of the code, we discovered a command injection vulnerability triggered when sending krabby patty in the message. Although the code includes some filters, they can be bypassed using $(test_cmd). To view the response, we redirected the output of the command injection to a file and then accessed it using the cURL functionality.
Let’s proceed with the command krabby patty $(ls > /tmp/output.txt). The response from the websocket server matched our expectations:
1 | Response from server: Thank you for your input, we will process your request in 1-3 business days |
Subsequently, reading the file from cURL using file:///tmp/output.txt yielded the desired response.

Let’s list the files of / using krabby patty $(ls / > /tmp/output.txt) as input
We can see the name of the flag file as flag53958e73c5ba4a66.
We also attempted alternative approaches, such as accessing the hostname provided on the dashboard using the cURL route. However, the static source code did not provide any useful information in this regard.
input = http://hostname:80/
One example

Obtaining the Flag
Now just read the file using krabby patty $(cat /flag53958e73c5ba4a66 > /tmp/output.txt)
Flag: UMASS{W3lC0m3_t0_Th3_FuTur3_Kr4bS_c28e1089b2}
Thank You