行业新闻

恶意npm包的自动化挖掘方法

恶意npm包的自动化挖掘方法

0x01 Intro

Javascript流行已久,V8引擎更是让其进化为服务端开发语言的一员。其对应的包管理工具NPM中存在着大量的可重用软件包,体量巨大。社区的热度促进了NPM的发展,也促进了Node.js的发展。但在NPM中发布一个新的包只需要注册一个NPM账户即可,更新一个包的新版本也只需要简单地进行注册表上传同步。恶意包在近几年成为一大焦点问题,因为哪怕官方很快地发现并清除了这些恶意包,在注册表中存活很短一段时间最终也会影响到一大片终端用户。

要从根本上解决这个问题,无非是从两个方面:一是阻断这些恶意包被同步到注册表中,即严格执行审查机制,在这些恶意包从上传开始到实际被同步到注册表中的这段时间里进行检查并清理;二是执行访问控制来限制包的安装过程,缩小攻击面。作者则是考虑在不改变现有的NPM基本过程的情况下,尽可能快地检测出恶意包,然后清理。(题外话,读者认为如此重要的一大社区生态,为了提高整体安全性做出一些改变是值得好好考虑的。

作者为了验证其方法在实际情况下的有效性,提出了三个准则:

  • 自动化,不使用人工审查
  • 实时性,需要跟上版本更迭速度
  • 准确率,避免错误标记正常包或是遗漏恶意包

0x02 Method

作者提出了AMALFI来满足上述有效性准则:

  • 用标记数据进行机器学习分类器的训练,包括APIs特征和用轻量语义扫描获得的元数据
  • 使用源代码进行包的重构,并与其在注册表中发布的版本进行比较
  • 相似度检测器,用于对已知恶意包的检查

0x021 Feature set

单包特征包括:

  1. 获取终端用户个人敏感信息:账户、密码等
  2. 访问特定的一些系统资源
  3. 2.1. 文件操作:读取/写入
  4. 2.2. 进程创建:创建新进程
  5. 2.3. 网络请求:收发数据
  6. 使用特定的一些APIs
  7. 3.1. 加密功能
  8. 3.2. 数据编码
  9. 3.3. 动态代码生成
  10. 安装时运行脚本
  11. 短代码(避免检测)或二进制文件(可执行文件)

多版本特征包括:

  1. 版本发布的间隔时间
  2. 版本更新说明中描述的更新类型

需要说明的是,对于第一次上传到注册表中的包,作者引入了一个伪更新版本,设定版本发布之间的时间为0,更新类型则是单包特征中的描述。(题外话,作者并没有解释为何设定为0,读者存疑:难道不存在一个年久失修的包突然被攻击者接管的可能性么?

0x022 Feature extraction

作者使用Tree-sitter来解析包中的Javascript和Typescript文件以获取单包特征:对于特征1,字符串匹配;对于特征2和特征3,API匹配;对于特征4,调用eval和Function来生成代码;对于特征5,考虑Shannon熵值。对于多版本特征则是利用npm view time获取版本发布时间间隔;利用语义分析获取更新类型。(作者未在文中给出相关启发式规则,感兴趣可以进一步去代码中看。

0x023 Classifier trainning

据读者先前的研究,NPM删除的包是不存在缓存的,也就是说没有任何途径再从官方的源中下载到。作者的恶意包是找NPM索取的。在索要到的643个恶意包的基础上,作者增加了1147个同一日期发布的正常包,构成了一个总量为1790的带标签语料库(题外话,这个语料库的量对于在当时单版本就有170w个包的总数据量是否有些小了,但在这个领域样本差距也是无可奈何的

关闭