【问题标题】:why Python pickle is different between win & linux with using os为什么 Python pickle 是 win 和 linux 与使用 os 的区别
【发布时间】:2021-08-30 16:07:42
【问题描述】:

完成我的 poc,我发现了不同

#py 3.9.6
import pickle
import os


class PickleRCE(object):
    def __reduce__(self):
        return (os.system, ('whoami',))


print(pickle.dumps(PickleRCE(), protocol=0))

当我在 linux 中加载 windows 的 pickle 字节时,我得到“ModuleNotFoundError: No module named 'nt' ";

当我在 Windows 中加载 linux 的 pickle 字节时,我得到“ModuleNotFoundError: No module named 'posix'”

这意味着带有os模块的pickle文件不能跨平台

谢谢

【问题讨论】:

  • 什么是“poc”?
  • 使用标签ctf是什么意思?

标签: python serialization pickle


【解决方案1】:

Python 泡菜不保证可移植。一个普通的 pickle 最多可以在支持相同版本的 pickle 协议的 Python 版本之间移植。但它们甚至不一定可以在 Python 版本之间移植,例如如果您正在挑选一个在一个版本的标准库中但不在另一个版本中的函数。

在这种情况下,您可以自己查看数据的差异(有一些不错的模块可以分析泡菜的内容,但我们只看字节):

>>> p = pickle.dumps((os.system, ('whatever',)))
>>> p
b'\x80\x03cposix\nsystem\nq\x00X\x08\x00\x00\x00whateverq\x01\x85q\x02\x86q\x03.'

正如您所见,其中有一些关于“posix”和“system”的内容(这是在 Linux 上)。在 Windows 上,您会在同一位置看到 nt\nsystem

这是因为它可以做到最好。 pickling functions 是存储定义函数的模块名称和函数本身的名称,并尝试从该模块导入。

os.system 的情况下,它是一个内置函数,实际上是在posix 模块或nt 模块中定义的,但为了方便/可移植性,也导入到os 模块中。

>>> os.system.__module__
'posix'

pickle 模块有一些扩展(例如,dill 可以腌制纯 Python 函数(主要是通过腌制它们的字节码等)。但这不适用于像 os.system 这样的内置函数。

不确定您要做什么,但可能有更好的方法(您是否尝试过os.getlogin

【讨论】:

    猜你喜欢
    • 2013-09-24
    • 2013-10-12
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2011-05-13
    • 2014-05-16
    • 2019-06-19
    • 1970-01-01
    相关资源
    最近更新 更多