Schrodingers Scope⚓︎

Difficulty:
Direct link: Schrodingers Scope
Area: Retro shop
In-game avatar: Kevin
Hints⚓︎
Hint 1
Pay close attention to the instructions and be very wary of advice from the tongues of gnomes!
Perhaps not ignore everything, but be careful!
Hint 2
During any kind of penetration test, always be on the lookout for items which may be predictable from the available information, such as application endpoints.
Things like a sitemap can be helpful, even if it is old or incomplete. Other predictable values to look for are things like token and cookie values
Hint 3
As you test this with a tool like Burp Suite, resist temptations and stay true to the instructed path.
Hint 4
Watch out for tiny, pesky gnomes who may be violating your progess.
If you find one, figure out how they are getting into things and consider matching and replacing them out of your way.
Hint 5
Though it might be more interesting to start off trying clever techniques and exploits, always start with the simple stuff first, such as reviewing HTML source code and basic SQLi.
Objective⚓︎
Request
Kevin in the Retro Store ponders pentest paradoxes—can you solve Schrödinger's Scope?
%%{init: {"themeVariables": {
"fontSize": "20px",
"nodeTextSize": "18px",
"clusterTextSize": "22px"
}}}%%
flowchart TD
subgraph Discover["Discover and Stabilize"]
direction LR
A[gnomeU background violations]
B[Block gnomeU requests]
A --> B
end
subgraph Enumerate["Enumerate and Access"]
direction LR
C[Exposed sitemap]
D[Access hidden dev endpoints]
E[Hardcoded credentials]
F[Login as teststudent with X-Forwarded-For header]
C --> D --> E --> F
end
subgraph Exploit["Exploit and Report"]
direction LR
G[Hidden course in commented UI]
H[SQL injection to get unauth gnome course]
I[Predictable registration cookie]
G --> H --> I
end
Discover --> Enumerate --> Exploit
Solution⚓︎
Initial page.

Upon just browsing around, we accumulate violations because of background requests to URL /gnomeU.
We first need to take that out so we don't get interrupted repeatedly.
For example :

https://flask-schrodingers-scope-firestore.holidayhackchallenge.com/gnomeU?id=308c8a1b-2f54-4e12-9f1f-fae78d758c9e
https://flask-schrodingers-scope-firestore.holidayhackchallenge.com/gnomeU*
After the above blocking, all the requests to that URL would be blocked and we wont be bothered by Gnomes.

The hint about the sitemap
"Things like a sitemap can be helpful, even if it is old or incomplete."
Site map
Remember - in order to be in scope, we can only try paths under /register.
So, nothing prevents us to use the sitemap to see what other paths noted there and use them under /register.
For example, in the below example, we use /register/dev/dev_todos and that reveals the password for "teststudent".
and we get our first vulnerability reported.
and in addition, we have our credentials to login.
UserName : teststudent
Password : 2025h0L1d4y5
Forwarding IP could be related to the IP used in the X-Forwarded-For header.
Since this needed to be passed every time I would login, want to make sure the header is added for every request.

When we attempt again, we can see the XFF header with 127.0.0.1 added and we see the home page showing "Neighborhood College Courses".


In the home page we see a commented out unordered list with a link.
/register/courses/search
In my example,
https://flask-schrodingers-scope-firestore.holidayhackchallenge.com/register/courses/search?id=308c8a1b-2f54-4e12-9f1f-fae78d758c9e

We want to uncomment that unordered list in the response body when It returns from the server before It renders in the browser so, we see the courses list in browser.
We create a regex replace rule with the Response body in the burp suite.
\s*<!--\s*(<ul\s+id="courseSearch"[\s\S]*?<\/ul>)\s*-->
$1

With the above change, the courses list link appears.

One of the endpoint /register/courseSearchUnlocked was throwing error because It was getting called without the id. We intercept and add the id in this and get successful response.



Vulnerability found : Found commented-out course search.

Now we land on the below page.
https://flask-schrodingers-scope-firestore.holidayhackchallenge.com/register/courses/search?id=4a5b61e7-2a82-4908-94bd-4044b8653592
Searching the above with simple SQL injection payload
' OR 1=1 --

Shows the course list.

Vulnerability found : Identified SQL injection vulnerability

In the above course list there is an interesting one.

In the below screen the Gnome notes:
Gnome on course details page
Have some heart and 'Continue' about your way. If you really 'MUST' do something, just 'Remove' the course. We'll put up another once you're done and in the clear, ok?

Instead of removing, we report it.

Vulnerability reported and accepted

Vulnerability found : Reported the unauthorized gnome course
<br/
https://flask-schrodingers-scope-firestore.holidayhackchallenge.com/register/courses/wip/holiday_behavior

It may be referring to the value of the cookie named "registration"

Looking at the values of the registration cookie for other courses, registration cookie starts with eb72a05369dcb4 with only last of the 2 digits different.
So we set up intruder for /register/courses/wip/holiday_behavior

Payload

eb72a05369dcb44c shows 200 OK

We intercept the request with a repeater and and send eb72a05369dcb44c as the registration cookie value.


Answer
Solved in the game.
Response⚓︎
Kevin
...
Learnings⚓︎
- The biggest learning was very non-technical but MOST important - If you are on a pentest engagement, stick to the scope you are given.
- Old artifacts like sitemaps are still gold, even when partially outdated.
- HTML comments does not actually hide things from the user as they can always look at the HTML source.
- Trusting headers like X-Forwarded-For is effectively trusting the attacker.
- Predictable cookies turn authorization into a guessing game.
Prevention & Hardening Notes⚓︎
- Don't ship dev or debug endpoints, especially under production paths.
- Never rely on client-supplied headers (XFF) for access control decisions.
- Remove dead/commented code from production responses.
- Use server-side authorization checks, not UI visibility.
- Make cookies non-predictable and bind them to user/session state.
