Mega Sekurak Hacking Party w Krakowie! 20.10.2025 r.
PyPI, Ruby, npm – atak na popularne łańcuchy dostaw z wykorzystaniem Discorda
To nie pierwszy raz kiedy atakujący obierają za cel łańcuchy dostaw. Nie tak dawno informowaliśmy o ataku na listę otwartych bibliotek npm, a już pojawia się kolejne zagrożenie – malware ukryty w pakietach PyPI, Ruby oraz wspomnianym wyżej npm.
TLDR:
- Badacze bezpieczeństwa z firmy Socket wykryli nowy wektor ataku, w którym złośliwy kod został umieszczony w pakietach npm, PyPI oraz Ruby.
- Zadaniem malware jest wykradanie wrażliwych informacji.
- Jako serwer C2 został wykorzystany Discord.
- Skala ataku nie jest znana. Mowa jedynie o szeregu zainfekowanych paczek w różnych ekosystemach.
Badacze bezpieczeństwa z Socket.dev zidentyfikowali szereg pakietów zainfekowanych złośliwym oprogramowaniem, którego głównym zadaniem było wykradanie wrażliwych informacji i przesyłanie ich na kanał kontrolowany przez atakującego. Komunikacja odbywała się za pośrednictwem platformy Discord, a dokładniej mówiąc wykorzystany został mechanizm Discord Webhook.
Czym jest webhook?
Webhook można zdefiniować jako mechanizm PUSH do automatycznej wymiany danych między aplikacjami po wystąpieniu danego zdarzenia. Polega na wysłaniu żądania HTTP (zwykle POST) na z góry ustalony adres URL odbiorcy z ładunkiem poszerzającym wiedzę na temat tego zdarzenia. Najczęściej informacje te zapisane są w formacie JSON oraz opatrzone metadanymi, pozwalającymi dodatkowo na weryfikację źródła nadania wiadomości. W przypadku Discorda, Webhook pełni analogiczną funkcję, z tym że informacje przesyłane są na konkretny kanał na serwerze. Ponadto, dla każdego kanału istnieje możliwość definicji unikalnych webhooków. Różnią się one identyfikatorem oraz tokenem, dzięki czemu zewnętrzne systemy mogą automatycznie publikować wiadomości i pliki w danym kanale.
Discord został wybrany przez atakujących jako kanał Command & Control (C2), głównie z powodu oferowania darmowego hostingu danych w chmurze oraz łatwość w automatyzacji i konfiguracji nowych kanałów. Dzięki nim istnieje możliwość wysyłania do przejętych systemów indywidualnych komend sterujących oraz odbierania wykradzionych danych. W przypadku zablokowania kanału, postawienie nowej, w pełni funkcjonalnej instancji trwa zaledwie kilka minut. Jeżeli nie został zaimplementowany kanał zapasowy lub inny mechanizm pozwalający na aktualizację danych serwera C2, atakujący traci kontrolę nad zainfekowanym systemem.
Ponadto, analitycy bezpieczeństwa mają duże wyzwania w opracowaniu efektywnych metod detekcji tego typu zagrożenia, ponieważ w komunikacji z discordapp.com trudno wykryć anomalie sugerujące nietypowy ruch. W przypadku środowisk korporacyjnych, sensownym rozwiązaniem wydaje się zablokowanie dostępu do takiej aplikacji lub uruchomienie jej w sandboxie, aby monitorować potencjalnie złośliwe zachowanie.
Jak doszło do wykrycia malware?
Malware został wykryty przez badaczy podczas rutynowej analizy kodów źródłowych pakietów. Zaobserwowano nietypowe wykorzystanie discordowych webhooków, których z punktu widzenia logiki pakietu nie powinno być.
Co ciekawe, w środowisku npm złośliwy kod odpowiadał za przesyłanie plików konfiguracyjnych, m.in.: config.json, .env oraz logów z informacjami diagnostycznymi. Na poniższym rysunku umieszczono listing ze złośliwym kodem.

Jak widać na rys. 1, kod nie jest skomplikowany. Malware szuka plików konfiguracyjnych, a następnie wysyła dane na kanał Discorda (adres kanału został zahardcodowany – WEBHOOK_URL). Z uwagi na ograniczenie Discorda, co do limitu długości wiadomości, przesyłane zostają jedynie maksymalnie 1900 znaków, niezależnie od rozmiaru pliku. Co ciekawe, wykorzystane zostały tureckie słowa oznaczajace konfigurację oraz komentarze, co może sugerować, źródło pochodzenia kodu.
Sytuacja analogiczna została zaobserwowana w pakietach dostępnych w PyPI. W celu lepszego zobrazowania możliwości złośliwego kodu posłużono się przykładem – malinssx – paczki, która została usunięta z menadżera PyPI.

Kod przedstawiony na rys. 2, pokazuje mechanizm pozwalający na przesyłanie informacji na temat zainstalowanych pakietów na kanał kontrolowany przez atakującego (adres kanału zdefiniowany stałą WEBHOOK_URL). Infekcja następuje w momencie instalacji pakietu, za pomocą polecenia pip install [packet_name]. W pierwszym kroku przygotowywany zostaje JSON z informacją o podjęciu próby instalacji pakietu. Następnie dane (nazwa zainstalowanego pakietu oraz jego wersja) są kodowane i przesyłane do atakującego. Jeżeli podczas instalacji wystąpią błędy lub ostrzeżenia, to są one przechwytywane i ukrywane przed użytkownikiem. Mechanizm ten zapewnia działanie skryptu, mimo błędów napotkanych podczas instalacji oraz maskuje podejrzaną aktywność, która mogłaby zaalarmować użytkownika. Na koniec wywoływany jest standardowy instalator (install.run(self)), co sprawia że cały proces wygląda na rutynową instalację pakietu.
Złośliwe pakiety zostały również wykryte w ekosystemie RubyGems. Działanie malware jest nieco inne niż w przypadkach przedstawionych powyżej, jednak wspólnym mianownikiem jest wykorzystanie kanału Discord (discord webhook).

Złośliwy skrypt odczytuje zawartość pliku /etc/passwd, konfigurację sieciową /etc/resolv.conf, nazwę hosta, użytkownika, katalog domowy, adres IP maszyny, a następnie przesyła zgromadzone dane na odpowiedni kanał na Discordzie (zmienna url przechowująca adres kanału Discord).
Dokładna liczba zainfekowanych pakietów nie jest znana. Zgodnie z opinią badaczy, zostało wykrytych wiele złośliwych paczek.
Czy jest się czego bać?
Zagrożenie jest realne, jednak odpowiednia higiena pracy pozwoli zmniejszyć ryzyko infekcji. Nadużywanie webhooków jako kanałów C2 implikuje implementację nowej strategii obrony. Obok blokowania złośliwych domen, należy podjąć działania skupiające się na monitorowaniu skryptów instalacyjnych pakietów oraz obserwacji zachowań, tzn.: kiedy i w jakiej sytuacji pakiet nawiązuje połączenie sieciowe, do jakich plików posiada dostęp.
Jak dotąd nie udało się ustalić, kto stoi za atakiem.
Źródło: socket.dev/blog/
~_secmike