python pickle反序列化漏洞_Python 的另外几个反序列化漏洞检查点

哔哔两句

最近刚做完某个白盒渗透项目,通读了整个项目代码后发现了几个比较明显的 Python 反序列化漏洞的问题。

代码中使用了 Pickle 这个 Python 反序列化模块,除此以外还发现了另外一个比较陌生的模块。from sklearn.externals import joblib

因为在这个项目中 pickle 模块加载的都是扩展名为 .pkl 的文件,我认为它是 PicKLe 的缩写,经过资料查询也证明了这个猜想。

同时除了 pickle 模块,还有一个 joblib 模块也用它的 load() 函数加载了 .pkl 的文件,这让我很好奇,问了几个朋友也没有认识这个模块的,谷歌也没找出关于这个模块的漏洞文章,python 反序列化漏洞都是在讲 pickle、cPickle 和 PyYaml 的。

于是我尝试了一下用 joblib 这个模块是否能达到反序列化的效果

结论是当然可以

对比生成后的反序列化字节码和跟踪 joblib.load() 函数发现其实他就是封装了 pickle。

而这个 sklearn 其实是一个用于机器学习的库,一般在大型项目中或者有关机器学习的项目中能找到,所以大家以后在白盒审计 python 项目时除了 pickle 和 cPickle 以外还可以注意一下 sklearn 的 joblib 模块。

举一反三

学习一个东西就要举一反三,所以在看完 sklearn 后又查了一些相关的资料。

sklearn 的反序列化问题是由于它要在机器学习的过程中加载模型,所以会有一些反序列化的操作。但是机器学习的库不止 sklearn 一个,还有很多知名的机器学习第三方库,那么它们是否也存在同样的问题?

NumPy (21,219 commits / 11,711 star)NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

这个是被曝存在过漏洞的(CVE-2019-6446),如果 load 方法的 allow_pickle 参数被允许的话,或 loads 方法参数可控,则会引起安全问题

numpy 的 load 函数中判断如果 allow_pickle 为 True,则调用 pickle.load 函数if not allow_pickle:

raise ValueError("Cannot load file containing pickled data "

"when allow_pickle=False")

try:

return pickle.load(fid, **pickle_kwargs)

except Exception:

raise IOError(

"Failed to interpret file %s as a pickle" % repr(file))

numpy.loads() 则是直接调用了 pickle.loads()

Demo#!/usr/bin/python

# -*- coding:utf-8 -*-

# @Author : b1u3r

# @Time : 2019/9/10 21:53

import numpy

numpy.load("blue.pkl",allow_pickle=True )

with open("blue.pkl","rb") as d:

numpy.loads(d.read())

Pandas (20,109 commits / 21,245 star)Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。

这个库的问题还没有被提出,在 pandas.read_pickle() 函数中,同样是由 pickle.load() 引起

Demo#!/usr/bin/python

# -*- coding:utf-8 -*-

# @Author : b1u3r

# @Time : 2019/9/10 21:53

import pandas

pandas.read_pickle("blue.pkl")

PyTorch (20,565 commits / 31,489 star)PyTorch是使用GPU和CPU优化的深度学习张量库。

pytorch 也存在相同的问题,它的 load 函数中,有一个值为 pickle 对象的 pickle_module 参数。

在后面的反序列化的过程直接调用的是 pickle_module.load() 函数,相当于是在调用 pickle.load()

Demo#!/usr/bin/python

# -*- coding:utf-8 -*-

# @Author : b1u3r

# @Time : 2019/9/10 21:53

import torch

torch.load("blue.pkl")

CheckList

以上三个是我从 python 的机器学习最常用、Commits 次数多的几个库中挑选出来的库,经过测试均存在反序列化的问题。

以下例举几个在 python 代码审计时针对反序列化漏洞的检查点。

CheckPoint 1import pickle

pickle.load(open("blue.pkl","rb"))

with open("blue.pkl","rb") as d:

pickle.loads(d.read())

CheckPoint 2import cPickle

cPickle.load(open("blue.pkl","rb"))

with open("blue.pkl","rb") as d:

cPickle.loads(d.read())

CheckPoint 3import _pickle

_pickle.load(open("blue.pkl","rb"))

with open("blue.pkl","rb") as d:

_pickle.loads(d.read())

CheckPoin 4from sklearn.externals import joblib

joblib.load("blue.pkl")

CheckPoint 5from pickle import Unpickler

Unpickler(open("blue.pkl","rb")).load()

CheckPoint 6import numpy

numpy.load("blue.pkl",allow_pickle=True )

with open("blue.pkl","rb") as d:

numpy.loads(d.read())

CheckPoint 7import pandas

pandas.read_pickle("blue.pkl")

CheckPoint 8import torch

torch.load("blue.pkl")

如何防御

其实让被加载的文件用户不可控,就能解决大部分问题,但这样往往在某些场景中不太容易做到。如果系统中存在任意文件写入的漏洞,即使限制了文件可控问题,也可以配合其提升成为任意代码执行。

过滤关键词?虽然也是个办法,但黑名单的方式总归的会被各种各样的骚操作 bypass。

如果要被反序列化的对象仅仅只需要里面的一些属性数据的话,可以使用 json 模块,这样就避免了不必要的不安全的反序列化操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值