RSS Feed
更好更安全的互联网

被忽视的攻击面:Python package 钓鱼

2017-06-15

作者:**知道创宇404实验室**

####一.概述
2017年6月2日,[Paper](http://paper.seebug.org/) 收录了一篇 fate0 的[《Package 钓鱼》](http://paper.seebug.org/311/) 文章,该文章讲述了作者在 PyPI 上投放恶意的 Python 包钓鱼的过程。当用户由于种种原因安装这些恶意包时,其主机名、Python 语言版本、安装时间、用户名等信息会被发送到攻击者的服务器上。在钓鱼的后期,作者已经将 [Github上的相关项目](https://github.com/fate0/cookiecutter-evilpy-package) 中获取相应主机信息改成了提示用户安装恶意的 Python 包。

在收录该文之后,知道创宇404安全实验室对该文中所提到的攻击方式进行跟进、整理分析原作者公布的钓鱼数据。值得一提的是,在跟进的过程中,我们发现了新的钓鱼行为。在文第四章有相应的介绍。

相比于传统的钓鱼方式,上传恶意 Python 包,不通过邮件、网页等方式传播,用户很难有相关的防护意识。与此同时,由于 Pypi 源的全球性和 Python 语言的跨平台性,相关的恶意包可以在世界各国的任意操作系统上被执行。由于执行恶意包的多数是互联网从业人员,通过恶意的 Python 包钓鱼也具有一定的定向攻击性,在原作者公布的钓鱼数据中,疑似百度,滴滴,京东等相关互联网公司均有中招。试想通过如此方式进行针对全球的APT攻击,将无疑是一场灾难。

本文,就让我们聊一聊这个被隐藏的攻击面—— Python package 钓鱼。

####二.Python package钓鱼简析

######2.1 Python package钓鱼方式

Python 有两个著名的包管理工具 easy_install.py 和 pip 。这次我们的主角就是 pip 这个包管理工具。在 Python 语言中,需要安装第三方库时,通过命令 pip install package_name 就可以迅速安装。我们将该安装过程中的相关步骤简化成如下流程图:

![](https://images.seebug.org/content/images/2017/06/1-2.png-w331s)

可以看到,通过 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 命令后,主机的相关信息就会发送至攻击者的服务器。

######2.2 Pypi 上传限制绕过
原作者 fate0 还注意到一个细节,在平时使用过程中,一般通过命令 pip install –r requirements.txt 来安装整个项目的依赖文件。但是往往会错敲成 pip install requirements.txt

这就意味着,requirements.txt 也是一个好的恶意程序包名称。原作者据此进行研究,发现了一个上传限制绕过的方法。

在 https://github.com/pypa/pypi-legacy/blob/master/webui.py 中有如下代码段

![](https://images.seebug.org/content/images/2017/06/--1-1.png-w331s)

我们可以看到 PyPI 直接硬编码这些文件名禁止用户上传同名文件。

而当用户利用 pip 安装 Python 包,PyPI 在查询数据库时会对文件名做以下正则处理
https://github.com/pypa/warehouse/blob/master/warehouse/migrations/versions/3af8d0006ba\_normalize\_runs\_of\_characters\_to\_a\_.py

![](https://images.seebug.org/content/images/2017/06/--2-1.png-w331s)

这意味者以下方式安装的将会是同一个包

![](https://images.seebug.org/content/images/2017/06/--3-1.png-w331s)

基于这点,我们可以绕过 requirements.txt 等一系列包被硬编码而无法上传的限制。

PyPI 官方已对该漏洞做出回应:https://github.com/pypa/pypi-legacy/issues/644

![](https://images.seebug.org/content/images/2017/06/--4-1.png-w331s)

截止发文,官方尚未发布针对该漏洞的补丁。

####三.钓鱼数据分析
根据 fate0 公开的钓鱼数据,我们根据 country, language, package, username 这几个关键字来进行数据汇总,得到如下排名:

* 受影响国家 TOP 10:
![](https://images.seebug.org/content/images/2017/06/--5-1.png-w331s)

* Python版本分布排名:
![](https://images.seebug.org/content/images/2017/06/--6-1.png-w331s)

* 恶意包命中排名:
![](https://images.seebug.org/content/images/2017/06/--7-1.png-w331s)

* 以root权限安装的恶意包排名
![](https://images.seebug.org/content/images/2017/06/--8-1.png-w331s)

* 主机用户排名:
![](https://images.seebug.org/content/images/2017/06/--9-1.png-w331s)

由上述数据可以看到,美国、中国、印度等国家纷纷中招,美国受到的影响最为严重,其次是中国及印度等国家,这也从一定程度上,反映了各个国家的互联网发展水平。

从 Python 的版本分布上我们可以看到绝大多数用户都在使用 2.7、3.5、3.6 等版本,具体的来说, python2 占比 48%, python3 占比 52%。这也从侧面反映出, python3 已经开始逐渐普及。

恶意包命中率最高的为 opencv、tkinter 等流行的软件,可见很多用户在安装软件包之前,没有养成检查的良好习惯,最终被钓鱼。

同时绝大多数用户是以最高权限 root 直接运行安装命令,一旦遭受钓鱼攻击,用户隐私和服务器安全将无法保障。

对这批数据的 hostname 字段进行深入分析,我们发现此次钓鱼事件中,以下公司企业、学校、政府可能受到影响。(理论上 hostname 可修改,以下结果仅供参考)

* 公司、企业、组织等:
![](https://images.seebug.org/content/images/2017/06/----_20170614151125.png-w331s)
![](https://images.seebug.org/content/images/2017/06/----_20170614151150.png-w331s)
![](https://images.seebug.org/content/images/2017/06/----_20170614151233.png-w331s)

* 学校
![](https://images.seebug.org/content/images/2017/06/----_20170614152133-1.png-w331s)

* 政府单位
![](https://images.seebug.org/content/images/2017/06/----_20170614152509.png-w331s)

* 受影响的中国公司
![](https://images.seebug.org/content/images/2017/06/----_20170614152648.png-w331s)

* 值得一提的是,以下 2017 年全球 500 强企业在此次钓鱼中可能也受到影响,如下:
![](https://images.seebug.org/content/images/2017/06/----_20170614152858.png-w331s)

根据 hostname 字段和 username 字段的信息对操作系统进行粗略估计,我们发现中招的系统包括:Linux、Mac、Windows、RaspberryPi 等,其中以 Mac、Linux 居多。显然,Python 的跨平台性决定了这种钓鱼攻击也是跨平台的。

可识别的系统分布如下:
![](https://images.seebug.org/content/images/2017/06/--10-1.png-w331s)

我们还发现以下IP多次中招:
![](https://images.seebug.org/content/images/2017/06/--11-1.png-w331s)

经过进一步分析,我们发现部分重复中招IP的 hostname 都相同且均符合 docker hostname 特征,同时操作权限均为 root,我们怀疑这可能是安全研究人员在借助 docker 环境对钓鱼后续行为进行跟踪分析。

####四.后续钓鱼事件
在对 python package 钓鱼进行持续跟进时,有人恶意的在 PyPI 上提交了 zoomeye-dev 的 Python 安装包, 截图如下:
![](https://images.seebug.org/content/images/2017/06/--12-1.png-w331s)

根据前期的分析,轻车熟路地找到关键恶意代码所在:

![](https://images.seebug.org/content/images/2017/06/--13-2.png-w331s)

可以看到,当用户误安装 zoomeye_dev 这个包时,会被收集操作系统名称,主机名,用户名,Python 语言版本等系统并发送至指定地址,同时返回一个 callback 地址,如果 callback 地址非空,将从这个地址下载文件并执行。在实际的测试过程中,该 callback 地址并未返回具体内容。如果钓鱼者怀有恶意的目的,而同时我们还以最高权限 root 安装了这个恶意的包,那恶意程序就已经在我们的电脑中畅行无阻了!

目前,该恶意程序包已经被删除,从该恶意程序包被上传至 Pypi 源到被发现被删除,仅仅用时两个小时。但我们无法想象,非互联网安全公司发现自己公司的相关恶意程序包被上传到 Pypi 源上会需要多久。也许,到最终被发现的时候,已经造成了巨大的损失。

####五.小结

Package 钓鱼巧妙利用了用户误操作的不可避免性以及开源仓库的松散审查,并利用流行软件名称来扩大钓鱼范围,往往这种思路的攻击比一般漏洞危害更大。就比如说这次钓鱼事件中 Google、Amazon 等网络巨头也纷纷中招,它们的安全防护能力肯定是毋庸置疑的,但谁能想到问题出在开源仓库,开源仓库一旦被污染,那么后果将是可怕的,举个例子,如果上述那个 callback 真的非空,那么渗透企业内网也并非什么难事。

仅仅是针对 Python 开源仓库平台进行钓鱼的一次尝试,影响就已经如此广泛。试想再结合Ruby等也面临着同样问题的语言,将会再次扩大潜在的攻击范围。甚至于如果公开的镜像源平台被攻陷,正常的第三方库被替换成恶意的程序包,那么通过该镜像源安装程序的主机都会受到影响。

我们可以想象如果利用其他攻击面,比如说针对开源组件的开发者进行攻击,从而控制相关开源组件代码,并在开发者未察觉的情况下长期潜伏,最终发起全球 APT 攻击,我们该如何防御?

当今世界,各种开源的软件、工具无处不在,我们在享受着自由软件所提供的便利时,是否考虑过它们的安全性?

开源本身极大的促进了信息时代的发展,但若是缺乏有效审查的开源,被不怀好意的人拿来作恶,那么杀伤力将是无法想象的。

为了世界更安全,我们一直在努力,但同时用户的安全意识才是重中之重!

####六.参考链接

[1] seebug收录的《package钓鱼》一文
[http://paper.seebug.org/311/](http://paper.seebug.org/311/)
[2] package钓鱼原文
[http://blog.fatezero.org/2017/06/01/package-fishing/](http://blog.fatezero.org/2017/06/01/package-fishing/)
[3] fate0公开的钓鱼数据
[http://evilpackage.fatezero.org/](http://evilpackage.fatezero.org/)
[4] Typosquatting in Programming Language Package Managers
[http://incolumitas.com/data/thesis.pdf](http://incolumitas.com/data/thesis.pdf)
[5] cookiecutter-evilpy-package
[https://github.com/fate0/cookiecutter-evilpy-package](https://github.com/fate0/cookiecutter-evilpy-package)

**致谢:**
感谢fate0在《package钓鱼》一文中以“恶意者”视角为我们带来的精彩尝试以及在[http://evilpackage.fatezero.org/](http://evilpackage.fatezero.org/)上公开的钓鱼数据,让我们意识到随意安装Python包潜在的危害性。同时也感谢全体404实验室的小伙伴在本篇报告完成中的无私帮助。谢谢。

作者:dawu | Categories:安全研究技术分享 | Tags:

发表评论