Good job to my team for obtaining 7th place! And also thanks to the challenge creators and organizers of course :)
๐ต Nicky Romero & MARF ft. Wulf - Okay๐ต
Web
Space Station
Where do you want to go?
http://20.198.209.142:55047
The flag is in the flag format: STC{โฆ}
Author: zeyu2001
If we visit the site, we just get a blank page with a one-line message.
|
|
Running a Burp Suite โDiscover contentโ scan, we find /app and /flag.txt.
/flag.txt gives 403 Forbidden, so letโs check out /app.
At the bottom of the page we can enter URLs into an input bar powered by something called โPHP-Proxyโ.
|
|
I went to the Github repository of this tool and found an open issue regarding a LFI vulnerability: https://github.com/Athlon1600/php-proxy-app/issues/161
Essentially, we just have to host our own page with the below contents and then submit it into the input bar.
|
|
To do this, we can spin up a publicly-accessible server real quick with php -S localhost:8000 and ngrok http 8000. ngrok creates a tunnel to localhost and after that we can submit the ngrok-generated public URL into PHP-Proxy:
|
|
After a few 302 Found redirects, we are greeted with the contents of /etc/passwd.
Now, we can retrieve the
flag.txt we couldnโt access previously by modifying our payload:
|
|
Submitting our URL again and following the redirects gives us the contents of flag.txt:
|
|
Flag: STC{l0cal_f1l3_1nclus10n_328d47c2ac5b2389ddc47e5500d30e04}
Specimens
Collected a bunch of specimens on our last run, wonder if there is more we misplaced.
http://20.198.209.142:55042
The flag is in the flag format: STC{โฆ}
Author: LegPains
Checking the site out and looking at its source code reveals an obvious possible LFI / Path Traversal vulnerability in /?specimen=.
|
|
Burp Suiteโs โactive scanโ feature marked this as a successful payload:
|
|
Confirmed retrieval of file contents:
After a bit of guesswork which I dislike, we find
flag.txt in /var/www/:
|
|
Response:
|
|
Flag: STC{StRINg_r3PLace_I5_n0T_ReCUR5ive}
Star Cereal
Have you heard of Star Cereal? Itโs a new brand of cereal thatโs been rapidly gaining popularity amongst astronauts - so much so that their devs had to scramble to piece together a website for their business! The stress must have really gotten to them though, because a junior >dev accidentally leaked part of the source codeโฆ
http://20.198.209.142:55043
The flag is in the flag format: STC{โฆ}
Author: zeyu2001
Hint: **Note: This is NOT required for solving but may have caused some of your payloads to fail. **
In line 11 of process_login.php:
$this->query = "SELECT email, password FROM admins WHERE email=? AND password=?";Should be
$this->query = "SELECT email, password FROM starcereal.admins WHERE email=? AND password=?";Additional hint: Think about what the code is checking. Your solution should work regardless of the contents of the database.
Attached: process_login.php
The login page of Star Cereal at /login.php requires an email address, password, and MFA token.
Looking at the source code provided in the attached file
process_login.php,
|
|
we can understand that the:
- email address, password, and MFA token are sent as POST parameters
- email address and password used to create a
Userobject Userobject and MFA token used to make aLoginobject.- Final
Loginobject is then serialized, base64-encoded, url-encoded, and then used as alogincookie.
To verify this login cookie, it is decoded and unserialized back into a Login object. verifyLogin() method of the Login object is then called as seen below:
|
|
Bypassing verifyLogin (MFA)
In verifyLogin(), our input mfa_token is checked with randomly-generated _correctValue.
The source code on lines 16 and 17 tells us that:
_correctValueis securely generated withrandom_int, so we are not supposed to try to guess_correctValue.mfa_tokenand_correctValueis compared strictly with===, so we are not looking at a type juggling vulnerability either.
|
|
Instead, the vulnerability lies in the fact that untrusted user input (login cookie) is unserialized back into objects (Login, User) without any prior validation or verification. This means that we can craft and modify our own serialized Login and User objects and attributes, encode it as a login cookie, submit it to the websiteโs login, and it will just be happily deserialized.
To bypass the MFA check, we can change the mfa_token attribute to be a reference to _correctValue so that they will always be strictly equal to each other. In code, it will look like this:
|
|
But how would the corresponding objects and serialized objects look like?
First, this is the unmodified Login object shown with print_r in a local testing environment:
|
|
And this is the serialized unmodified Login object with some newline formatting. Do also note that the \0s are supposed to be actual null bytes.
|
|
Now, by modifying $this->mfa_token = $mfa_token; to be $this->mfa_token = &$this->_correctValue; and printing the serialized object, we observe that
|
|
will be changed to
|
|
mfa_token no longer has a string value s but a null value N. _correctValue is also being referenced as evident by the R.
Thatโs great! But after bypassing this MFA check we still have a is_admin() method being called on the User object.
Bypassing is_admin (SQL)
In is_admin(), an SQL query is executed, rows are retrieved and checked to have non-empty email and password column values. An SQL object is also first created on line 12.
|
|
Looking into the SQL object created, we see that prepared statements are used to bind query parameters so SQL injection is not possible. However, we can instead exploit the PHP deserialization vulnerability again to modify query to whatever we like, as long as we ensure that our new query returns rows that have non-empty email and password fields.
|
|
Initially, I thought of using SELECT email, password FROM starcereal.admins WHERE email=? AND password=? OR 1=1 to return all existing rows in the database, but it did not work. I hypothesized that this could be because the existing database was empty and contained no rows to fetch.
As such, I modified the query to be:
|
|
which will definitely return a row with email value 'a' and password value 'a' even if the existing database was empty. Note that admins is changed to starcereal.admins as suggested by the challengeโs hint.
Final payload
To easily edit encoded serialized data to modify the query attribute to our new payload, we can use Hackvertor which is a Burp Suite extension.
- Paste the base64-encoded
logincookie into Input. - Use
auto_decode_no_decrypton the Input and we can see the serialized objects in the Output. - Swap Output with Input
After swapping, you can now edit the serialized object string as Input and it will be automatically converted into the appropriate login cookie format in the Output!
So now, this is how our final serialized payload looks like with additional newline formatting. Note that
query";s:63 on line 4 also needs to be changed to query";s:96 to reflect the new length of the query string.
|
|
Encoding it via Hackvertor and submitting it as a login cookie to /login.php:
|
|
we get a flag in the HTML response:
|
|
Flag: STC{1ns3cur3_d3s3r14l1z4t10n_7b20b860e23a128688cffc07a5b7e898}
Star Cereal 2
Ha, that was sneaky! But Iโve patched the login so that people like you canโt gain access anymore. Stop hacking us!
http://20.198.209.142:55045
The flag is in the flag format: STC{โฆ}
Author: zeyu2001
The website has interesting HTML comments that suggests there is a login vulnerability, but the login page is only accessible internally. 172.16.2.155 is also revealed to be one of the internal endpoints.
|
|
Checking the login page at /login.php gives us a 403 Forbidden and a message that says only admins are allowed to login.
|
|
This seems like a routing-based SSRF challenge via HTTP headers so I used Burp Intruder to place IP address payloads from the internal 172.16.2.0/24 subnet in various headers.
Filtering out
4xx responses, we see that our 172.16.2.24 payload responded with a 200 OK and a login page!
As seen from the source code, we need to send a POST request to
/login.php with email and pass parameters to login. I narrowed down the exploitable HTTP header to be X-Forwarded-For so we just need to include X-Forwarded-For: 172.16.2.24 in our request.
|
|
I assumed that the login vulnerability mentioned in the HTML comments was an SQL injection and the affected query statement was something similar to that of Star Cereal except that it does not use prepared statements. Thus, I tried using ' UNION SELECT "a", "a"# in the pass field:
|
|
Flag in HTML response:
|
|
Flag: STC{w0w_you'r3_r3lly_a_l33t_h4x0r_bc1d4611be52117c9a8bb99bf572d6a7}
Thanks for reading :)