访问模块'sys'而不使用导入机制

zwo*_*wol 6 python exploit sandbox

由于语言中内置的反射功能的强大功能,沙盒Python代码非常难以实现.至少必须带走import机制和大多数内置函数和全局变量,甚至还有漏洞({}.__class__.__base__.__subclasses__()例如).

在Python 2和3中,'sys'模块内置于解释器中,并在用户代码开始执行之前预加载(即使在-S模式下).如果你可以获得sys模块的句柄,那么你可以访问加载模块的全局列表(sys.modules),这使你可以做各种顽皮的事情.

因此,问题:从一个空的模块开始,不使用进口机器在所有(没有import说法,没有__import__,没有imp图书馆等),也没有使用任何通常发现__builtins__,除非你能得到它的句柄一些其他的方式,是否有可能获得对?syssys.modules?的引用?(每个都指向另一个.)对2.x和3.x答案感兴趣.

Mar*_*ers 5

__builtins__通常可以恢复,为您提供返回__import__任何模块的路径.

对于Python 3,来自eryksun的评论有用,例如:

>>> f = [t for t in ().__class__.__base__.__subclasses__() 
...      if t.__name__ == 'Sized'][0].__len__
>>> f.__globals__['__builtins__']['__import__']('sys')
<module 'sys' (built-in)>
Run Code Online (Sandbox Code Playgroud)

在Python 2中,您只需查找不同的对象:

>>> f = [t for t in ().__class__.__base__.__subclasses__()
...      if t.__name__ == 'catch_warnings'][0].__exit__.__func__
>>> f.__globals__['__builtins__']['__import__']('sys')
<module 'sys' (built-in)>
Run Code Online (Sandbox Code Playgroud)

这两种方法都可以查找您可以使用文字语法(此处为元组)创建的内置类型的子类,然后在该子类上引用一个函数对象.函数对象有一个__globals__字典引用,它将为您提供__builtins__对象.

需要注意的是,你不能只是说没有__import__,因为它的一部分__builtins__ 反正.

然而,许多这些的__globals__对象必然会有sys目前.sys例如,在Python 3上搜索模块可以让我在flash中访问一个模块:

>>> next(getattr(c, f).__globals__['sys']
...      for c in ().__class__.__base__.__subclasses__()
...      for f in dir(c)
...      if isinstance(getattr(c, f, None), type(lambda: None)) and
...         'sys' in getattr(c, f).__globals__)
<module 'sys' (built-in)>
Run Code Online (Sandbox Code Playgroud)

Python 2版本只需要解开您在类上找到的未绑定方法以获得相同的结果:

>>> next(getattr(c, f).__func__.__globals__['sys']
...      for c in ().__class__.__base__.__subclasses__()
...      for f in dir(c)
...      if isinstance(getattr(c, f, None), type((lambda: 0).__get__(0))) and
...         'sys' in getattr(c, f).__func__.__globals__)
<module 'sys' (built-in)>
Run Code Online (Sandbox Code Playgroud)