
Wprowadzenie do problemu / definicja luki
Badacze ReversingLabs opisali kampanię, w której 19 rozszerzeń VS Code publikowanych w oficjalnym VSCode Marketplace zawierało złośliwy ładunek ukryty w folderze node_modules. Najbardziej charakterystyczny element ataku: plik banner.png, który nie był obrazem, ale archiwum z dwoma binariami — wykorzystywany był cmstp.exe (Living-off-the-Land) oraz trojan napisany w Rust. Kampania miała działać od lutego 2025 r., a znaleziska zgłoszono do Microsoftu na początku grudnia; rozszerzenia zostały usunięte z marketplace.
W skrócie
- 19 złośliwych rozszerzeń (głównie „theme’y”) dostarczało zmodyfikowane zależności w node_modules, aby ominąć pobieranie z npm i ukryć różnice.
- Atak modyfikował popularny pakiet path-is-absolute (ponad 9 mld pobrań) lub alternatywnie @actions/io, dorzucając klasę inicjującą dropper.
- Dropper dekodował zaszyfrowany JavaScript z pliku lock (base64 + odwrócenie łańcucha), następnie uruchamiał binaria z fałszywego banner.png przez cmstp.exe, co finalnie ładowało trojana w Rust.
- Microsoft usunął zgłoszone pozycje z Marketplace; użytkownicy powinni sprawdzić system pod kątem kompromitacji.
Kontekst / historia / powiązania
Marketplace’y dla IDE stały się atrakcyjnym wektorem łańcucha dostaw. W 2025 r. obserwowano kolejne incydenty z udziałem złośliwych rozszerzeń VS Code oraz pakietów Go/npm/Rust kradnących dane devów. Równolegle badania Wiz wykazały setki wycieków sekretów i tokenów publikacyjnych w pakietach rozszerzeń (co umożliwia skryte „pchanie” aktualizacji do całej bazy instalacyjnej). Te trendy pokazują, iż nawet „niewinne” motywy/tematy mogą być nośnikiem ryzyka supply-chain.
Analiza techniczna / szczegóły luki
Pakowanie zależności w rozszerzeniach VS Code. W przeciwieństwie do typowego obiegu npm (gdzie npm install pobiera świeże zależności), rozszerzenia VS Code dostarczają kompletny folder node_modules w paczce .vsix. To pozwala atakującym „podmienić” treść popularnych paczek tylko na potrzeby swojego rozszerzenia — bez modyfikowania artefaktów na npm i bez czerwonych flag po stronie użytkownika.
Modyfikacja dependency. Atakujący dodali nową klasę do index.js w path-is-absolute (lub w części próbek użyli @actions/io), która automatycznie uruchamiała się przy starcie VS Code i dekodowała obfuskowany dropper z pliku lock (base64 + reverse).
Fałszywy obraz banner.png. W większości wariantów w node_modules znajdował się banner.png — w praktyce archiwum z dwoma binariami: cmstp.exe (LOLBin) do uruchomienia ładunku oraz docelowym trojanem Rust. W wersjach z @actions/io pliki były ukryte w parach .ts/.map. Zdolności trojana są przez cały czas analizowane, ale łańcuch wykonywania jest spójny między próbkami.
Przykładowe nazwy rozszerzeń (IOC): m.in. Malkolm Theme, PandaExpress Theme, Prada 555 Theme, Priskinski Theme — wszystkie w wersji 1.0.0; ReversingLabs opublikował pełną listę nazw/SHA1.
Praktyczne konsekwencje / ryzyko
- Ryzyko supply-chain po stronie devów. Wystarczy instalacja „tematu”/„motywu”, by kod w node_modules uruchomił dropper podczas startu VS Code. W środowisku developerskim to często maszyny z tajemnicami (tokeny, SSH, ciasteczka przeglądarek, konfiguracje chmurowe).
- Trudność detekcji. Zależności są „zaufane z nazwy”, a plik PNG nie otwiera się jako obraz — nie generuje to oczywistych alertów. LOLBin cmstp.exe zaciera ślady.
- Szybka dystrybucja / aktualizacje. Auto-update rozszerzeń i (osobny problem) wyciekające PAT-y wydawców zwiększają zasięg i prędkość potencjalnego skażenia.
Rekomendacje operacyjne / co zrobić teraz
1) Triage i hunting (Windows/macOS):
- Inwentaryzacja VS Code: code --list-extensions --show-versions i weryfikacja na liście IOC ReversingLabs. Usuń podejrzane rozszerzenia, zwłaszcza o nazwach z rodziny Malkolm/PandaExpress/Prada 555/Priskinski (v1.0.0).
- Przegląd paczek .vsix: rozpakuj (ZIP) i zbadaj node_modules pod kątem zmodyfikowanego index.js w path-is-absolute/@actions/io, obecności plików lock, fałszywych .png, nietypowych .ts/.map z binariami.
- Telemetria / EDR: poluj na uruchomienia cmstp.exe przez procesy VS Code (Code.exe, code), nietypowe wywołania curl/PowerShell oraz świeże binaria Rust w katalogach rozszerzeń.
2) Odtwarzanie zaufania:
- Reset sekretów na stacjach dev (tokeny API, PAT, klucze chmurowe, cookies przeglądarek) o ile wykryto instalację z listy IOC. Zalecana rotacja haseł i odświeżenie sesji przeglądarek. (Kontekst: znane kampanie kradły cookies, Wi-Fi i zrzuty ekranu).
- Segregacja środowisk: minimalizuj pracę z wrażliwymi sekretami na stacjach z bogatym zestawem rozszerzeń VS Code.
3) Hardening procesowy:
- Allowlista rozszerzeń i centralna polityka dla VS Code (np. przez Settings Sync for Business, polityki systemowe, MDM). Ogranicz auto-update dla rozszerzeń wysokiego ryzyka lub wymuś update’y z repozytorium wewnętrznego po skanowaniu.
- Skanowanie rozszerzeń przed dystrybucją (CI) — rozpakowanie .vsix, statyczna analiza node_modules, reguły na anomalie (np. binaria w PNG, obecność cmstp.exe).
- Program „least extensions”: ogranicz liczbę instalowanych pluginów; weryfikuj reputację wydawcy, historię wersji, liczbę pobrań i recenzje.
4) Kontrole platformowe (dla zespołów platform/devx):
- Repo lokalne rozszerzeń (mirror/allowlist) zamiast bezpośredniego Marketplace.
- Sekrety w pakietach: przegląd publikowanych przez organizację rozszerzeń pod kątem wycieków PAT/API i zaciśnięcie polityk TTL dla tokenów (wnioski z badań Wiz).
Różnice / porównania z innymi przypadkami (2025)
- GlassWorm / WhiteCobra i inne fale — wcześniejsze kampanie celowały w VS Code/Open VSX, dostarczając m.in. infostealery (kradzież ciasteczek, sesji, portfeli). Opisywany dziś przypadek wyróżnia się „fałszywym PNG” i nadużyciem pre-pakowanych zależności w node_modules, zamiast prostego pobrania payloadu po instalacji.
- „Material Icon Theme” – Rust implants — niedawna analiza Nextron wykazała wykorzystanie implantów Rust i nietypowych kanałów C2 (Solana/Google Calendar). To inna kampania, ale trend wykorzystania Rust + sprytnych nośników się utrzymuje.
Podsumowanie / najważniejsze wnioski
- Atakujący schowali malware w zaufanych nazwach zależności i w „obrazku” PNG, co świetnie wpisuje się w model niskiej widoczności w IDE.
- Audyt rozszerzeń musi obejmować folder node_modules. Samo zerknięcie w package.json to za mało.
- Organizacje powinny centralizować kontrolę nad rozszerzeniami, rotować sekrety po incydentach i polować na LOLBiny odpalane przez VS Code.
Źródła / bibliografia
- ReversingLabs: „VS Code extensions use fake image containing a trojan” (pełne IOC, szczegóły techniczne). (ReversingLabs)
- BleepingComputer: „Malicious VSCode Marketplace extensions hid trojan in fake PNG file” (daty, usunięcie z Marketplace). (BleepingComputer)
- The Hacker News: „Researchers Find Malicious VS Code, Go, npm, and Rust Packages…” (szerszy kontekst kradzieży danych przez rozszerzenia/pakiety). (The Hacker News)
- Wiz Research: „Dismantling a Critical Supply Chain Risk in VSCode Extension Marketplaces” (ryzyko tokenów wydawców, rekomendacje hardeningu). (wiz.io)
- Nextron Systems: „Analysis of the Rust implants found in the malicious VS Code extension” (porównawczo: Rust C2/implanty). (nextron-systems.com)













