沙箱逃逸
免责声明
本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.
相关文章
什么是沙箱逃逸
沙箱逃逸,就是在给我们的一个代码执行环境下,脱离种种过滤和限制,最终拿到 shell。
python如何执行命令
python 可以使用以下几个模块执行系统命令
import os
import subprocess
import commands
import pty
os.system('ifconfig')
os.popen('ifconfig')
commands.getoutput('ifconfig')
commands.getstatusoutput('ifconfig')
subprocess.call('ifconfig', shell = True)
subprocess.Popen('ifconfig', shell = True)
pty.spawn('ifconfig')对于不同的 py 版本可能情况不一样,记得获取当前的 Python 环境
timeit 模块
用于测试小代码片段的运行时间(number 即表示测试的次数):
platform 模块
类似 os 模块的 popen,可以执行命令:
codecs 模块
可以用来读文件:
exec()、eval()、execfile()、compile() 函数
exec():动态运行代码段,返回值为 None
eval():计算单个表达式的值,有返回值
execfile():动态运行某个文件中的代码
compile():将一个字符串编译为字节代码
字符串过滤的绕过
如果是某个字符串被过滤了,可以对它进行一些变换:
如果是关键字被过滤了,可以使用 getattr。getattr 接收两个参数,第一个是模块或对象,第二个是一个字符串。它会在模块或对象中搜索指定的函数或属性:
也可以使用 # coding:<encoding> 编码整个文件.
import 花式处理
import 关键字用来导入包,沙箱中对一些包或是函数进行了屏蔽,从 import 的不同方法到 import 的本质有多种不同的绕过方法。
使用其他的方式来导入其他包名
f修饰符
在PEP 498(python > 3.6.0)中引入了新的字符串类型修饰符:f或F,用f修饰的字符串将可以执行代码.可以理解为字符串外层套了一个exec().
模块路径
Python 中的所有包都是以 .py 文件的形式存在的,说明所有 import 进来的包一开始都预先在某个位置了。一般和系统相关的信息都在 sys 下,使用 sys.path 查看各个包的路径:
如果把 sys、os、reload 等一系列模块都过滤掉了,使用什么方法来绕过呢?导入模块的过程其实就是把对应模块的代码执行一遍的过程,在知道模块对应路径的情况下,就可以相应地执行它:
在 execfile 被禁止的情况下,还可以用 open 读入文件,并使用 exec 来执行相应的代码:
内置函数
python存在一些内置函数(即默认已经导入的函数),对应的内置模块__builtins__.
内置函数 dir() 在没有参数的时候返回本地作用域中的名称列表, 有参数的时候返回参数对象的有效属性列表. 可以通过 dir(__builtins__) 获取内置函数列表, 然后通过 dict 引入模块, dict 的作用是列出一个模组 / 类 / 对象下所有的属性和函数.
如果一些内置函数被删除, 可以通过 reload(__builtins__) 重新载入.
在 python3.x 版本中,__builtin__ 变成了 builtins 模块, 而且需要导入.
dir 和 __dict__
__dict__dir 和 __dict__ 可以用来查看类或对象下的所有属性信息:
和 sys.modules 配合使用获得一个模块的引用:
func_code 的利用
函数的 func_code 属性可以被用来查看函数的参数个数以及变量,还能看到函数对应的字节码:
使用 dis 库可以获取函数对应汇编格式的字节码:
object类基础函数
Python 允许多重继承,即一个子类有多个父类。__mro__ 属性可以用来查看一个子类所有的父类;__bases__ 可以获取上一层的继承关系:
python 的 object 类中集成了很多的基础函数, 可以通过创建对象来引用.
寻找特殊模块的方法:__class__, 获得当前对象的类;__bases__, 列出其基类;__mro__, 列出解析方法的调用顺序(即类的继承关系);__subclasses__(), 返回子类列表;__dict__, 列出当前属性 / 函数的字典; func_globals, 返回一个包含函数全局变量的字典引用.
比如 ().__class__.__bases__[0].__subclasses__()[40] 对应的是 file 类.在 open 等文件操作被限制的情况下可以用下面的方法读取文件内容(__subclasses__ 即用来查看对象的所有子类;
其他的一些执行命令的方法(通过获取其他已经载入了 os 等模块的类进行调用):
可以编写一个函数对导入了 os 或 sys 的库进行一个遍历:
伪 private 属性和函数
Python 中以双下划线开头的函数和属性是 private 的,但是这种 private 只是形式上的,表示这个函数不应该在本类之外的地方进行访问,而是否遵守则取决于具体的实现。公有的函数和属性,使用其名字直接进行访问;而私有的属性和函数,使用 下划线+类名+函数名 进行访问:
构造 so 库
编译一个 so 库,并写入指定的路径:
调用 ctypes 来载入 so 库:
修改 GOT 表
把 fopen 的 GOT 改为 system。先用 objdump 查找