Python代码审计实战案例总结之反序列化和命令执行
字数 1985 2025-08-15 21:30:31
Python代码审计实战:反序列化与命令执行漏洞详解
一、反序列化漏洞审计
1.1 Python反序列化模块概述
Python中常见的反序列化模块包括:
pickle/cPickle:Python原生序列化模块yaml:YAML格式处理模块json:JSON格式处理模块(相对安全)
其中pickle和yaml是最常出现安全问题的模块。
1.2 反序列化漏洞原理
反序列化漏洞的核心在于:当程序从不可信源加载序列化数据时,攻击者可以构造恶意序列化数据,在反序列化过程中执行任意代码。
危险方法:
pickle.load()/pickle.loads()yaml.load()/yaml.loads()
安全替代方法:
pickle:无完全安全的替代方案,应避免反序列化不可信数据yaml:使用yaml.safe_load()替代yaml.load()json:使用json.loads()
1.3 实战案例1:dask反序列化漏洞(CNVD-2019-16789)
漏洞分析:
- 影响版本:dask 1.1.4
- 漏洞文件:
config.py - 关键代码位置:第139行
collect_yaml方法 - 漏洞触发点:第168行
yaml.load()调用
漏洞利用条件:
- 程序从可控的YAML文件加载配置
- 使用了不安全的
yaml.load()而非yaml.safe_load()
修复方案:
将yaml.load()替换为yaml.safe_load()
1.4 实战案例2:NumPy命令执行漏洞(CVE-2019-6446)
漏洞分析:
- 影响版本:NumPy < 1.16.0
- 漏洞文件:
lib/npyio.py - 关键参数:
allow_pickle=True(默认值) - 漏洞触发流程:
NumPy.lib.npyio.py:load()pickle.py:load()
漏洞利用条件:
- 加载的文件不是有效的NumPy二进制文件或ZIP文件
allow_pickle参数为True(默认值)
POC示例:
from numpy.lib import npyio
import os
import pickle
class Test(object):
def __reduce__(self):
return (os.system, ('whoami',))
tmpdaa = Test()
with open("test-file.pickle", 'wb') as f:
pickle.dump(tmpdaa, f)
npyio.load("test-file.pickle")
修复方案:
- 升级NumPy到1.16.0及以上版本
- 调用
load()时设置allow_pickle=False
二、命令执行漏洞审计
2.1 常见危险函数
Python中可能导致命令执行的函数:
os.system()os.popen()subprocess.Popen()commands.getoutput()(Python 2)eval()exec()
2.2 审计要点
- 查找上述危险函数的调用
- 检查参数是否可控
- 检查是否有适当的过滤和验证
2.3 实战案例1:numexpr命令执行漏洞(CNVD-2019-17298)
漏洞分析:
- 漏洞文件:
numexpr/cpuinfo.py - 关键代码位置:第37行
getoutput方法 - 平台限制:仅Linux系统可利用
- 触发条件:
os.WIFEXITED(status)为Trueos.WEXITSTATUS(status)在successful_status中
漏洞原理:
通过控制successful_status参数,可以绕过安全检查执行任意命令。
2.4 实战案例2:dotenv命令执行漏洞(CNVD-2019-17299)
漏洞分析:
- 影响版本:dotenv 0.10.1
- 漏洞文件:
main.py - 关键代码位置:第317行
- 漏洞原因:未对命令参数进行过滤
漏洞利用条件:
- 能够控制传入的环境变量或命令参数
三、防御方案
3.1 反序列化漏洞防御
- 避免反序列化不可信数据
- 使用安全的替代方法:
yaml.safe_load()替代yaml.load()json.loads()替代pickle.loads()
- 对序列化数据进行签名验证
3.2 命令执行漏洞防御
- 避免使用危险函数
- 使用安全的替代方法:
subprocess.run()替代os.system()
- 对用户输入进行严格过滤和验证
- 使用白名单机制限制可执行命令
四、审计方法论
4.1 审计流程
- 识别危险模块和函数
- 跟踪用户输入流向
- 检查安全控制措施
- 验证漏洞可利用性
4.2 工具推荐
- 静态分析工具:
- Bandit
- PyLint
- Safety
- 动态分析工具:
- 交互式调试器
- 请求拦截代理
4.3 重点关注
- 反序列化操作
- 系统命令执行
- 文件操作
- 数据库操作
- 模板渲染
五、总结
Python代码审计需要重点关注:
- 反序列化操作(pickle/yaml)
- 命令执行函数调用
- 用户输入流向
- 平台特性差异
通过案例学习可以积累审计经验,提高发现漏洞的效率。在实际审计中,应结合静态分析和动态验证,全面评估代码安全性。