哔哔两句
from sklearn.externals import joblib
.pkl的文件,我认为它是 PicK Le 的缩写,经过资料查询也证明了这个猜想。
.pkl的文件,这让我很好奇,问了几个朋友也没有认识这个模块的,谷歌也没找出关于这个模块的漏洞文章,python 反序列化漏洞都是在讲 pickle、cPickle 和 PyYaml 的。

结论是当然可以,对比生成后的反序列化字节码和跟踪 joblib.load() 函数发现其实他就是封装了 pickle。
而这个 sklearn 其实是一个用于机器学习的库,一般在大型项目中或者有关机器学习的项目中能找到,所以大家以后在白盒审计 python 项目时除了 pickle 和 cPickle 以外还可以注意一下 sklearn 的 joblib 模块。
举一反三
NumPy (21,219 commits / 11,711 star)
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
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:53import numpynumpy.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:53import pandaspandas.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:53import torchtorch.load("blue.pkl")

CheckList
以下例举几个在 python 代码审计时针对反序列化漏洞的检查点。
CheckPoint 1
import picklepickle.load(open("blue.pkl","rb"))with open("blue.pkl","rb") as d:pickle.loads(d.read())
CheckPoint 2
import cPicklecPickle.load(open("blue.pkl","rb"))with open("blue.pkl","rb") as d:cPickle.loads(d.read())
CheckPoint 3
import _pickle_pickle.load(open("blue.pkl","rb"))with open("blue.pkl","rb") as d:_pickle.loads(d.read())
CheckPoint 4
from sklearn.externals import joblibjoblib.load("blue.pkl")
CheckPoint 5
from pickle import UnpicklerUnpickler(open("blue.pkl","rb")).load()
CheckPoint 6
import numpynumpy.load("blue.pkl",allow_pickle=True )with open("blue.pkl","rb") as d:numpy.loads(d.read())
CheckPoint 7
import pandaspandas.read_pickle("blue.pkl")
CheckPoint 8
import torchtorch.load("blue.pkl")




