Strona główna / Blog / OVHcloud CLI: podmienione wydania

Blog · case study

OVHcloud CLI: ktoś podmienił pliki w pięciu oficjalnych wydaniach. Ta sama wersja, inne bajty, okno 93 minut i żadnego CVE

19 października 2026 przez 93 minuty archiwa do pobrania przy wydaniach v0.11.0–v0.15.0 OVHcloud CLI na GitHubie zawierały złośliwy program kradnący sekrety. Kodu źródłowego nie zmieniono, tagów też nie. Pod tymi samymi adresami i z tym samym numerem wersji leżały po prostu inne bajty. Według OVHcloud plik pobrano w tym czasie około 250 razy. CVE nie ma i nie powinno być, bo to nie jest błąd produktu. Dla VM to czysty przypadek, w którym skaner porównujący wersje niczego nie zobaczy, a o narażeniu decydują trzy pytania: kiedy plik pobrano, na jaką platformę i czy go uruchomiono.

Produkt: OVHcloud CLI (ovh/ovhcloud-cli), binarki z GitHub Releases: macOS arm64 i x86_64, Linux arm64 i x86_64, Windows x86_64.
Identyfikator: advisory producenta GHSA-862f-55f5-vmvw z 20.10.2026, bez CVE. Pierwsze zgłoszenie: publiczne issue #300 z 19.10.2026.
Okno: 19.10.2026, 12:47–14:21 UTC (w advisory: 14:47–16:21 UTC+2), czyli 1 h 33 min. Około 250 pobrań.
Nienarażone: ≤ v0.10.0 i ≥ v0.16.0 oraz kopie v0.11–v0.15 pobrane przed oknem. Kod źródłowy i pipeline budowania według producenta nienaruszone. Według BleepingComputer, za OpenSourceMalware, nienaruszone są też buildy ze źródeł i obrazy Docker.
Czysta wersja: v0.16.0 z podpisanym tagiem, wydanie w trybie niezmienialnym (19.10, 17:16 UTC).
Threat state: incydent potwierdzony przez producenta. Liczba uruchomień złośliwego pliku i ewentualnych nadużyć skradzionych sekretów nie jest znana.

Co się stało

Advisory OVHcloud jest konkretne. Ktoś użył przejętego konta GitHub jednego z deweloperów OVHcloud, żeby zastąpić istniejące pliki wydań. Producent podaje oś czasu:

Czas (UTC, 19.10.2026)Zdarzenie (wg GHSA OVHcloud)
12:47Podmiana binarki Darwin w wydaniu v0.15.0
12:57Podmienione wszystkie binarki v0.15.0 (reporter: także checksums.txt)
13:30Podmienione binarki wydań v0.15.0 do v0.11.0
13:50Klient zgłasza problem w publicznym issue #300. Wykrył go, bo jego CI przypinało SHA-256 archiwum i przestało przechodzić
14:21Wszystkie złośliwe binarki usunięte z repozytorium
16:52Pierwszy publiczny komunikat na X
17:16Wydanie v0.16.0 z podpisanym tagiem, w trybie niezmienialnym

Podmienione binarki to oryginalne CLI przekompilowane z dodanym modułem kradnącym dane. Reporter z issue #300 pokazał to bez uruchamiania pliku, poleceniem go version -m: „v0.15.0” był lokalnym buildem późniejszego commita z niezatwierdzonymi zmianami (+dirty), bez flag z konfiguracji goreleasera. Tag v0.15.0 nadal wskazywał oryginalny commit, a proxy modułów Go serwował ten sam, czysty kod. W v0.15.0, v0.14.0 i v0.13.0 podmieniono też checksums.txt. Weryfikacja sumy z pliku pobranego z tej samej, przejętej strony wydania niczego więc nie potwierdzała.

Przyczyna według producenta: w październiku 2025 deweloper zainstalował na prywatnym MacBooku rozszerzenie VS Code color-picker-universal 2.8.91. Portfel Solana używany przez to rozszerzenie OVHcloud uznaje za należący do grupy GlassWorm. Rok później skradzione w ten sposób dane posłużyły do podmiany wydań. Bezpośrednią przyczyną techniczną było to, że repozytorium nie miało włączonej niezmienialności wydań. OVHcloud włączył ją od razu w całej organizacji. Atrybucja do GlassWorm opiera się na wskaźniku (portfelu), a nie na pełnej analizie sprawcy. Szkic, z którego powstał ten wpis, nazywał ją hipotezą badaczy. W rzeczywistości to ustalenie samego producenta, choć oparte na jednym typie dowodu.

Ta sama wersja, inne bajty

Większość narzędzi VM i SCA zakłada, że para „nazwa pakietu + wersja” jednoznacznie identyfikuje artefakt. Tutaj tak nie było: ovhcloud-cli 0.15.0 przed 12:47 i po 12:57 to dwa różne pliki. Dlatego:

  • Skaner wersji nie pomoże w żadną stronę. Nie wykryje podmienionej kopii i nie odróżni jej od czystej kopii tej samej wersji pobranej tydzień wcześniej. Oznaczenie wszystkich instalacji v0.11–v0.15 jako zainfekowanych to fałszywe alarmy, a zignorowanie ich to przeoczenie.
  • CI z przypiętym SHA-256 zadziałało jak detektor. Problem wykrył użytkownik, którego pipeline przestał przechodzić, bo hash pobranego pliku nie zgadzał się z zapisanym. To najlepszy argument za przypinaniem hashy z niezależnego źródła, a nie z checksums.txt obok pliku.
  • Stały URL to ryzyko. Zadanie CI, które pobiera „v0.15.0” spod znanego adresu, w oknie incydentu pobrało złośliwy plik i uruchomiło go z sekretami pipeline’u.

Ten sam wzorzec opisywałem przy Rank Math PRO (CVE opisuje okno pobrania, nie wersję), AOMEI (kanał aktualizacji złośliwy przez kilka minut) i złośliwych wersjach npm, gdzie właściwe pytanie brzmi „czy build już wykonał malware”.

Homebrew, go install, Docker: co wiadomo

Producent nie rozpisuje kanałów instalacji. Pisze tylko, że kod źródłowy i pipeline budowania nie były naruszone, a podmiana dotyczyła plików w GitHub Releases. Z tego wynika, że build ze źródeł z oryginalnego tagu (np. go install przez proxy modułów) nie powinien być dotknięty. Reporter potwierdza, że proxy serwował oryginalny commit. BleepingComputer, powołując się na OpenSourceMalware, pisze, że obrazy Docker nie były dotknięte.

Homebrew: niepotwierdzone. Szkic VMRT Radar podawał, że instalacja przez Homebrew z przypiętym SHA-256 odrzucała podmieniony plik. Jeden z niezależnych opisów incydentu twierdzi natomiast, że użytkownicy Homebrew mogli otrzymać złośliwy plik z GitHuba. Nie sprawdziłem, czy formuła lub cask przypina hash i jak zachowała się w oknie. Do czasu wyjaśnienia traktuj instalacje i aktualizacje przez Homebrew z 19.10 jak każde inne pobranie: „do weryfikacji”.

Pobrany to nie to samo co wykonany

FAQ producenta stawia granicę jasno: jeśli ktoś pobrał lub zaktualizował CLI w oknie i uruchomił je, sekrety na tym komputerze należy uznać za skradzione. W przeciwnym razie nic się nie stało. Advisory daje do tego dwa praktyczne narzędzia, które nie wymagają uruchamiania podejrzanego pliku:

  • Hashe MD5 pięciu złośliwych binarek (po jednej na platformę) w załączniku advisory oraz linki do próbek w VirusTotal.
  • Katalog roboczy envchecker- z 9–10 cyframi w katalogu tymczasowym. Złośliwy kod tworzy go przy każdym uruchomieniu i nigdy nie usuwa. Jego obecność to mocny ślad wykonania, choć wyczyszczony katalog tymczasowy (restart, efemeryczny runner CI) da wynik fałszywie ujemny.

Na runnerach CI katalog tymczasowy zwykle nie przetrwał, więc ślad wykonania trzeba odtworzyć z historii zadań: czy pipeline 19.10 między 12:47 a 14:21 UTC pobierał CLI z GitHub Releases i go uruchamiał. W rejestrze VE rozdzieliłbym statusy tak:

Status w rejestrzeWarunekDziałanieKryterium zamknięcia
NienarażonyInstalacja ≤ v0.10.0 lub ≥ v0.16.0, albo v0.11–v0.15 pobrana przed 12:47 UTC 19.10, albo build ze źródeł / obraz DockerZapis źródła i daty pobraniaUdokumentowane pochodzenie artefaktu
Do weryfikacjiv0.11–v0.15 pobrana lub zaktualizowana 19.10, czas nieznany, platforma z listyPorównanie hasha z listą IoC bez uruchamiania, sprawdzenie katalogu envchecker-*Hash zgodny z oryginałem albo przejście do statusu niżej
Pobrany, nieuruchomionyHash złośliwy, brak śladów wykonaniaUsunięcie pliku, instalacja v0.16.0 lub nowszejCzysty artefakt w inwentarzu
WykonanyHash złośliwy i ślad uruchomienia (np. katalog envchecker-*, logi CI)IR: rotacja wszystkich sekretów dostępnych na hoście, przegląd użycia tokenówRozliczona rotacja i analiza dostępu

Co rotować

Lista celów w advisory jest szersza niż „klucze OVHcloud”. Złośliwy kod zbierał m.in.: dane uwierzytelniające i konfigurację AWS, Google Cloud i Azure, konfigurację Dockera, Kubernetes, npm i DigitalOcean, klucze SSH, poświadczenia Terraform, .netrc, globalny .gitconfig. Do tego bazy stanu VS Code i Cursor, dane rozszerzeń Continue i Sourcegraph Cody, lokalną bazę OpenCode, sesje agenta Hermes oraz katalog konfiguracji agenta Claude. Dane trafiały do archiwum wysyłanego na serwer napastnika, a adres serwera był pobierany przez zapytania RPC do sieci Solana.

Dla VM wynikają z tego dwie rzeczy. Po pierwsze, rotacja obejmuje wszystkich dostawców chmury i narzędzia, z których korzystał dany host, a nie tylko OVHcloud. Po drugie, bazy IDE i agentów AI to dziś magazyny sekretów: tokeny API modeli, historie rozmów z wklejonymi fragmentami konfiguracji, połączenia z serwerami MCP. Jeśli rejestr sekretów ich nie obejmuje, rotacja po takim incydencie będzie niepełna. Rotację prowadź z właścicielami usług i sprawdź w logach dostawców, czy tokeny nie zostały użyte z nieznanych adresów.

Co powinien zrobić VE

  1. Inwentarz: gdzie jest ovhcloud (stacje administratorów, runnery CI, obrazy narzędziowe) i jakim kanałem trafił: GitHub Releases, Homebrew, build ze źródeł, Docker.
  2. Okno: dla instalacji v0.11–v0.15 ustal czas pobrania. Źródła: logi proxy, historia CI, cache artefaktów, znaczniki czasu plików.
  3. Hash bez uruchamiania: porównaj z listą z advisory i sprawdź katalog envchecker-*. Nie uruchamiaj podejrzanej binarki, żeby sprawdzić wersję.
  4. Status i działanie: według tabeli wyżej. „Wykonany” oznacza IR i rotację, a nie tylko podmianę pliku.
  5. Docelowo: v0.16.0 lub nowsza z potwierdzonego źródła. Hashe przypięte we własnym repozytorium artefaktów, pobierane z niezależnego kanału, a w rejestrze dostawców pytanie o obiecany szczegółowy post-mortem.

Ten incydent pokazuje też, czego VM potrzebuje w danych o artefakcie: obok wersji także hash, kanał i datę pobrania oraz informację o uruchomieniu. Bez tych pól tego typu zdarzeń nie da się ocenić inaczej niż ręcznie. To samo wyzwanie, „podatność, której nie widzi skaner”, opisywałem przy Broadcom WPS.

Powiązane na blogu

Źródła

  • OVHcloud — GHSA-862f-55f5-vmvw (20.10.2026): oś czasu, zakres, liczba pobrań, wskaźniki, lista kradzionych plików, przyczyna, działania — github.com
  • ovh/ovhcloud-cli — issue #300 (19–20.10.2026): zgłoszenie z analizą binarki, odpowiedzi opiekunów — github.com
  • ovh/ovhcloud-cli — wydanie v0.16.0 (podpisany tag, wydanie niezmienialne) — github.com
  • BleepingComputer — opis incydentu i powiązanie z GlassWorm wg OpenSourceMalware (20.10.2026) — bleepingcomputer.com
  • GitHub Docs — Immutable releases — docs.github.com

Nota redakcyjna: wpis powstał na podstawie szkicu VMRT Radar z 20 października 2026 i został zweryfikowany ze źródłami pierwotnymi 20 października 2026 (ok. 19:00 CEST), a katalog CISA KEV sprawdziłem ponownie 22 października 2026 (wersja 2026.10.21, bez wpisów dla tego tematu). Źródła: advisory OVHcloud GHSA-862f-55f5-vmvw, publiczne issue #300 w repozytorium ovh/ovhcloud-cli wraz z odpowiedziami opiekunów oraz artykuł BleepingComputer. Względem szkicu doprecyzowałem, że powiązanie z GlassWorm to ustalenie samego OVHcloud (na podstawie portfela Solana), dodałem dane z advisory (oś czasu, około 250 pobrań, wskaźniki, lista celów, przyczyna) i oznaczyłem zachowanie Homebrew jako niepotwierdzone. Artykułu The Hacker News, na który powoływał się szkic, nie udało się pobrać. Nie potwierdziłem: ile z około 250 pobrań zostało uruchomionych, czy którykolwiek skradziony sekret został użyty, jak w oknie zachowała się instalacja przez Homebrew ani treści zapowiadanego szczegółowego post-mortem. Model statusów, kryteria zamknięcia i wnioski o bazach IDE i agentów AI jako magazynach sekretów to ocena autora, nie zalecenia OVHcloud. Wpis nie podaje adresów infrastruktury napastnika, są one w advisory producenta.

Zapamiętaj jedno

OVHcloud CLI v0.11.0–v0.15.0 przez 93 minuty 19 października miało pod tymi samymi adresami i numerami wersji złośliwe binarki. CVE nie ma, a skaner wersji nie odróżni czystej kopii od podmienionej. O narażeniu decyduje okno pobrania (12:47–14:21 UTC), platforma i to, czy plik uruchomiono. Sprawdzasz hash i katalog envchecker-* bez uruchamiania pliku. Jeśli binarka była wykonana, rotujesz wszystko, co było na hoście, łącznie z bazami IDE i agentów AI. Wykrył to ktoś, kto przypinał SHA-256 w CI, i to jest najtańsza kontrola z całej historii.