Bypass Python sandboxes

chevron-right从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)arrow-up-righthashtag

支持 HackTricks 的其他方式:

Try Hard Security Group


这些是绕过 Python 沙盒保护并执行任意命令的一些技巧。

命令执行库

您需要了解的第一件事是,您是否可以直接使用某个已导入的库执行代码,或者您是否可以导入以下任何库:

请记住,openread 函数可以用于在 Python 沙盒内读取文件,并编写一些代码来绕过沙盒执行。

triangle-exclamation

Python 会尝试首先从当前目录加载库(以下命令将打印 Python 加载模块的位置):python3 -c 'import sys; print(sys.path)'

使用默认安装的 Python 包绕过 pickle 沙盒

默认包

您可以在此处找到预安装的包列表https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.htmlarrow-up-right 请注意,通过 pickle,您可以使 Python 环境导入系统中安装的任意库。 例如,加载以下 pickle 时,将导入 pip 库以使用它:

有关pickle工作原理的更多信息,请查看这里:https://checkoway.net/musings/pickle/arrow-up-right

Pip软件包

@isHaacK分享的技巧

如果您可以访问pippip.main(),您可以安装任意软件包并调用以获取反向shell:

你可以在这里下载创建反向shell的软件包。请注意,在使用之前,你应该解压缩它,更改setup.py,并将你的IP放入反向shell中

circle-info

这个软件包叫做Reverse。然而,它经过特殊设计,当你退出反向shell时,安装的其余部分将失败,因此当你离开时不会在服务器上留下任何额外的Python软件包

评估Python代码

circle-exclamation

如果某些字符被禁止,你可以使用十六进制/八进制/Base64表示来绕过限制:

允许评估Python代码的其他库

运算符和简便技巧

通过编码(UTF-7)绕过保护

这篇文章arrow-up-right中,使用UTF-7来加载和执行任意Python代码,绕过了一个明显的沙盒:

也可以使用其他编码方式来绕过,例如 raw_unicode_escapeunicode_escape

无需调用的Python执行

如果你处于一个不允许你进行调用的Python监狱中,仍然有一些方法可以执行任意函数、代码命令

利用创建对象和重载实现RCE

如果你可以声明一个类创建该类的一个对象,你可以编写/重写不同的方法,这些方法可以在不需要直接调用它们的情况下被触发

使用自定义类实现RCE

你可以修改一些类方法(通过重写现有的类方法或创建一个新的类)来使它们在被触发时执行任意代码,而无需直接调用它们。

使用元类arrow-up-right创建对象

元类允许我们做的关键事情是,通过使用目标类作为元类,创建一个新的类,从而在不直接调用构造函数的情况下实例化一个类的实例

通过异常创建对象

当触发异常时,会自动创建一个 Exception 对象,无需直接调用构造函数(来自 @_nag0mezarrow-up-right 的技巧):

更多远程代码执行

使用内置的帮助和许可证读取文件

内建函数

如果你可以访问**__builtins__**对象,你可以导入库(注意,你也可以在最后一节中使用其他字符串表示形式):

无内建函数

当你没有 __builtins__ 时,你将无法导入任何东西,甚至无法读取或写入文件,因为所有的全局函数(如 openimportprint...)都没有被加载。 然而,默认情况下,Python 会在内存中导入许多模块。这些模块可能看起来无害,但其中一些也导入了危险的功能,可以访问这些功能以获得任意代码执行

在以下示例中,你可以看到如何滥用一些这些“无害”模块的加载,以访问其中的危险 功能

Python2

Python3

Python3

下面有一个更大的函数用于查找数十/数百个可以找到内置函数位置

Python2 和 Python3

内置载荷

全局变量和局部变量

检查 globalslocals 是了解你可以访问的内容的好方法。

寻找全局变量的递归搜索

在下面有一个更大的函数,可以找到数十/数百个可以找到全局变量的地方。

发现任意执行

在这里,我想解释如何轻松发现加载的更危险功能,并提出更可靠的利用方法。

使用绕过访问子类

这种技术最敏感的部分之一是能够访问基类的子类。在之前的示例中,可以使用''.__class__.__base__.__subclasses__()来实现,但也有其他可能的方法:

寻找已加载的危险库

例如,知道使用库 sys 可以导入任意库,你可以搜索所有已加载的模块中是否导入了 sys

有很多,我们只需要一个来执行命令:

我们可以使用其他已知可用于执行命令的库来做同样的事情:

此外,我们甚至可以搜索加载恶意库的模块:

此外,如果您认为其他库可能能够调用函数来执行命令,我们还可以在可能的库中按函数名称进行过滤

递归搜索内置函数、全局变量...

circle-exclamation

你可以在此页面上检查此脚本的输出:

https://github.com/carlospolop/hacktricks/blob/cn/generic-methodologies-and-resources/python/bypass-python-sandboxes/broken-reference/README.mdchevron-right

Python格式化字符串

如果你向Python发送一个将要被格式化的字符串,你可以使用 {} 来访问Python的内部信息。你可以使用之前的示例来访问全局变量或内置函数,例如。

circle-info

然而,有一个限制,你只能使用符号 .[],所以你无法执行任意代码,只能读取信息。 如果你知道如何通过这个漏洞执行代码,请与我联系。

注意如何可以用(dot)的方式像people_obj.__init__一样正常访问属性,以及用括号(parenthesis)而不加引号访问字典元素,比如__globals__[CONFIG]

还要注意可以使用.__dict__来枚举对象的元素,比如get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)

格式字符串的一些其他有趣特性是通过添加**!s!r!a分别执行指定对象中的strreprascii**函数:

此外,还可以在类中编写新的格式化程序

更多关于格式化字符串的示例可以在https://pyformat.info/arrow-up-right找到。

triangle-exclamation
Python Internal Read Gadgetschevron-right

敏感信息泄露有效载荷

解剖 Python 对象

circle-info

如果您想深入了解Python 字节码,请阅读这篇关于该主题的精彩文章:https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734darrow-up-right

在一些 CTF 比赛中,您可能会收到一个自定义函数的名称,其中包含标志,您需要查看函数内部以提取它。

这是要检查的函数:

dir

dir

全局变量

__globals__func_globals(相同)获取全局环境。在示例中,您可以看到一些导入的模块,一些全局变量及其声明的内容:

访问函数代码

__code__func_code: 您可以访问函数的这个属性来获取函数的代码对象。

获取代码信息

反汇编一个函数

请注意,如果您无法在Python沙箱中导入dis,您可以获取函数的字节码get_flag.func_code.co_code),然后在本地反汇编它。您将无法看到加载的变量内容(LOAD_CONST),但可以从(get_flag.func_code.co_consts)猜测它们,因为LOAD_CONST还会告诉您加载的变量的偏移量。

编译 Python

现在,让我们想象一下,你可以转储关于一个无法执行但你需要执行的函数的信息。 就像下面的例子,你可以访问该函数的代码对象,但仅仅通过阅读反汇编,你不知道如何计算标志想象一个更复杂的calc_flag函数)。

创建代码对象

首先,我们需要知道如何创建和执行一个代码对象,这样我们就可以创建一个来执行我们的函数 leaked:

根据 Python 版本,code_type参数可能有不同的顺序。了解你正在运行的 Python 版本中参数的顺序的最佳方法是运行:

重新创建一个泄霏的函数

circle-exclamation

绕过防御

在本文开头的示例中,您可以看到如何使用compile函数执行任何Python代码。这很有趣,因为您可以使用一行代码执行整个脚本,包括循环等(我们也可以使用exec做同样的事情)。 无论如何,有时在本地机器上创建一个编译对象并在CTF机器上执行它可能很有用(例如,因为我们在CTF中没有compile函数)。

例如,让我们手动编译和执行一个读取_./poc.py_文件的函数:

如果您无法访问 evalexec,您可以创建一个适当的函数,但直接调用它通常会失败,并显示:constructor not accessible in restricted mode。因此,您需要一个不在受限环境中的函数来调用此函数

反编译编译的Python

使用类似https://www.decompiler.com/arrow-up-right的工具,可以对给定的编译后的Python代码进行反编译

查看这个教程

Decompile compiled python binaries (exe, elf) - Retreive from .pycchevron-right

杂项 Python

断言

使用参数-O对Python进行优化执行时,将会移除断言语句和任何基于debug值的条件代码。 因此,像

将被绕过

参考资料

Try Hard Security Group

chevron-right从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert)arrow-up-righthashtag

支持HackTricks的其他方式:

最后更新于