【问题标题】:Is there a way to make buffer() writable without copying when the size argument is set?有没有办法在设置 size 参数时使 buffer() 可写而不复制?
【发布时间】:2016-12-03 12:33:53
【问题描述】:

如果一个对象是可变的,那么可以通过不指定 buffer() 的第二个参数来获得一个可修改的缓冲区(这是一个内置函数),如下所示:

>>> s = bytearray(1000000)   # a million zeroed bytes
>>> t = buffer(s, 1)         # slice cuts off the first byte
>>> s[1] = 5                 # set the second element in s
>>> t[0]                     # which is now also the first element in t!
'\x05'

但是,就我而言,我需要指定0x7fffffff作为大小参数。在这种情况下:

>>> b = buffer(bytearray('a'), 1,0x7fffffff)

how to make b writeable without copying it’s data?在我的情况下,_ctypessupport 已禁用,并且该程序未以 root 身份启动。
当然,可以使用 memoryview 之类的东西,但我失去了读取每个虚拟地址的内存的可能性。

【问题讨论】:

    标签: python linux security python-2.x 32-bit


    【解决方案1】:

    副本是必要的。 bytearray 的内部缓冲区根本不是 2 GiB 长;如果你想要一个 2 GiB 的缓冲区,你需要将字节数组的数据复制到一个新的缓冲区中。

    如果您以某种方式强制 Python 将缓冲区视为您想要的大小而不进行复制,那么写入它会破坏您的进程的内存和/或导致段错误。

    【讨论】:

    • 你注意安全标签了吗?我在我的问题中忘记了include this。我获得了在网站上执行任意 python 代码的可能性。但是他们的赏金计划只有在我逃脱用于解释器的沙箱时才会奖励(我需要为此执行本机汇编代码)
    • writing to it would corrupt your process's memory。这就是我想要做的:我需要直接访问系统调用才能逃脱操作系统级别的沙箱。这需要能够执行本机程序集,以便我可以绕过 python 级沙箱(python 沙箱阻止我逃离ᴏꜱ级沙箱)
    • @user2284570:好吧,如果你试图利用这个漏洞,你会遇到一个额外的问题,即使用buffer 创建的缓冲区对象根本不可写,无论你是否通过一个大小参数,并且没有 Python 端 API 可以使它们可写。您使用 s[1] = 5 通过字节数组进行了写入,而不是通过缓冲区对象进行了写入。
    • 如果你想接管一个 Python 进程,我会考虑其他方法。还有很多其他的攻击媒介,比如构建你自己的 Python 代码对象,它写入到其 locals 数组的末尾,或者查看他们是否忘记禁用 _ctypes,或者只是使用类似 os.exec* 的函数,或者采取利用引用泄漏(可能是property.__init__ 中的泄漏)溢出对象的引用计数,释放它,并使用悬空引用来拧紧在同一空间上分配的东西的内部。
    • 我已经在我的问题中告诉_ctypeisn't available 由于 python 级别的沙箱。可用于启动外部应用程序的所有内容都将被删除os.popen()os.system()os.fork() 等内容已禁用)。即使_socket不存在。也无法写入文件 (python 沙箱确保所有内容都是只读的)。大多数 python 标准库都是可用的。只是禁用了可能损害系统的功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    相关资源
    最近更新 更多