跳转到主要内容

Python pickle数据的静态分析器和解释器

项目描述

Fickling

Fickling image

Fickling是Python pickle对象序列化的反汇编器、静态分析器和字节码重写器。您可以使用fickling来检测、分析、逆向工程,甚至创建恶意pickle或基于pickle的文件,包括PyTorch文件。

Fickling可以作为python库CLI使用。

安装

Fickling已在Python 3.8至Python 3.11上进行了测试,并且依赖性很少。库和命令行实用程序都可以通过pip安装

python -m pip install fickling

PyTorch是Fickling的可选依赖项。因此,为了使用Fickling的pytorchpolyglot模块,您应该运行

python -m pip install fickling[torch]

恶意文件检测

Fickling可以无缝集成到您的代码库中,以在运行时检测并阻止恶意文件的加载。

以下展示了您可以使用 fickling 对 pickle 文件进行安全检查的不同方法。在底层,它通过挂钩 pickle 库来添加安全检查,如果文件中检测到恶意内容,则加载 pickle 文件时会引发 UnsafeFileError 异常。

选项 1(推荐):检查所有加载的 pickle 文件的安全性

# This enforces safety checks every time pickle.load() is used
fickling.always_check_safety()

# Attempt to load an unsafe file now raises an exception  
with open("file.pkl", "rb") as f:
    try:
        pickle.load(f)
    except fickling.UnsafeFileError:
        print("Unsafe file!")

选项 2:使用上下文管理器

with fickling.check_safety():
    # All pickle files loaded within the context manager are checked for safety
    try:
        with open("file.pkl", "rb") as f:
            pickle.load("file.pkl")
    except fickling.UnsafeFileError:
        print("Unsafe file!")

# Files loaded outside of context manager are NOT checked
pickle.load("file.pkl")

选项 3:检查和加载单个文件

# Use fickling.load() in place of pickle.load() to check safety and load a single pickle file 
try:
    fickling.load("file.pkl")
except fickling.UnsafeFileError as e:
    print("Unsafe file!")

选项 4:只检查 pickle 文件的安全性,而不加载

# Perform a safety check on a pickle file without loading it
if not fickling.is_likely_safe("file.pkl"):
    print("Unsafe file!")

访问安全分析结果

您可以从引发的异常中访问 fickling 的安全分析细节

>>> try:
...     fickling.load("unsafe.pkl")
... except fickling.UnsafeFileError as e:
...     print(e.info)

{
    "severity": "OVERTLY_MALICIOUS",
    "analysis": "Call to `eval(b'[5, 6, 7, 8]')` is almost certainly evidence of a malicious pickle file. Variable `_var0` is assigned value `eval(b'[5, 6, 7, 8]')` but unused afterward; this is suspicious and indicative of a malicious pickle file",
    "detailed_results": {
        "AnalysisResult": {
            "OvertlyBadEval": "eval(b'[5, 6, 7, 8]')",
            "UnusedVariables": [
                "_var0",
                "eval(b'[5, 6, 7, 8]')"
            ]
        }
    }
}

如果您使用的是 Python 之外的语言,您仍然可以使用 fickling 的 CLI 来安全检查 pickle 文件

fickling --check-safety -p pickled.data

高级用法

跟踪pickle执行

Fickling 的 CLI 允许在执行恶意代码之前安全地跟踪 Pickle 虚拟机的执行

fickling --trace file.pkl

Pickle代码注入

Fickling 允许在 pickle 文件中注入任意代码,这些代码将在每次加载文件时运行

fickling --inject "print('Malicious')" file.pkl

Pickle反汇编

Fickling 可以用于将 pickle 文件反编译以进行进一步分析

>>> import ast, pickle
>>> from fickling.fickle import Pickled
>>> fickled_object = Pickled.load(pickle.dumps([1, 2, 3, 4]))
>>> print(ast.dump(fickled_object.ast, indent=4))
Module(
    body=[
        Assign(
            targets=[
                Name(id='result', ctx=Store())],
            value=List(
                elts=[
                    Constant(value=1),
                    Constant(value=2),
                    Constant(value=3),
                    Constant(value=4)],
                ctx=Load()))],
    type_ignores=[])

PyTorch多语言

PyTorch 包含多种文件格式,可以创建多语言文件,即可以合法地解释为多个文件格式的文件。fickling 支持 PyTorch 以下文件格式的识别、检查和创建多语言文件

  • PyTorch v0.1.1:包含 sys_info、pickle、storages 和 tensors 的 Tar 文件
  • PyTorch v0.1.10:堆叠的 pickle 文件
  • TorchScript v1.0:包含 model.json 的 ZIP 文件
  • TorchScript v1.1:包含 model.json 和 attributes.pkl 的 ZIP 文件
  • TorchScript v1.3:包含 data.pkl 和 constants.pkl 的 ZIP 文件
  • TorchScript v1.4:包含 data.pkl、constants.pkl 且版本设置为 2 或更高(2 个 pickle 文件和一个文件夹)的 ZIP 文件
  • PyTorch v1.3:包含 data.pkl 的 ZIP 文件(1 个 pickle 文件)
  • PyTorch 模型存档格式[ZIP]:包含 Python 代码文件和 pickle 文件的 ZIP 文件
>> import torch
>> import torchvision.models as models
>> from fickling.pytorch import PyTorchModelWrapper
>> model = models.mobilenet_v2()
>> torch.save(model, "mobilenet.pth")
>> fickled_model = PyTorchModelWrapper("mobilenet.pth")
>> print(fickled_model.formats)
Your file is most likely of this format:  PyTorch v1.3 
['PyTorch v1.3']

查看我们的示例,了解如何使用 fickling 的更多信息!

更多信息

Python 序列化的对象实际上是字节码,由 Python 内置的基于栈的虚拟机“Pickle 机”进行解释。Fickling 可以将序列化的数据流反编译成可读的 Python 代码,当执行时,将反序列化为原始的序列化对象。这是通过 Fickling 对 PM 的自定义实现实现的。由于 Fickling 的 PM 是符号执行代码而不是直接执行,因此可以在潜在恶意的文件上安全运行。

作者并没有对 Fickling 中的“F”赋予任何意义;它可能代表“多变”……或者别的什么。解读其含义是一种个人旅程,留作读者的练习。

在我们的博客文章DEF CON AI Village 2021 演讲中了解更多关于 fickling 的信息。

联系

如果您想提交错误报告或功能请求,请使用我们的问题页面。如果您需要使用或扩展 fickling 的帮助,请随时联系我们或在Empire Hacking 中寻求帮助。

许可协议

本实用程序由Trail of Bits开发。它根据GNU Lesser General Public License v3.0许可。如果您需要例外,请联系我们

© 2021,Trail of Bits。

项目详情


下载文件

下载您平台对应的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码分发

fickling-0.1.3.tar.gz (32.8 kB 查看哈希值)

上传时间 源代码

构建分发

fickling-0.1.3-py3-none-any.whl (34.5 kB 查看哈希值)

上传时间 Python 3

支持者