Python沙箱逃逸与模板注入(SSTI)(一)

 最近恰巧同时研究了一下python沙箱逃逸和jinja2模板注入,而且模板注入使用了很多沙箱逃逸的方法,所以将python的沙箱逃逸和服务端模板注入放在一起总结。

    网上的python沙箱逃逸都是关注于Python2,介于与3的不同我把所有payload都在3中实验了一遍,把部分修改成可用,不能使用的删去。

python沙箱逃逸

基础知识

沙箱:沙箱是一种按照安全策略限制程序行为的执行环境。

    沙箱逃逸:就是在给我们的一个代码执行环境下,脱离种种过滤和限制,最终成功拿到shell权限的过程。其实就是闯过重重黑名单,最终拿到系统命令执行权限的过程。

    简而言之就是绕过限制拿到shell。而在python环境下绕过限制当然还是要对python的各种系统函数内建函数熟悉啦,所以下面我们总结一下有用的python知识。

python知识扩展

shell执行相关

当然,这些模块都是需要import导入的,如果限制了导入那也百搭。

import导入相关

    1. import
    1. __import__ 函数
    1. importlib
  1. builtin内建函数

__import__

importlib

builtin
我们dir(__builtins__)看一下有哪些内建函数可以使用

     还是很多的,当然也包括了eval,exec,execfile等危险函数。当然,很多沙箱会直接del __builtins__.eval这样的操作会将eval函数从内建函数删除,我们就无法直接使用eval函数了。但是1我们可以通过内建函数reload()重置builtin内建函数

如果它把reload也删了就用不了啦。

python重要的魔法函数和属性

 

名称 介绍
__dict__ 这个属性中存放着类的属性和方法对应的键值对,实测module也有这个属性
__class__ 返回一个实例对应的类型
__base__ 返回一个类所继承的基类
__subclasses__() 返回该类的所有子类
__mro__ python支持多重继承,在解析__init__时,定义解析顺序的是子类的__mro__属性(值是类的元组)
__slots__ 限制类动态添加属性
__getattribute__() 获取属性或方法,对模块和类都有效
__getitem__() 以索引取值或者键取值
__globals__ 返回函数所在模块命名空间中的所有变量

沙箱逃逸绕过

 看了上面这么多,我们应该可以理解,沙箱逃逸就是用奇淫技巧来执行一些函数,接下来我们看看在限制下可以怎么bypass。

直接import模块

 如果能直接import或者按按上面的方式import危险模块,比如os或者commands,那就应该感谢上帝了。但现在这样的情况不多了。

使用exec、execfile

    我们现在已知它们是内建函数中的两个函数,假如沙箱限制了所有import的方法,不过我们可以用这两个函数直接运行/usr/lib/python2.7/os.py里的代码,那么我们就可以直接使用system函数了。

键值被过滤&关键字或函数名被过滤

 假如是限制了关键字怎么办?(比如不让输入system,popen等函数名或者字典的键值被过滤)

[被过滤

使用__getitem__获取列表或者元祖的值

使用timeit

魔法函数

 我们可以通过魔法函数回溯继承类再从子类中找到能用的函数。上面已经总结了一些常用的魔法函数,下面我们推导一下。

这样我们就找到eval函数了,按照同样的方法,我们还可以找到很多种payload

__globals__

​ 其他魔法函数和内置属性在上面的表格中有列出它的作用,在这里重点理解一下__globals__会返回函数所在模块命名空间中的所有变量的键值对表示。
​   此时,我们找到一个函数看看他的__globals__是啥。

  按照上面的推导,我们总能从__globals__中找到我们想要的函数。
​ 如果能使用__globals__,就使我们的沙箱逃逸方法变得简单多了,我们只要遍寻到一个类(实测只有部分类的函数有这个属性,不过概率很大),然后取它一个内置函数的__globals__就能找到__builtins__了。

总结

 python沙箱逃逸重点就得熟悉python,全文最难就在于如何从庞大的继承树中找到自己需要的危险函数,懂得原理我们就可以一步一步的推导,虽然不同系统不同环境我们所取的下标可能不同,但是多试试总能找到的。

 这篇博客主要总结了python沙箱逃逸问题,下一篇总结一下SSTI。

3 thoughts on “Python沙箱逃逸与模板注入(SSTI)(一)

  1. 请问如果用sys.modules导入os模块,键值使用路径,我测试并不能使用os的功能,他的键值应该是一个module,要怎么解决呢= =。

发表评论

电子邮件地址不会被公开。 必填项已用*标注