浅析Python沙盒逃逸
沙盒逃逸原理
沙盒逃逸的过程就是在一个代码执行的环境下,脱离种种过滤和限制,最终拿到shell权限的过程。也就是绕过各种黑名单最终拿到系统命令执行权限。
Python中的魔术方法
1 | __class__ 返回类型所属的对象 |
我们打开python编译器后就算没有创建任何的变量或者函数,但是在python中我们还是有可以调用的函数,也就是所说的内建函数。
我们通过上述提到的python中的魔术方法,我们就可以利用任何一个变量到基类
中,获得基类中的所有实现的类,然后再调用相应的成员变量。从而达到沙盒逃逸。
魔术方法
众所周知,python是一门面对对象编程的语言,在python中一切皆为对象。均继承Object对象。
__base__
和__mro__
都是用来寻找基类的,通过上图我们可以看到基类都是Object.
获取字符串的类对象
1 | ''.__class__ |
获取基类地址
1 | ''.__class__.__mro__ |
查看实现类和成员
1 | ''.__class__.__mro__[1].__subclasses__() |
jinja2变量解析
1 | 控制结构 {% %} |
读取
file
不能像字符串对象,列表对象那样直接引用(' ',[ ])
,所以我们只能用上面说到的属性和方法
1 | for c in {}.__class__.__base__.__subclasses__(): |
分析一下代码,能够知道基类为Object
然后取Object的所有子类,在子类中寻找file类,如果能找到就使用file构造方法创建对象,再利用readlines()读取文件内容。
用jinja2的语法就是
1 | {% for c in [].__class__.__base__.__subclasses__() %} |
在docker容器中找不到
不过在本地是可以的
然后就去百度了一下为什么找不到file,发现在python3中并没有file类,上述方法只适用于python2
eval
寻找builtins得到eval
既然file在python3中不能使用,那就找eval,有了它还会发愁嘛!
我们在python2和python3中找__builtins__
找共有的类。然后构造通用的任意执行代码。
1 | for c in ().__class__.__bases__[0].__subclasses__(): |
jinja2语法
1 | {% for c in [].__class__.__base__.__subclasses__() %} |
直接从globals中寻找eval
原理和上面大同小异,先取所有子类,看是否有catch_warnings
,变量b在globals__.values()
下进行遍历。
判断变量b的类型是否为{}.__class__
, 如果eval在b.keys中,则执行eval下构造的代码。
1 | {% for c in [].__class__.__base__.__subclasses__() %} |
另外一种payload构造方法
1 | {% for c in [].__class__.__base__.__subclasses__() %} |
- 小白学习,文章若有错误,还请大佬们指出。QQ:515469508