-
-
[原创]CTF真题之python3的沙箱逃逸
-
发表于: 2021-12-9 11:35 6336
-
CTF真题之python3的沙箱逃逸
前提知识
内联函数
1 2 3 4 5 | # 下面代码可列出所有的内联函数 dir (__builtins__) # Python3有一个builtins模块,可以导入builtins模块后通过dir函数查看所有的内联函数 import builtins dir (builtins) |
魔术函数
1 2 3 4 5 6 7 8 9 | __class__ 返回一个实例所属的类 __mro__ 查看类继承的所有父类,直到 object __subclasses__() 获取一个类的子类,返回的是一个列表 __bases__ 返回一个类直接所继承的类(元组形式) __init__ 类实例创建之后调用, 对当前对象的实例的一些初始化 __globals__ 使用方式是 函数名.__globals__,返回一个当前空间下能使用的模块,方法和变量的字典 __getattribute__ 当类被调用的时候,无条件进入此函数。 __getattr__ 对象中不存在的属性时调用 __dict__ 返回所有属性,包括属性,方法等 |
builtin
在python中,我们知道,不用引入直接使用的内置函数称为 builtin 函数,随着__builtin__
这一个module 自动被引入到环境中
(在python3.x 版本中,__builtin__
变成了builtins,而且需要引入)
因此,open(),int(),chr()这些函数,就相当于
1 2 3 | __builtin__. open () __builtin__. int () __builtin__. chr () |
如果我们把这些函数从builtin中删除,那么就不能够再直接使用了
1 2 3 4 5 6 | >>> import __builtin__ >>> del __builtin__. chr >>> chr ( 1 ) Traceback (most recent call last): File "<stdin>" , line 1 , in <module> NameError: name 'chr' is not defined |
同样,刚才的__import__
函数,同样也是一个builtin函数,同样,常用的危险函数eval,exec,execfile也是__builtin__
的,因此只要从__builtin__
中删除这些东西,那么就不能再去使用了
object类
对于支持继承的编程语言来说,其方法(属性)可能定义在当前类,也可能来自于基类,所以在方法调用时就需要对当前类和基类进行搜索以确定方法所在的位置。而搜索的顺序就是所谓的「方法解析顺序」(Method Resolution Order,或MRO)。
关于MRO的文章:http://hanjianwei.com/2013/07/25/python-mro/
python的主旨是一切变量皆对象
python的object类中集成了很多的基础函数,我们想要调用的时候也是需要用object去操作的,主要是通过__mro__
和 __bases__
两种方式来创建。__mro__
属性获取类的MRO(方法解析顺序),也就是继承关系。__bases__
属性可以获取上一层的继承关系,如果是多层继承则返回上一层的东西,可能有多个。
通过__mro__
和__bases__
两种方式创建object类
1 2 3 4 5 6 7 8 | ().__class__.__bases__[ 0 ] {}.__class__.__bases__[ 0 ] [].__class__.__mro__[ 1 ] python3 ''.__class__.__mro__[ 1 ] python2 ''.__class__.__mro__[ 2 ] |
然后通过object类的__subclasses__()
方法来获得当前环境下能够访问的所有对象,因为调用对象的 __subclasses__()
方法会返回当前环境中所有继承于该对象的对象.。Python2和Python3获取的结果不同。
1 | {}.__class__.__bases__[ 0 ].__subclasses__() |
前言
前段时间在twitter上看到大佬抛出一个疑问。给出了一段代码,我当时也是想了半天也没想出来。
1 2 3 4 | code = input () for c in 'hui"\'(' : assert c not in code exec (code, { '__builtins__' : {}}) |
这题禁用了hui"\'(
这些字符导致常用的沙箱绕过的payload和魔法方法都无法执行,都会被断言失败。
_builtins与builtin__的区别
两者有何区别,以及为何这么做,请阅读以下两篇博客:
https://www.cnblogs.com/Ladylittleleaf/p/10240096.html
总的概括而言:
By default, when in the
__main__
module,__builtins__
is the built-in module__builtin__
(note: no 's'); when in any other module,__builtins__
is an alias for the dictionary of the__builtin__
module itself.
解题
3 月 15 号的时候 Arthur Khashaev (twitter @Invizory)给了个解法,我觉得很有趣,来和大家分享一下
原帖地址: https://gist.github.com/Invizory/36b5c4e037548b940c831efe350162d2
他给的解题思路是这样
1 2 3 4 5 6 7 8 9 10 11 12 | b = [].__class__.__base__ d = [].__doc__ n = d.__doc__[ 31 ] __bᵤ 赞赏
他的文章
看原图
赞赏雪币:
留言:
|