作者:知道创宇404实验室
2017年6月2日,Paper 收录了一篇 fate0 的《Package 钓鱼》 文章,该文章讲述了作者在 PyPI 上投放恶意的 Python 包钓鱼的过程。当用户由于种种原因安装这些恶意包时,其主机名、Python 语言版本、安装时间、用户名等信息会被发送到攻击者的服务器上。在钓鱼的后期,作者已经将 Github上的相关项目 中获取相应主机信息改成了提示用户安装恶意的 Python 包。
在收录该文之后,知道创宇404安全实验室对该文中所提到的攻击方式进行跟进、整理分析原作者公布的钓鱼数据。值得一提的是,在跟进的过程中,我们发现了新的钓鱼行为。在文第四章有相应的介绍。
相比于传统的钓鱼方式,上传恶意 Python 包,不通过邮件、网页等方式传播,用户很难有相关的防护意识。与此同时,由于 Pypi 源的全球性和 Python 语言的跨平台性,相关的恶意包可以在世界各国的任意操作系统上被执行。由于执行恶意包的多数是互联网从业人员,通过恶意的 Python 包钓鱼也具有一定的定向攻击性,在原作者公布的钓鱼数据中,疑似百度,滴滴,京东等相关互联网公司均有中招。试想通过如此方式进行针对全球的APT攻击,将无疑是一场灾难。
本文,就让我们聊一聊这个被隐藏的攻击面—— Python package 钓鱼。
Python 有两个著名的包管理工具 easy_install.py 和 pip 。这次我们的主角就是 pip 这个包管理工具。在 Python 语言中,需要安装第三方库时,通过命令 pip install package_name
就可以迅速安装。我们将该安装过程中的相关步骤简化成如下流程图:
可以看到,通过 pip 安装恶意的 smb 包时,最终将运行 setup.py 文件。由于任意 Python 开发者可以将自己的开发包上传至 Pypi 时,所以当上传的包名字被攻击者精心构造时,就可以达到钓鱼的目的。
例如前段时间的 samba 远程命令执行漏洞的 POC 中导入了如下包:
from smb.SMBConnection import SMBConnection
from smb import smb_structs
from smb.base import _PendingRequest
from smb.smb2_structs import *
from smb.base import *
经过查询,可以知道我们需要安装 pysmb 这个包就可以成功执行该 POC 。但是,很多安全研究人员会根据经验直接执行 pip install smb
,然而 smb 这个包却是原文作者上传的恶意程序包。所以当我们执行 pip install smb
命令后,主机的相关信息就会发送至攻击者的服务器。
原作者 fate0 还注意到一个细节,在平时使用过程中,一般通过命令 pip install –r requirements.txt
来安装整个项目的依赖文件。但是往往会错敲成 pip install requirements.txt
。
这就意味着,requirements.txt
也是一个好的恶意程序包名称。原作者据此进行研究,发现了一个上传限制绕过的方法。
在 https://github.com/pypa/pypi-legacy/blob/master/webui.py 中有如下代码段
我们可以看到 PyPI 直接硬编码这些文件名禁止用户上传同名文件。
而当用户利用 pip 安装 Python 包,PyPI 在查询数据库时会对文件名做以下正则处理 https://github.com/pypa/warehouse/blob/master/warehouse/migrations/versions/3af8d0006ba_normalize_runs_of_characters_to_a_.py
这意味者以下方式安装的将会是同一个包
基于这点,我们可以绕过 requirements.txt
等一系列包被硬编码而无法上传的限制。
PyPI 官方已对该漏洞做出回应:https://github.com/pypa/pypi-legacy/issues/644
截止发文,官方尚未发布针对该漏洞的补丁。
根据 fate0 公开的钓鱼数据,我们根据 country, language, package, username 这几个关键字来进行数据汇总,得到如下排名:
受影响国家 TOP 10:
Python版本分布排名:
恶意包命中排名:
以root权限安装的恶意包排名
主机用户排名:
由上述数据可以看到,美国、中国、印度等国家纷纷中招,美国受到的影响最为严重,其次是中国及印度等国家,这也从一定程度上,反映了各个国家的互联网发展水平。
从 Python 的版本分布上我们可以看到绝大多数用户都在使用 2.7、3.5、3.6 等版本,具体的来说, python2 占比 48%, python3 占比 52%。这也从侧面反映出, python3 已经开始逐渐普及。
恶意包命中率最高的为 opencv、tkinter 等流行的软件,可见很多用户在安装软件包之前,没有养成检查的良好习惯,最终被钓鱼。
同时绝大多数用户是以最高权限 root 直接运行安装命令,一旦遭受钓鱼攻击,用户隐私和服务器安全将无法保障。
对这批数据的 hostname 字段进行深入分析,我们发现此次钓鱼事件中,以下公司企业、学校、政府可能受到影响。(理论上 hostname 可修改,以下结果仅供参考)
公司、企业、组织等:
学校
政府单位
受影响的中国公司
值得一提的是,以下 2017 年全球 500 强企业在此次钓鱼中可能也受到影响,如下:
根据 hostname 字段和 username 字段的信息对操作系统进行粗略估计,我们发现中招的系统包括:Linux、Mac、Windows、RaspberryPi 等,其中以 Mac、Linux 居多。显然,Python 的跨平台性决定了这种钓鱼攻击也是跨平台的。
可识别的系统分布如下:
我们还发现以下IP多次中招:
经过进一步分析,我们发现部分重复中招IP的 hostname 都相同且均符合 docker hostname 特征,同时操作权限均为 root,我们怀疑这可能是安全研究人员在借助 docker 环境对钓鱼后续行为进行跟踪分析。
在对 python package 钓鱼进行持续跟进时,有人恶意的在 PyPI 上提交了 zoomeye-dev 的 Python 安装包, 截图如下:
根据前期的分析,轻车熟路地找到关键恶意代码所在:
可以看到,当用户误安装 zoomeye_dev 这个包时,会被收集操作系统名称,主机名,用户名,Python 语言版本等系统并发送至指定地址,同时返回一个 callback 地址,如果 callback 地址非空,将从这个地址下载文件并执行。在实际的测试过程中,该 callback 地址并未返回具体内容。如果钓鱼者怀有恶意的目的,而同时我们还以最高权限 root 安装了这个恶意的包,那恶意程序就已经在我们的电脑中畅行无阻了!
目前,该恶意程序包已经被删除,从该恶意程序包被上传至 Pypi 源到被发现被删除,仅仅用时两个小时。但我们无法想象,非互联网安全公司发现自己公司的相关恶意程序包被上传到 Pypi 源上会需要多久。也许,到最终被发现的时候,已经造成了巨大的损失。
Package 钓鱼巧妙利用了用户误操作的不可避免性以及开源仓库的松散审查,并利用流行软件名称来扩大钓鱼范围,往往这种思路的攻击比一般漏洞危害更大。就比如说这次钓鱼事件中 Google、Amazon 等网络巨头也纷纷中招,它们的安全防护能力肯定是毋庸置疑的,但谁能想到问题出在开源仓库,开源仓库一旦被污染,那么后果将是可怕的,举个例子,如果上述那个 callback 真的非空,那么渗透企业内网也并非什么难事。
仅仅是针对 Python 开源仓库平台进行钓鱼的一次尝试,影响就已经如此广泛。试想再结合Ruby等也面临着同样问题的语言,将会再次扩大潜在的攻击范围。甚至于如果公开的镜像源平台被攻陷,正常的第三方库被替换成恶意的程序包,那么通过该镜像源安装程序的主机都会受到影响。
我们可以想象如果利用其他攻击面,比如说针对开源组件的开发者进行攻击,从而控制相关开源组件代码,并在开发者未察觉的情况下长期潜伏,最终发起全球 APT 攻击,我们该如何防御?
当今世界,各种开源的软件、工具无处不在,我们在享受着自由软件所提供的便利时,是否考虑过它们的安全性?
开源本身极大的促进了信息时代的发展,但若是缺乏有效审查的开源,被不怀好意的人拿来作恶,那么杀伤力将是无法想象的。
为了世界更安全,我们一直在努力,但同时用户的安全意识才是重中之重!
[1] seebug收录的《package钓鱼》一文
http://paper.seebug.org/311/
[2] package钓鱼原文
http://blog.fatezero.org/2017/06/01/package-fishing/
[3] fate0公开的钓鱼数据
http://evilpackage.fatezero.org/
[4] Typosquatting in Programming Language Package Managers
http://incolumitas.com/data/thesis.pdf
[5] cookiecutter-evilpy-package
https://github.com/fate0/cookiecutter-evilpy-package
致谢:
感谢fate0在《package钓鱼》一文中以“恶意者”视角为我们带来的精彩尝试以及在http://evilpackage.fatezero.org/上公开的钓鱼数据,让我们意识到随意安装Python包潜在的危害性。同时也感谢全体404实验室的小伙伴在本篇报告完成中的无私帮助。谢谢。