Shai-Hulud蠕虫攻击:npm供应链的重大威胁

引言

在开源软件生态系统中,Node Package Manager (npm) 是开发者依赖管理的核心工具。然而,最近发生的一起复杂供应链攻击事件揭示了这一生态系统的脆弱性。攻击者通过一个名为“Shai-Hulud”的自复制蠕虫,感染了超过500个npm包,窃取了开发者的敏感凭据,并实现了自动传播。这一事件不仅影响了众多开发者,还对全球组织的软件供应链安全构成了严重威胁。

20250917211801429-图片

攻击背景

这一攻击可能源于8月底的一次先前妥协事件,显示出攻击者对npm生态系统的长期渗透。Shai-Hulud蠕虫的出现标志着供应链攻击技术的一次显著进化。它不再依赖人工干预,而是具备自主复制和传播的能力,利用合法工具窃取凭据,并在受感染的开发者机器上扩展影响。安全研究人员发现,这一蠕虫的目标直指开发者的核心资产,包括npm和GitHub令牌以及云服务密钥。

Shai-Hulud蠕虫的描述

Shai-Hulud是一种高度复杂的蠕虫式恶意软件,其名称源自科幻小说《沙丘》中的巨型沙虫,象征其吞噬一切的破坏力。该蠕虫的主要功能包括:

    • 凭据窃取:利用合法的秘密扫描工具,从开发者的机器中提取敏感信息,如npm凭据、API密钥、数据库密码、私钥以及项目环境文件中的其他秘密。

    • 数据泄露:窃取的凭据被上传到公开可访问的GitHub存储库中,便于攻击者进一步利用。

    • 自动传播:使用被盗的npm令牌,蠕虫能够发布其他包的恶意新版本,从而感染由同一开发者维护的其他包,形成级联效应。

这一设计使得Shai-Hulud能够快速扩展,影响范围远超单一包。

感染的npm包数量和类型

20250917211822753-图片

 

据报道,此次攻击感染了超过500个npm包,这些包涵盖了各种开发场景和组织。以下是一些示例:

    • @ahmedhfarag/ngx-perfect-scrollbar@20.0.20:Angular组件相关包。

    • @crowdstrike/commitlint@8.1.1:CrowdStrike公司维护的代码提交规范工具。

    • 其他包包括React工具、eslint配置、数据库工具等,涉及多个命名空间和版本。

@ahmedhfarag/ngx-perfect-scrollbar@20.0.20
@ahmedhfarag/ngx-perfect-scrollbar@20.0.20
@ahmedhfarag/ngx-virtual-scroller@4.0.4
@art-ws/common@2.0.28
@art-ws/config-eslint@2.0.4
@art-ws/config-eslint@2.0.5
@art-ws/config-ts@2.0.7
@art-ws/config-ts@2.0.8
@art-ws/db-context@2.0.24
@art-ws/di-node@2.0.13
@art-ws/di@2.0.28
@art-ws/di@2.0.32
@art-ws/eslint@1.0.5
@art-ws/eslint@1.0.6
@art-ws/fastify-http-server@2.0.24
@art-ws/fastify-http-server@2.0.27
@art-ws/http-server@2.0.21
@art-ws/http-server@2.0.25
@art-ws/openapi@0.1.12
@art-ws/openapi@0.1.9
@art-ws/package-base@1.0.5
@art-ws/package-base@1.0.6
@art-ws/prettier@1.0.5
@art-ws/prettier@1.0.6
@art-ws/slf@2.0.15
@art-ws/slf@2.0.22
@art-ws/ssl-info@1.0.10
@art-ws/ssl-info@1.0.9
@art-ws/web-app@1.0.3
@art-ws/web-app@1.0.4
@crowdstrike/commitlint@8.1.1
@crowdstrike/commitlint@8.1.2
@crowdstrike/falcon-shoelace@0.4.1
@crowdstrike/falcon-shoelace@0.4.2
@crowdstrike/foundry-js@0.19.1
@crowdstrike/foundry-js@0.19.2
@crowdstrike/glide-core@0.34.2
@crowdstrike/glide-core@0.34.3
@crowdstrike/logscale-dashboard@1.205.1
@crowdstrike/logscale-dashboard@1.205.2
@crowdstrike/logscale-file-editor@1.205.1
@crowdstrike/logscale-file-editor@1.205.2
@crowdstrike/logscale-parser-edit@1.205.1
@crowdstrike/logscale-parser-edit@1.205.2
@crowdstrike/logscale-search@1.205.1
@crowdstrike/logscale-search@1.205.2
@crowdstrike/tailwind-toucan-base@5.0.1
@crowdstrike/tailwind-toucan-base@5.0.2
@ctrl/deluge@7.2.1
@ctrl/deluge@7.2.2
@ctrl/golang-template@1.4.2
@ctrl/golang-template@1.4.3
@ctrl/magnet-link@4.0.3
@ctrl/magnet-link@4.0.4
@ctrl/ngx-codemirror@7.0.1
@ctrl/ngx-codemirror@7.0.2
@ctrl/ngx-csv@6.0.1
@ctrl/ngx-csv@6.0.2
@ctrl/ngx-emoji-mart@9.2.1
@ctrl/ngx-emoji-mart@9.2.2
@ctrl/ngx-rightclick@4.0.1
@ctrl/ngx-rightclick@4.0.2
@ctrl/qbittorrent@9.7.1
@ctrl/qbittorrent@9.7.2
@ctrl/react-adsense@2.0.1
@ctrl/react-adsense@2.0.2
@ctrl/shared-torrent@6.3.1
@ctrl/shared-torrent@6.3.2
@ctrl/tinycolor@4.1.1
@ctrl/tinycolor@4.1.2
@ctrl/torrent-file@4.1.1
@ctrl/torrent-file@4.1.2
@ctrl/transmission@7.3.1
@ctrl/ts-base32@4.0.1
@ctrl/ts-base32@4.0.2
@hestjs/core@0.2.1
@hestjs/cqrs@0.1.6
@hestjs/demo@0.1.2
@hestjs/eslint-config@0.1.2
@hestjs/logger@0.1.6
@hestjs/scalar@0.1.7
@hestjs/validation@0.1.6
@nativescript-community/arraybuffers@1.1.6
@nativescript-community/arraybuffers@1.1.7
@nativescript-community/arraybuffers@1.1.8
@nativescript-community/gesturehandler@2.0.35
@nativescript-community/perms@3.0.5
@nativescript-community/perms@3.0.6
@nativescript-community/perms@3.0.7
@nativescript-community/perms@3.0.8
@nativescript-community/sentry@4.6.43
@nativescript-community/sqlite@3.5.2
@nativescript-community/sqlite@3.5.3
@nativescript-community/sqlite@3.5.4
@nativescript-community/sqlite@3.5.5
@nativescript-community/text@1.6.10
@nativescript-community/text@1.6.11
@nativescript-community/text@1.6.12
@nativescript-community/text@1.6.13
@nativescript-community/text@1.6.9
@nativescript-community/typeorm@0.2.30
@nativescript-community/typeorm@0.2.31
@nativescript-community/typeorm@0.2.32
@nativescript-community/typeorm@0.2.33
@nativescript-community/ui-collectionview@6.0.6
@nativescript-community/ui-document-picker@1.1.27
@nativescript-community/ui-document-picker@1.1.28
@nativescript-community/ui-drawer@0.1.30
@nativescript-community/ui-image@4.5.6
@nativescript-community/ui-label@1.3.35
@nativescript-community/ui-label@1.3.36
@nativescript-community/ui-label@1.3.37
@nativescript-community/ui-material-bottom-navigation@7.2.72
@nativescript-community/ui-material-bottom-navigation@7.2.73
@nativescript-community/ui-material-bottom-navigation@7.2.74
@nativescript-community/ui-material-bottom-navigation@7.2.75
@nativescript-community/ui-material-bottomsheet@7.2.72
@nativescript-community/ui-material-core-tabs@7.2.72
@nativescript-community/ui-material-core-tabs@7.2.73
@nativescript-community/ui-material-core-tabs@7.2.74
@nativescript-community/ui-material-core-tabs@7.2.75
@nativescript-community/ui-material-core-tabs@7.2.76
@nativescript-community/ui-material-core@7.2.72
@nativescript-community/ui-material-core@7.2.73
@nativescript-community/ui-material-core@7.2.74
@nativescript-community/ui-material-core@7.2.75
@nativescript-community/ui-material-core@7.2.76
@nativescript-community/ui-material-ripple@7.2.72
@nativescript-community/ui-material-ripple@7.2.73
@nativescript-community/ui-material-ripple@7.2.74
@nativescript-community/ui-material-ripple@7.2.75
@nativescript-community/ui-material-tabs@7.2.72
@nativescript-community/ui-material-tabs@7.2.73
@nativescript-community/ui-material-tabs@7.2.74
@nativescript-community/ui-material-tabs@7.2.75
@nativescript-community/ui-pager@14.1.36
@nativescript-community/ui-pager@14.1.37
@nativescript-community/ui-pager@14.1.38
@nativescript-community/ui-pulltorefresh@2.5.4
@nativescript-community/ui-pulltorefresh@2.5.5
@nativescript-community/ui-pulltorefresh@2.5.6
@nativescript-community/ui-pulltorefresh@2.5.7
@nexe/config-manager@0.1.1
@nexe/eslint-config@0.1.1
@nexe/logger@0.1.3
@nstudio/angular@20.0.4
@nstudio/angular@20.0.5
@nstudio/angular@20.0.6
@nstudio/focus@20.0.4
@nstudio/focus@20.0.5
@nstudio/focus@20.0.6
@nstudio/nativescript-checkbox@2.0.6
@nstudio/nativescript-checkbox@2.0.7
@nstudio/nativescript-checkbox@2.0.8
@nstudio/nativescript-checkbox@2.0.9
@nstudio/nativescript-loading-indicator@5.0.1
@nstudio/nativescript-loading-indicator@5.0.2
@nstudio/nativescript-loading-indicator@5.0.3
@nstudio/nativescript-loading-indicator@5.0.4
@nstudio/ui-collectionview@5.1.11
@nstudio/ui-collectionview@5.1.12
@nstudio/ui-collectionview@5.1.13
@nstudio/ui-collectionview@5.1.14
@nstudio/web-angular@20.0.4
@nstudio/web@20.0.4
@nstudio/xplat-utils@20.0.5
@nstudio/xplat-utils@20.0.6
@nstudio/xplat-utils@20.0.7
@nstudio/xplat@20.0.5
@nstudio/xplat@20.0.6
@nstudio/xplat@20.0.7
@operato/board@9.0.36
@operato/board@9.0.37
@operato/board@9.0.38
@operato/board@9.0.39
@operato/board@9.0.40
@operato/board@9.0.41
@operato/board@9.0.42
@operato/board@9.0.43
@operato/board@9.0.44
@operato/board@9.0.45
@operato/board@9.0.46
@operato/data-grist@9.0.29
@operato/data-grist@9.0.35
@operato/data-grist@9.0.36
@operato/data-grist@9.0.37
@operato/graphql@9.0.22
@operato/graphql@9.0.35
@operato/graphql@9.0.36
@operato/graphql@9.0.37
@operato/graphql@9.0.38
@operato/graphql@9.0.39
@operato/graphql@9.0.40
@operato/graphql@9.0.41
@operato/graphql@9.0.42
@operato/graphql@9.0.43
@operato/graphql@9.0.44
@operato/graphql@9.0.45
@operato/graphql@9.0.46
@operato/headroom@9.0.2
@operato/headroom@9.0.35
@operato/headroom@9.0.36
@operato/headroom@9.0.37
@operato/help@9.0.35
@operato/help@9.0.36
@operato/help@9.0.37
@operato/help@9.0.38
@operato/help@9.0.39
@operato/help@9.0.40
@operato/help@9.0.41
@operato/help@9.0.42
@operato/help@9.0.43
@operato/help@9.0.44
@operato/help@9.0.45
@operato/help@9.0.46
@operato/i18n@9.0.35
@operato/i18n@9.0.36
@operato/i18n@9.0.37
@operato/input@9.0.27
@operato/input@9.0.35
@operato/input@9.0.36
@operato/input@9.0.37
@operato/input@9.0.38
@operato/input@9.0.39
@operato/input@9.0.40
@operato/input@9.0.41
@operato/input@9.0.42
@operato/input@9.0.43
@operato/input@9.0.44
@operato/input@9.0.45
@operato/input@9.0.46
@operato/input@9.0.47
@operato/input@9.0.48
@operato/layout@9.0.35
@operato/layout@9.0.36
@operato/layout@9.0.37
@operato/popup@9.0.22
@operato/popup@9.0.35
@operato/popup@9.0.36
@operato/popup@9.0.37
@operato/popup@9.0.38
@operato/popup@9.0.39
@operato/popup@9.0.40
@operato/popup@9.0.41
@operato/popup@9.0.42
@operato/popup@9.0.43
@operato/popup@9.0.44
@operato/popup@9.0.45
@operato/popup@9.0.46
@operato/popup@9.0.49
@operato/pull-to-refresh@9.0.36
@operato/pull-to-refresh@9.0.37
@operato/pull-to-refresh@9.0.38
@operato/pull-to-refresh@9.0.39
@operato/pull-to-refresh@9.0.40
@operato/pull-to-refresh@9.0.41
@operato/pull-to-refresh@9.0.42
@operato/shell@9.0.22
@operato/shell@9.0.35
@operato/shell@9.0.36
@operato/shell@9.0.37
@operato/shell@9.0.38
@operato/shell@9.0.39
@operato/styles@9.0.2
@operato/styles@9.0.35
@operato/styles@9.0.36
@operato/styles@9.0.37
@operato/utils@9.0.22
@operato/utils@9.0.35
@operato/utils@9.0.36
@operato/utils@9.0.37
@operato/utils@9.0.38
@operato/utils@9.0.39
@operato/utils@9.0.40
@operato/utils@9.0.41
@operato/utils@9.0.42
@operato/utils@9.0.43
@operato/utils@9.0.44
@operato/utils@9.0.45
@operato/utils@9.0.46
@operato/utils@9.0.49
@teselagen/bio-parsers@0.4.30
@teselagen/bounce-loader@0.3.16
@teselagen/bounce-loader@0.3.17
@teselagen/file-utils@0.3.22
@teselagen/liquibase-tools@0.4.1
@teselagen/ove@0.7.40
@teselagen/range-utils@0.3.14
@teselagen/range-utils@0.3.15
@teselagen/react-list@0.8.19
@teselagen/react-list@0.8.20
@teselagen/react-table@6.10.19
@teselagen/react-table@6.10.20
@teselagen/react-table@6.10.22
@teselagen/sequence-utils@0.3.34
@teselagen/ui@0.9.10
@thangved/callback-window@1.1.4
@things-factory/attachment-base@9.0.43
@things-factory/attachment-base@9.0.44
@things-factory/attachment-base@9.0.45
@things-factory/attachment-base@9.0.46
@things-factory/attachment-base@9.0.47
@things-factory/attachment-base@9.0.48
@things-factory/attachment-base@9.0.49
@things-factory/attachment-base@9.0.50
@things-factory/auth-base@9.0.43
@things-factory/auth-base@9.0.44
@things-factory/auth-base@9.0.45
@things-factory/email-base@9.0.42
@things-factory/email-base@9.0.43
@things-factory/email-base@9.0.44
@things-factory/email-base@9.0.45
@things-factory/email-base@9.0.46
@things-factory/email-base@9.0.47
@things-factory/email-base@9.0.48
@things-factory/email-base@9.0.49
@things-factory/email-base@9.0.50
@things-factory/email-base@9.0.51
@things-factory/email-base@9.0.52
@things-factory/email-base@9.0.53
@things-factory/email-base@9.0.54
@things-factory/env@9.0.42
@things-factory/env@9.0.43
@things-factory/env@9.0.44
@things-factory/env@9.0.45
@things-factory/integration-base@9.0.43
@things-factory/integration-base@9.0.44
@things-factory/integration-base@9.0.45
@things-factory/integration-marketplace@9.0.43
@things-factory/integration-marketplace@9.0.44
@things-factory/integration-marketplace@9.0.45
@things-factory/shell@9.0.43
@things-factory/shell@9.0.44
@things-factory/shell@9.0.45
@tnf-dev/api@1.0.8
@tnf-dev/core@1.0.8
@tnf-dev/js@1.0.8
@tnf-dev/mui@1.0.8
@tnf-dev/react@1.0.8
@ui-ux-gang/devextreme-angular-rpk@24.1.7
@yoobic/design-system@6.5.17
@yoobic/jpeg-camera-es6@1.0.13
@yoobic/yobi@8.7.53
airchief@0.3.1
airpilot@0.8.8
angulartics2@14.1.1
angulartics2@14.1.2
browser-webdriver-downloader@3.0.8
capacitor-notificationhandler@0.0.2
capacitor-notificationhandler@0.0.3
capacitor-plugin-healthapp@0.0.2
capacitor-plugin-healthapp@0.0.3
capacitor-plugin-ihealth@1.1.8
capacitor-plugin-ihealth@1.1.9
capacitor-plugin-vonage@1.0.2
capacitor-plugin-vonage@1.0.3
capacitorandroidpermissions@0.0.4
capacitorandroidpermissions@0.0.5
config-cordova@0.8.5
cordova-plugin-voxeet2@1.0.24
cordova-voxeet@1.0.32
create-hest-app@0.1.9
db-evo@1.1.4
db-evo@1.1.5
devextreme-angular-rpk@21.2.8
ember-browser-services@5.0.2
ember-browser-services@5.0.3
ember-headless-form-yup@1.0.1
ember-headless-form@1.1.2
ember-headless-form@1.1.3
ember-headless-table@2.1.5
ember-headless-table@2.1.6
ember-url-hash-polyfill@1.0.12
ember-url-hash-polyfill@1.0.13
ember-velcro@2.2.1
ember-velcro@2.2.2
encounter-playground@0.0.2
encounter-playground@0.0.3
encounter-playground@0.0.4
encounter-playground@0.0.5
eslint-config-crowdstrike-node@4.0.3
eslint-config-crowdstrike-node@4.0.4
eslint-config-crowdstrike@11.0.2
eslint-config-crowdstrike@11.0.3
eslint-config-teselagen@6.1.7
eslint-config-teselagen@6.1.8
globalize-rpk@1.7.4
graphql-sequelize-teselagen@5.3.8
graphql-sequelize-teselagen@5.3.9
html-to-base64-image@1.0.2
json-rules-engine-simplified@0.2.1
json-rules-engine-simplified@0.2.4
jumpgate@0.0.2
koa2-swagger-ui@5.11.1
koa2-swagger-ui@5.11.2
mcfly-semantic-release@1.3.1
mcp-knowledge-base@0.0.2
mcp-knowledge-graph@1.2.1
mobioffice-cli@1.0.3
monorepo-next@13.0.1
monorepo-next@13.0.2
mstate-angular@0.4.4
mstate-cli@0.4.7
mstate-dev-react@1.1.1
mstate-react@1.6.5
ng2-file-upload@7.0.2
ng2-file-upload@7.0.3
ng2-file-upload@8.0.1
ng2-file-upload@8.0.2
ng2-file-upload@8.0.3
ng2-file-upload@9.0.1
ngx-bootstrap@18.1.4
ngx-bootstrap@19.0.3
ngx-bootstrap@19.0.4
ngx-bootstrap@20.0.3
ngx-bootstrap@20.0.4
ngx-bootstrap@20.0.5
ngx-color@10.0.1
ngx-color@10.0.2
ngx-toastr@19.0.1
ngx-toastr@19.0.2
ngx-trend@8.0.1
ngx-ws@1.1.5
ngx-ws@1.1.6
oradm-to-gql@35.0.14
oradm-to-gql@35.0.15
oradm-to-sqlz@1.1.2
ove-auto-annotate@0.0.10
ove-auto-annotate@0.0.9
pm2-gelf-json@1.0.4
pm2-gelf-json@1.0.5
printjs-rpk@1.6.1
react-complaint-image@0.0.32
react-complaint-image@0.0.35
react-jsonschema-form-conditionals@0.3.18
react-jsonschema-form-conditionals@0.3.21
react-jsonschema-form-extras@1.0.4
react-jsonschema-rxnt-extras@0.4.9
remark-preset-lint-crowdstrike@4.0.1
remark-preset-lint-crowdstrike@4.0.2
rxnt-authentication@0.0.3
rxnt-authentication@0.0.4
rxnt-authentication@0.0.5
rxnt-authentication@0.0.6
rxnt-healthchecks-nestjs@1.0.2
rxnt-healthchecks-nestjs@1.0.3
rxnt-healthchecks-nestjs@1.0.4
rxnt-healthchecks-nestjs@1.0.5
rxnt-kue@1.0.4
rxnt-kue@1.0.5
rxnt-kue@1.0.6
rxnt-kue@1.0.7
swc-plugin-component-annotate@1.9.1
swc-plugin-component-annotate@1.9.2
tbssnch@1.0.2
teselagen-interval-tree@1.1.2
tg-client-query-builder@2.14.4
tg-client-query-builder@2.14.5
tg-redbird@1.3.1
tg-redbird@1.3.2
tg-seq-gen@1.0.10
tg-seq-gen@1.0.9
thangved-react-grid@1.0.3
ts-gaussian@3.0.5
ts-gaussian@3.0.6
ts-imports@1.0.1
ts-imports@1.0.2
tvi-cli@0.1.5
ve-bamreader@0.2.6
ve-bamreader@0.2.7
ve-editor@1.0.1
ve-editor@1.0.2
verror-extra@6.0.1
voip-callkit@1.0.2
voip-callkit@1.0.3
wdio-web-reporter@0.1.3
yargs-help-output@5.0.3
yoo-styles@6.0.326

更多受影响的软件包请移步:

这些包的广泛性表明,攻击并非针对特定领域,而是旨在最大化影响。受影响包的完整列表可在相关安全报告中查阅,开发者应立即检查自己的项目依赖。

攻击机制

Shai-Hulud的攻击机制高度自动化,具体步骤如下:

    1. 初始感染:通过某种方式(如钓鱼或先前妥协)进入开发者的机器。

    1. 凭据提取:部署秘密扫描工具,扫描并提取敏感数据。

    1. 泄露与利用:将凭据上传至GitHub仓库,使用npm令牌发布恶意包版本。

    1. 级联传播:恶意版本被其他开发者下载,进一步感染他们的环境,实现蠕虫的自复制。

这一机制利用了npm生态的信任模型,即开发者通常不会怀疑官方发布的包更新,从而绕过了传统安全检查。

影响分析

此次攻击的影响深远:

    • 开发者层面:凭据泄露可能导致账户被劫持,进一步扩展到GitHub、云服务等领域。

    • 组织层面:如CrowdStrike等知名公司受影响,凸显供应链攻击对企业安全的威胁。

    • 生态系统层面:npm作为全球最大的包管理器,其安全事件可能波及数百万项目,增加软件供应链的整体风险。

安全研究人员强调,这一事件是开源软件面临的新型威胁,需要全球协作来评估全部影响。

检测和缓解方法

为应对Shai-Hulud蠕虫,开发者应立即采取以下措施:

    • 撤销凭据:检查并撤销任何可能被妥协的npm、GitHub令牌和API密钥。

    • 审计依赖:使用工具如npm audit扫描项目,移除受影响的包和版本。

    • 环境清理:从开发环境中彻底删除恶意依赖,并监控异常活动。

    • 加强安全:采用多因素认证、定期轮换凭据,并使用安全的秘密管理工具。

此外,开源社区应推动npm生态的改进,如增强包签名验证和自动化安全扫描。

结论

Shai-Hulud蠕虫攻击事件提醒我们,供应链安全已成为软件开发的核心挑战。在开源时代,开发者需保持高度警惕,结合技术工具和最佳实践来防范此类威胁。通过及时响应和社区合作,我们可以共同构建更安全的软件生态。

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 共1条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片
    • 李白的头像李白你好-实战攻防李白你好永久会员李白徽章-活跃Hacker李白你好-实战攻防李白你好等级-LV3李白你好-实战攻防李白你好作者0