一、 背景介绍
许多现代网络应用依靠解释型编程语言,因为它们有丰富的库和包。像PyPI、Npm和RubyGems这样包管理器提供了一个集中的仓库,开发者可以搜索和安装代码包,以帮助开发。包管理器不仅使开发过程更加有效,而且还创建了一个大型社区,进行合作和分享开源代码。不幸的是,攻击者已经找到方法渗透到这些社区,用恶意代码感染良性的流行软件包,窃取凭证,安装后门,甚至滥用计算资源进行加密货币挖掘。
这个问题的影响不仅局限于小型个人网络应用程序,而且还涉及到大型的网站、企业,甚至是依赖于开源解释型编程语言进行内部和外部应用程序开发的政府机构。攻击者可以通过向这些包管理器投毒恶意包,制造软件供应链攻击来渗透到一些防御良好的组织中。例如,在NPM中,eslint-scope是一个每周下载量达数百万的软件包,被攻击者篡改以窃取开发者的凭证。同样地,在RubyGems中,rest-client已经被下载了超过一亿次,被攻击者篡改以在Web服务器上留下了一个远程代码执行(RCE)后门。这些攻击行为悄无声息,用户极难发现。
考虑到包管理器投毒攻击的巨大影响,学术界和工业界也提出了多种恶意包检测的方法。但是现有方法的误报很高,数量巨大的待审核的可疑包无法处理,导致方法无法真正投入使用。例如PyPI官方在2020年推出的检测工具PyPI malware checks就在上线两年后由于未能达到预期效果被撤销。
二、 攻击方法
由于第三方库开发和管理涉及到众多的环节,而且规则较为灵活,容易被攻击的角度有很多,主要分为上游和下游两类,分别对应着攻击中央仓库和攻击用户。有的攻击者目标是安装第三方库的使用者,他们上传大量有害的第三方库。用户在安装的过程中执行命令盗取用户信息,或者是从远程下载恶意软件植入后门,开启挖矿进程占用资源。部分攻击者更是将目标直接瞄准了中央管理仓库,PyPI就曾被爆出存在远程代码执行的漏洞,如果管理仓库被控制,攻击者可以随意修改包中的代码,后果不堪设想。也有攻击者对中央仓库进行DDos攻击,造成服务瘫痪。常见的攻击方式有以下几种:
错别字劫持(typosquatting):在PyPI/NPM等代码管理仓库中 typosquatting攻击是一种常见的攻击方式。攻击者会注册一个与目标软件包名称相似但存在拼写错误的软件包名称,然后上传一个恶意软件包到这个软件包名称下,使得用户在安装软件包时误输入错误的软件包名称,从而下载并安装恶意软件包。比如,假设一个开发者想要下载名为"requests"的Python软件包,但是他因为疏忽打错了一个字母,将软件包名称误输为"reqeusts",而攻击者正好注册了这个名称的软件包并上传了一个恶意的软件包到其中。当这个开发者使用pip安装这个软件包时,他实际上下载并安装了攻击者上传的恶意软件包。typosquatting攻击可以利用用户的拼写错误和疏忽大意,骗取用户下载恶意软件包,从而对用户的电脑和数据造成危害。
依赖混淆(dependency confusion):依赖性混淆攻击发生在从公共包管理器而不是预定的私有/内部包管理器下载依赖性库,因为恶意攻击者可以欺骗软件包管理从他控制的公共仓库下载恶意软件包。攻击者利用了开发者在使用多个软件库时的依赖管理机制,例如在使用Python的pip包管理器时,pip会首先查找本地环境中已经安装的软件包,若没有找到则会去公共的Python软件包仓库PyPI中寻找。攻击者通过上传一个与公共Python软件包仓库中同名但版本号更高的恶意软件包到一个私有的软件仓库,就能够欺骗pip去下载该恶意软件包,而不是从公共的Python软件包仓库中下载。
账户劫持(account hijacking):由于开源项目的合作性质,攻击者很容易猜测到管理者账户的薄弱身份凭证或者是通过社会工程学获得账户的管理权,并在管理的项目中插入恶意代码进行攻击。在最近发生的管理器投毒事件中,这类情况频频发生。目前包管理器的维护者们已经注意到了这个问题,主动实施了一些安全改进措施,例如软件包签名和双因素认真(2FA)等。
三、 防御方法
考虑到整个第三方库供应链可以攻击的环节很多,防御检测的角度也有很多。因为我们无法参与中央仓库的管理,这里我们只考虑下游的防护,即作为第三方库的使用者如何检测出危险的库,防止受到伤害。
在检测思路上,第三方库和其他软件的不同之处在于会提供有关的基本信息,如开发者姓名,邮箱,源码地址等等。可以将这些基本信息纳入检测的范围之内,因为正常的开发者会留下尽可能全面的信息方便后续的沟通,恶意攻击者上传的库往往缺乏这些基本信息,或者是随意填写虚假的姓名,邮箱。一些基本信息中带有anonymous,hacker等词的几乎可以直接判定为恶意包。
攻击者为了以假乱真,会使用正常开发者的信息迷惑检测。附上正常项目的代码仓库和star数,其实用户实际下载的代码和仓库中的完全不同。可以通过检测仓库名和下载的包名是否一致,开发者的名称是否一致,包中的代码和仓库中的是否一致进行判断。对于在安装过程中提供可执行程序的包,可以从仓库中的源码构建可执行程序,将两者进行比较。攻击者可能提供和开源代码完全不同的恶意可执行程序供下载。
除了通过基本信息进行大致的筛选和辅助判断,还可以使用静态分析的方式。构建控制流图对敏感的api进行提取。因为在危险的第三方库中,攻击者为了隐藏痕迹或者是获得窃取的敏感数据,会使用网络相关的api下载木马程序或上传信息,如python中的requests。还有加密相关的api,用来加密攻击代码不易被关键词检测发现。还有对于文件的读写操作也很值得注意,很多攻击是将危险代码下载写入本地文件中,或是从本地的机密文件中读取用户信息密码等敏感信息。可以使用污点分析的方式,判断是否有进行过滤,是否存在敏感信息泄露,危险代码下载的情况。
静态分析的检测方式速度会比较快,但是检测效果并不能很理想。因为静态检测会产生大量的假阳性的情况,而且很多精心设计的有害包并不能发现。例如,有的攻击者除了发布有害包,还会发布新的包依赖有害包,在新发布的这些包中并没有使用任何的危险代码。但是在安装的过程中还是完成了攻击者预想的攻击操作。为了避免这种情况,动态检测是必要的。可以使用沙箱,防止有害的包造成实际的破坏。有害包为了攻击能够真正被执行,攻击者往往会将有害代码写入安装的环节,而不是在实际调用的过程中执行。所以需要在沙箱环境中执行安装的环节,通过工具检测安装过程中执行的系统调用进行判断是否有有害行为的执行。安装完成后,比较安装后的环境和初始环境的差别是否有除了包文件以外的文件写入。重点关注这些写入的文件,有一些是代码运行所必须的代码配置或是证书,有一些则是危险代码和事先编写好的后门程序。对这些文件使用常用的方式进行扫描可以有效检测出有害包。
除了这些传统的检测方式,还可以采用机器学习的方法。提取包的关键特征进行分类学习。采集的特征包括发布者的信息是否完善,网络、加密、文件读写相关api的数量,动态执行代码的数量等等。
四、 总结与展望
包的中央管理仓库管理十分松散,影响的范围又极其广泛,安全保护十分重要。需要定期对包进行安全扫描,去除有害包。先通过基本信息进行初步筛查,然后使用静态分析的方法辅助扫描,动态分析最终确定是否有害。除了这种方法,现代的机器学习也可以提供帮助进行分类,但是缺乏足够的数据集进行训练是现在面对的一大难题。
我们作为开发者,同时也是第三方库的使用者。尽管我们无法控制上游的软件包,但可以遵循最佳策略来补救安全问题。开发者可以用已知安全的版本,以避免来自上游的供应链攻击。还应该定期检查安全公告并及时更新以避免已知的漏洞。对于不受信任的包,开发人员可以手动检查,部署一个审查管道来检查代码,并在运行时将其隔离,以避免潜在的危险。
参考文献
[1] Duan R, Alrawi O, Kasturi R P, et al. Towards measuring supply chain attacks on package managers for interpreted languages[J]. arXiv preprint arXiv:2002.01139, 2020.
[2] Sejfia A, Schäfer M. Practical automated detection of malicious npm packages[C]//Proceedings of the 44th International Conference on Software Engineering. 2022: 1681-1692.
[3] Vu D L, Pashchenko I, Massacci F, et al. Typosquatting and combosquatting attacks on the python ecosystem[C]//2020 ieee european symposium on security and privacy workshops (euros&pw). IEEE, 2020: 509-514.
[4] Zimmermann M, Staicu C A, Tenny C, et al. Small World with High Risks: A Study of Security Threats in the npm Ecosystem[C]//USENIX security symposium. 2019, 17.
[5] Ladisa P, Plate H, Martinez M, et al. Taxonomy of attacks on open-source software supply chains[J]. arXiv preprint arXiv:2204.04008, 2022.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。