作者:知道创宇404实验室

一.概述

2017年6月2日,Paper 收录了一篇 fate0 的《Package 钓鱼》 文章,该文章讲述了作者在 PyPI 上投放恶意的 Python 包钓鱼的过程。当用户由于种种原因安装这些恶意包时,其主机名、Python 语言版本、安装时间、用户名等信息会被发送到攻击者的服务器上。在钓鱼的后期,作者已经将 Github上的相关项目 中获取相应主机信息改成了提示用户安装恶意的 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 就可以迅速安装。我们将该安装过程中的相关步骤简化成如下流程图:

可以看到,通过 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 中有如下代码段

我们可以看到 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实验室的小伙伴在本篇报告完成中的无私帮助。谢谢。


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:http://paper.seebug.org/326/