picoctf CTF 2018 Flaskcards serial

picoCTF is a CTF hosted by CMU targeted at high school students, which is a great opportunity for beginner to improve their skill. I enjoy this CTF a lot.
Not really a Team, just me.

This is the Writeup for Flaskcards serial: “Flaskcards”, “Flaskcards Skeleton Key” and “Flaskcards and Freedom”.

All three problems have the same interface: first you create an account, login in with the account you created, exploit different vulnerabilities to get the Flag.

This is the register page:

After the user login to the account, the user can create a Flashcard by entering the question and answer:

Click “List Cards” on the top to show the Flashcard:

There is an Admin Page on the website, which looks interesting:

Problem 1, Flaskcards:
We found this fishy website for flashcards that we think may be sending secrets. Could you take a look?

For this problem, I try base64decode the Cookie, but the output is not plain text.

I noticed the name of the problem is strange, it should spell as “Flashcard”, but why the name is “Flaskcard”? Then I realize this can be a Flask application, which might be vulnerable to template injection attack: https://portswigger.net/blog/server-side-template-injection

I test the input {{2*2}}, if the application is vulnerable to template injection, it should return “4”.

And it did return “4”, which prove the application is vulnerable to a template injection attack.

{{config}} can show the configuration of the application, I create a card with Question {{config}}.

The server returns the application configuration and the Flag:

Problem 2: Flaskcards Skeleton Key
Nice! You found out they were sending the Secret_key: 385c16dd09098b011d0086f9e218a0a2. Now, can you find a way to log in as admin? http://2018shell3.picoctf.com:48263 (link).

It seems the problem want me to login as Admin. I Google how cookie work in Flask application:
Found this: http://flask.pocoo.org/docs/1.0/quickstart/

And this write-up form 2017 ASIS CTF that is also related to Flask Cookie and template injection. I use the Code from this article to encode and decode the Flask Cookie: https://teamrocketist.github.io/2017/09/11/Web-ASIS-Golem-is-stupid

My original cookie value: .eJwtjzluwzAQAP_C2sWS1B70Z4Q9EcNAAkh2FeTvVpF-Bpj5bXsdeX61--t4563tj2j3toVLLEIgRYwuMHTSDB6zvGIaOiLpFgJuY1oaLdhURXQiMPuojQZNBevSid2kz3SPYcVLFwsEGoIAVYHPSs6QEL7YciNot-bnUfvr55nfV8_FC9YombnRsloLGVndK6tTUC7OYayX9z7z-J9ofx-whT-m.Dp7TIg.XWUpmVkxoQAUPFWekpTEPe2UA2U
The cookie value after decoding:

{u'csrf_token': u'80d85f2f83e469bf995757accfef16d6e97e2b7a', u'_fresh': True, u'user_id': u'4', u'_id': u'4dc8d96506a55d1802a363d723fcfd3b5c556a4d80cb23beb6904aa88a35077c2f46263a0b18167cb813eccd2bf79a9780d5b50806ff0c3fe7ed8d87167fcb60'}

I change the "user_id" value to 1 and encode the Cookie again:

sk = '385c16dd09098b011d0086f9e218a0a2'
decodedDict = decodeFlaskCookie(sk, '.eJwtjzluwzAQAP_C2sWS1B70Z4Q9........original Cookie value....UA2U')
print decodedDict
decodedDict['user_id'] = '1'
cookie = encodeFlaskCookie(sk, decodedDict)cookie = encodeFlaskCookie(sk, decodedDict)

Insert the new Cookie in Chrome:

Get the Flag from the Admin page:

Problem 3: Flaskcards and Freedom
There seem to be a few more files stored on the flashcard server but we can’t log in. Can you? http://2018shell3.picoctf.com:46628 (link)

From the hint I know I need to achieve remote code execution to get the Flag:

After Googling and Baiduing “Flask template injection”, the first step is to dump all available class with command:

The server returns all available class:

The second step is to find certain Classes that have the ability to do “eval” or “exec”, in this case, I use "warings.catch_warnings"
Copy and Paste all the classes in Sublime Text and format them nicely so we can find out where is the "warings.catch_warnings" Class. The number is 243, so to call the Class, the command should be:

From this post: https://blog.csdn.net/qq_27446553/article/details/79379136. I learn that the command to execute code will be:
Create a card with the command above, the server will return:

Found a file called “Flag”, use “cat flag” to read the Flag:
{{[].__class__.__base__.__subclasses__()[243].__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat flag").read()')}}