Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Adminie… Czy znamy Twoje grzechy? ;-) Sprawdź!
Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Adminie… Czy znamy Twoje grzechy? ;-) Sprawdź!
Badacze z StepSecurity odkryli złośliwe aktualizacje pakietu pgserve w npm. Jest to narzędzie do uruchamiania lokalnych baz PostgreSQL do developmentu / testów. Zainfekowane wersje (1.1.11, 1.1.12 i 1.1.13) wstrzykują 1143-liniowy skrypt wykradający poświadczenia użytkownika. Jest on uruchamiany przy instalacji przez hook postinstall.
Nie jest to jednak “zwykły” infostealer, bo malware ma także możliwość dalszego rozprzestrzeniania. Jeśli na urządzeniu ofiary znajdzie token npm, wstrzykuje złośliwy kod do każdego pakietu, który można opublikować za pomocą tego tokenu.
Żadna z trzech zainfekowanych wersji nie ma odpowiadającego git tag ani release w oryginalnym repozytorium na GitHub. Ostatnia prawidłowo wydana wersja to v1.1.10 (17 kwietnia 2026).
W wersji 1.1.11 atakujący dodali dwa pliki: check-env.js i public.pem. Wersje 1.1.12 i 1.1.13 zawierają ten sam kod, a zmienia się jedynie package.json.
Zmiana polegała na dopisaniu fallbacku:
| “postinstall”: “node scripts/check-env.cjs || true” |
Listing 1 – fallback w hooku postinstall, źródło: stepsecurity.io
Dzięki temu proces instalacji wygląda na zrealizowany poprawnie niezależnie od tego, czy złośliwy kod zostanie wykonany pomyślnie.
Sam złośliwy payload ma 1143 linie. Wykonuje on sześć operacji:
Najpierw funkcja harvest() skanuje każdą zmienną środowiskową względem ~40 wzorców regex, szukając wszystkiego, co wygląda jak poświadczenia / wartości konfiguracyjne:
| const sensitivePatterns = [ /TOKEN/i, /SECRET/i, /KEY/i, /PASSWORD/i, /CREDENTIAL/i, /^AWS_/i, /^AZURE_/i, /^GCP_/i, /^GOOGLE_/i, /^NPM_/i, /^GITHUB_/i, /^GITLAB_/i, /^DOCKER_/i, /^DATABASE/i, /^DB_/i, /^REDIS/i, /^MONGO/i, /^OPENAI/i, /^ANTHROPIC/i, /^COHERE/i, /^STRIPE/i, /^TWILIO_/i, /^SENDGRID_/i, …]; |
Listing 2 – wzorce przeszukiwania zmiennych środowiskowych, źródło: stepsecurity.io
Skrypt szuka plików mogących zawierać poświadczenia w katalogu domowym ofiary:
a także dane portfeli kryptowalutowych. Ponadto wykradane są także hasła zapisane w przeglądarce Chrome.
Przed wysłaniem danych do atakującego generowany jest losowy session key (AES-256-CBC), a następnie dane szyfrowane tym kluczem. Następnie session key jest szyfrowany publicznym kluczem RSA-4096 kontrolowanym przez atakujących (zapisano go w pliku scripts/public.pem).
Oznacza to, że wykradzione dane nie mogą zostać odczytane bez prywatnego klucza RSA atakujących – nawet jeśli transmisja zostanie przechwycona.
Zaszyfrowane dane są wysyłane dwoma kanałami:
Jako podstawowy kanał wykorzystano canister utrzymywany na blockchainie Internet Computer Protocol (ICP). Prawdopodobnie celem było utrudnienie jego zablokowania.
Badacze nie znaleźli śladów wcześniejszego wykorzystania domeny telemetry[.]api-monitor[.]com – najprawdopodobniej jest to domena zarejestrowana specjalnie dla tej kampanii.
Po eksfiltrowaniu poświadczeń malware wyszukuje tokeny npm:
| // Checks process.env.NPM_TOKEN and ~/.npmrc for _authToken entries const tokenInfo = await findNpmToken(); if (tokenInfo) { const { username, packages } = await enumPackages(tokenInfo.token); // Injects itself into every package the victim can publish for (const pkg of packages) { await infectPackage(pkg, tokenInfo.token); } } |
Listing 3 – kod samopropagujący malware (komentarze badaczy), źródło: stepsecurity.io
Dla każdego pakietu, dla którego ofiara (a dokładniej token, z którego korzysta) ma uprawnienia do publikacji, malware podbija wersję (patch version), kopiuje pliki check-env.js i public.pem do katalogu scripts, dodaje hook postinstall w package.json i wywołuje npm publish. W ten sposób jedno konto może prowadzić do zainfekowania wielu kolejnych pakietów.
Niestety regularnie obserwujemy, jak niebezpieczne mogą być ataki na łańcuch dostaw. W tym przypadku zwykła paczka, która wcześniej nie wykonywała żadnych złośliwych działań, nagle stała się zagrożeniem.
Programistom polecamy w miarę możliwości ograniczać wszelkie tokeny / klucze API do konkretnych adresów IP oraz limitować ich uprawnienia/dostępy. Do publikowania paczek w NPM warto skorzystać z trusted publishing. Bardziej wrażliwe poświadczenia (jak np. klucze SSH) można obsługiwać sprzętowo, za pomocą np. klucza FIDO.
Źródło: stepsecurity.io
~Tymoteusz Jóźwiak