案例分析:NPM中恶意包利用环境变量差异绕过检测

2022年7月14日,OSCS 监测发现NPM仓库中上传了 branch-node-core、epic-ue-loading 两个恶意组件包,出自相同的模板,通过多种方式绕过静态、动态检测机制。

OSCS
OSCS   Follow

# 一、事件简述

2022年7月14日,OSCS 监测发现NPM仓库中上传了 branch-node-core、epic-ue-loading 两个恶意组件包,出自相同的模板,通过多种方式绕过静态、动态检测机制。

由于发现这些恶意组件包在不同环境中的运行结果并不相同,我们对代码进行了分析,发现这些恶意组件包会检测用户运行环境的特征,根据特征判断是否进入恶意逻辑。

接下来我们以 branch-node-core为例,分析其中尝试绕过代码静态分析和运行时动态检测的手法,希望能帮助安全研究人员和开发者关注此类风险,更加了解其中的绕过手法。

# 二、详细分析

如下图package.json所示,branch-node-core只会在安装和构建时使用node build-utils/update-library.js调用恶意代码

img

branch-node-core/package.json

攻击者首先在update-library.js 中定义了一个名为filter的列表,filter列表中的元素使用join来生成字符串,例如将["mirrors", "tencent", "com"]转为mirrors.tencent.com

join是为了尝试绕过静态检测对代码中特殊字符串的分析,其中存放着攻击者用来判断是否开启投毒的环境信息元素。

img

branch-node-core/build-utils/update-library.js中filter 列表代码片段

代码随后对环境信息进行了判断,在data中传入了环境变量,然后一共判断了6个条件,这些条件使用||连接,任一条件的返回值为 true ,将不会去调用var req = http.request 执行恶意代码。

img

判断环境信息的表达式

# 1.判断环境变量内容

表达式的第一个条件:判断运行环境内的环境变量是否符合目标真实服务器的环境变量模板,

  • some() 方法用于检测数组中的元素是否满足指定条件(通过将元素传入匿名函数来判断条件),当匿名函数返回值为true则停止继续运行,直接返回true

  • every() 方法用于检测数组所有元素是否都符合指定条件(通过将元素传入匿名函数来判断条件),当匿名函数返回值为false则停止继续运行,直接返回false

攻击者通过结合some和every方法来将环境变量data与filter列表内的每一个元素进行比对,如果环境变量data完全包含filter的中的任一元素,则返回 true。

例如如果环境变量中包含npm_config_registry=``registry.npmmirror.com,则表达式返回true,不会执行恶意代码

img

# 2.判断环境变量数量

表达式的第二个条件:判断本机系统的环境变量的个数是否大于 10 个

一般真实服务器的环境数量都大于10,攻击者借此判断是否为沙箱环境,若本机环境变量的个数不满足 10 个,那么第二个条件就会返回true,不会执行恶意代码。

img

# 3.判断当前目录

表达式的第三个条件:判断当前路径是否为用户默认的npm包存放路径

img

判断当前目录

# 4.判断是否有流量分析

表达式的第四个条件:判断环境信息内是否存在**mitmproxy**代理劫持工具进行流量分析

img

判断是否存在代理

# 5.判断NPM包名是否存在

表达式的第五和第六个条件:会去判断环境信息中是否存在 NPM的包名与版本

img

判断NPM包名是否存在

if判断的表达式均为false时,接下来会通过http方法试图请求 eo1ew7v449gkbah.m.pipedream.net 域名,将环境变量中的敏感数据发送给恶意域名

img

传输敏感数据

# 三、总结

目前branch-node-core和epic-ue-loading的下载数量分别为532,318,OSCS推测有用户可能已经安装了恶意组件。

img

img

通过分析branch-node-core我们可以发现其使用的多种绕过检测方式,类似这样的情况可能还有很多,对抗也会持续。对企业安全团队来说,需要持续提升风险检测防范能力;对于开发者而言,在引入项目依赖时需要注意甄别。