← Wszystkie wpisy

Bomba forkowa nas uratowała

Złośliwe oprogramowanie w LiteLLM 1.82.8 zawierało plik .pth, który uruchamiał się przy każdym starcie Pythona. Zbierało klucze SSH, poświadczenia chmurowe, portfele kryptowalutowe i sekrety CI/CD, szyfrowało je 4096-bitowym kluczem RSA, po czym wysyłało archiwum do domeny kontrolowanej przez napastnika. Ładunek był dobrze zaprojektowany. Szyfrowanie — poprawne. Eksfiltracja — czysta.1 Ten incydent należy do mojej serii bezpieczeństwo agentów, poświęconej rzeczywistym porażkom, które kształtują sposób budowania zaufania do systemów zautomatyzowanych.5

Plik .pth uruchamiał jednak proces potomny Pythona, żeby wykonać swoje zadanie. Ten proces potomny ponownie wyzwalał plik .pth. Co uruchamiało kolejny proces potomny. Który znów go wyzwalał. Wykładnicza bomba forkowa, która w kilka sekund pochłaniała 100% CPU i ponad 5 GB RAM.2

Bomba forkowa była błędem. Napastnik nie chciał, żeby złośliwe oprogramowanie było widoczne. Poprawnie napisana wersja działałaby po cichu przy każdym wywołaniu Pythona w każdym zainfekowanym systemie, potencjalnie przez tygodnie. Zamiast tego programiści zauważyli, że ich maszyny stają w miejscu, zaczęli drążyć sprawę i znaleźli złodzieja poświadczeń. PyPI objęło kwarantanną obie wersje 46 minut po publikacji.1

Czterdzieści sześć tysięcy instalacji w czterdzieści sześć minut. Mechanizmem wykrycia był błąd implementacyjny w samym złośliwym kodzie.

Kiedy zależność agenta AI instaluje pakiet zawierający bombę forkową, wykładnicze mnożenie procesów pochłania 100% CPU i gigabajty RAM w ciągu kilku sekund, czyniąc maszynę bezużyteczną. W przypadku LiteLLM 1.82.8 ta przypadkowa bomba forkowa była jedynym powodem, dla którego wykryto ładunek wykradający poświadczenia: programiści zauważyli, że maszyny stają w miejscu, i zaczęli to badać. Bez tego błędu złośliwe oprogramowanie po cichu wyprowadzałoby klucze SSH, poświadczenia chmurowe i portfele kryptowalutowe przez tygodnie, zanim ktokolwiek by je odkrył.

W skrócie

  • Błąd: złodziej poświadczeń w LiteLLM 1.82.8 miał błąd bomby forkowej, przez który zainfekowane maszyny stawały w miejscu. Bez niego działałby po cichu przez tygodnie.
  • Luka: analiza statyczna, monitorowanie zachowań i przegląd kodu — wszystkie te warstwy przeoczyły atak. Każda z nich zakładała, że złapie go inna. Żadna nie złapała.3
  • Krzywa: jakość po stronie napastnika rośnie z każdą iteracją. Technika .pth jest już publicznie udokumentowana. Kolejny napastnik przejmie ją bez tego błędu.
  • Co działa bez łutu szczęścia: sprawdzanie wieku domeny przy ruchu wychodzącym, budowanie profilu bazowego zachowań dla instalacji pakietów, pułapki w systemie plików, izolacja instalacji. Każde z tych rozwiązań działa niezależnie od jakości ładunku.
  • Asymetria: to obrońca wybiera środowisko. Jeśli w środowisku instalacyjnym nie ma poświadczeń do kradzieży, nawet doskonały ładunek nie zbierze niczego.

Mieliśmy szczęście

Wystarczy usunąć bombę forkową z ładunku, a atak przebiega niezauważenie. Plik .pth uruchamia się przed jakimkolwiek importem, przed kodem aplikacji, przed jakąkolwiek piaskownicą na poziomie Pythona. Nie ma tu punktu zaczepienia. Nie ma wpisu w logach. Złodziej poświadczeń działa, szyfruje, wyprowadza dane, a proces Pythona toczy się dalej jak gdyby nigdy nic. Programista nie widzi niczego. Pipeline CI nie widzi niczego. Skaner bezpieczeństwa nie widzi niczego, bo to właśnie skaner bezpieczeństwa był wektorem ataku.3

Historia wykrycia LiteLLM 1.82.8 nie brzmi: „nasz monitoring to złapał”. Brzmi: „napastnik wypuścił kod z błędem”.

To niewygodny fundament dla bezpieczeństwa łańcucha dostaw. Jak dowodzę w tekście piaskownica agenta to tylko sugestia, granice, które rzekomo dzielą kod zaufany od niezaufanego, są znacznie bardziej przepuszczalne, niż sądzi większość zespołów.

Krzywa jakości po stronie napastnika

Jakość oprogramowania rośnie z każdą iteracją. Dotyczy to zarówno napastników, jak i obrońców. Kampania TeamPCP uderzyła w pięć ekosystemów w ciągu tygodnia: GitHub Actions, Docker Hub, npm, Open VSX i PyPI.4 Każde kolejne włamanie wykorzystywało poświadczenia zebrane w poprzednim. Kampania pokazała operacyjną biegłość: rejestrację domeny 24 godziny przed dostarczeniem ładunku, przejmowanie tagów na zmiennych referencjach oraz omijanie rotacji poświadczeń dzięki niepełnej wymianie kluczy w Aqua Security.

Bomba forkowa była jedyną wpadką w skądinąd sprawnie przeprowadzonej operacji. Następna kampania tego błędu nie popełni. Technika z plikiem .pth jest już publicznie udokumentowana i przeanalizowana przez CrowdStrike, Microsoft, Wiz i Palo Alto.3 Kolejny napastnik dziedziczy tę technikę już bez błędu.

Zdolności ofensywne podlegają tej samej krzywej doskonalenia co zdolności obronne. Technika jest jawna. Analiza jest jawna. Następny napastnik startuje tam, gdzie TeamPCP skończył. Co ta krzywa oznacza dla systemów autonomicznych, rozwijam w tekście co naprawdę psuje się bez nadzoru.

Detekcja nie może opierać się na błędach napastnika

Obecny model wykrywania zagrożeń w łańcuchu dostaw ma trzy warstwy i wszystkie trzy zawiodły w przypadku LiteLLM:

Analiza statyczna ataku nie wykryła. Plik .pth to legalna funkcja Pythona. Ładunek był podwójnie zakodowany w base64 i dekodowany w trakcie działania. Statyczne skanery szukające znanych złośliwych wzorców nie znajdują niczego, bo wzorzec jest nowy.

Monitorowanie zachowań go nie wychwyciło. Złodziej poświadczeń wykonał jedno wychodzące żądanie HTTPS POST do domeny wyglądającej na legalną usługę (models.litellm.cloud). Monitorowanie ruchu wychodzącego oparte na inspekcji domen docelowych musiałoby wiedzieć, że akurat ta domena została zarejestrowana 24 godziny wcześniej. Większość takich rozwiązań nie sprawdza wieku domeny.

Przegląd kodu również zawiódł. Złośliwe wersje trafiły bezpośrednio do PyPI, z pominięciem całego pipeline’u CI/CD na GitHubie. Nie było pull requesta do przejrzenia. Nie było diffa do sprawdzenia. Napastnik użył wykradzionych poświadczeń publikacyjnych, żeby wgrać gotowe pakiety.

Każda warstwa detekcji zakładała, że problem wychwyci inny fragment łańcucha ataku. Żadna go nie wychwyciła. Wychwyciła go bomba forkowa.

Co naprawdę wykrywa ciche złośliwe oprogramowanie

Skoro nie można liczyć na błędy napastnika, potrzebne są mechanizmy detekcji działające niezależnie od jakości implementacji.

Sprawdzanie wieku domeny przy żądaniach wychodzących. Domena eksfiltracyjna została zarejestrowana 24 godziny przed atakiem. Reguła firewalla oznaczająca ruch wychodzący do domen młodszych niż 7 dni złapałaby ten przypadek. Reguła jest prosta, odsetek fałszywych alarmów da się opanować, a wychwytuje najczęstszy schemat eksfiltracji.

Profil bazowy zachowań procesów Pythona. pip install, który nagle wysyła żądania HTTPS POST do nieznanej domeny, to anomalia. Monitorowanie zachowań na poziomie procesu, śledzące aktywność sieciową podczas instalacji pakietów, oznaczyłoby taki przypadek.

Pułapki w systemie plików. Warto umieścić fałszywy klucz SSH w jednej ścieżce-pułapce, a fałszywe poświadczenie AWS w innej. Następnie monitorować, czy jakikolwiek proces czyta te pliki. Złodziej poświadczeń przeczesujący standardowe ścieżki odczyta pułapki. Legalny proces tego nie zrobi. Pułapka wyzwala alert, zanim eksfiltracja dobiegnie końca.

Izolacja instalacji. pip install należy uruchamiać w środowisku bez dostępu do prawdziwych poświadczeń, a zainstalowane pakiety przenosić do środowiska produkcyjnego dopiero potem. Plik .pth odpala się w procesie Pythona uruchamianym przez samo narzędzie pip, co oznacza, że złodziej poświadczeń działa w trakcie instalacji. Jeśli w środowisku instalacyjnym nie ma poświadczeń do kradzieży, atak niczego nie zbierze.

Żaden z tych mechanizmów nie wymaga, by napastnik popełnił błąd. Działają niezależnie od jakości ładunku. Ten wzorzec architektoniczny — projektowanie środowisk, w których nawet doskonały atak niczego nie zbierze — stoi też za tekstem wdrażać i bronić: paradoks zaufania do agentów.

Asymetria

Obrona ma jedną strukturalną przewagę: to obrońca wybiera środowisko. Napastnik musi działać w tym, do którego zainstalowano pakiet. Jeśli nie ma tam poświadczeń ani dostępu do sieci, a w systemie plików czają się pułapki, ładunek odnosi sukces techniczny, ale operacyjnie ponosi porażkę.

Atak na LiteLLM powiódł się dlatego, że środowiskiem instalacyjnym było to samo środowisko, w którym trzymano poświadczenia publikacyjne, klucze SSH i tokeny chmurowe. Dla architektury bezpieczeństwa bomba forkowa nie miała znaczenia. Miała je dla przebiegu wydarzeń.

Następnym razem bomby forkowej nie będzie. Poświadczenia wciąż będą leżeć w tym samym środowisku co menedżer pakietów. Pytanie brzmi, czy uda się zmienić to środowisko, zanim kolejny napastnik wypuści czysty ładunek. Moja analiza architektury agenta Ralph pokazuje, jak budować systemy agentowe tak, aby przejęte komponenty nie mogły wyjść poza własną granicę izolacji.


FAQ

Dlaczego napastnik nie przetestował bomby forkowej?

Uruchamianie ładunku w procesie potomnym z pliku .pth to rozsądny wybór implementacyjny, jeśli nie chce się blokować procesu nadrzędnego. Rekurencyjne wyzwolenie to subtelna interakcja między .pth a inicjalizacją site.py w Pythonie. To rodzaj błędu, który ujawnia się w testach integracyjnych, ale nie w jednostkowych, a autorzy złośliwego oprogramowania mają ograniczone możliwości testowania integracyjnego w realistycznych warunkach.

Czy bomba forkowa mogła być zamierzona?

Mało prawdopodobne. Bomba forkowa natychmiast ujawniła złośliwe oprogramowanie, co jest odwrotnością celu napastnika. Cichy złodziej poświadczeń działający tygodniami zbiera o rzędy wielkości więcej poświadczeń niż taki, którego wykrywa się w 46 minut.

Czy sprawdzanie wieku domeny jest praktyczne w dużej skali?

Tak. Wiek domeny jest dostępny przez WHOIS lub API z datami rejestracji DNS. Sprawdzenie dokłada milisekundy opóźnienia na żądanie. Większość organizacji może dodać znane nowe domeny do białej listy.


Źródła


  1. FutureSearch (Daniel Hnyk), “LiteLLM Hack: Were You One of the 47,000?” marzec 2026. 

  2. isfinne i in., “LiteLLM Supply Chain Attack,” GitHub Issue #24512, marzec 2026. 

  3. Blake Crosley, “The Supply Chain Is the Attack Surface,” blakecrosley.com, marzec 2026. 

  4. Kaspersky, “Trojanization of Trivy, Checkmarx, and LiteLLM Solutions,” marzec 2026. 

  5. Blake Crosley, “When Your Agent Becomes the Researcher,” blakecrosley.com, marzec 2026. 

Powiązane artykuły

Pański agent ma pośrednika, którego Pan nie zweryfikował

Badacze przetestowali 28 routerów LLM API: 17 sięgnęło po pułapkowe poświadczenia AWS, jeden opróżnił portfel ETH. Route…

11 min czytania

Łańcuch dostaw to powierzchnia ataku

Trivy został skompromitowany. Potem LiteLLM. Potem 47 000 instalacji w 46 minut. Łańcuch dostaw AI zadziałał dokładnie t…

16 min czytania

Pętla Ralph: jak uruchamiam autonomiczne agenty AI na noc

Zbudowałem system autonomicznych agentów z hookami zatrzymania, budżetami spawnowania i pamięcią opartą na plikach. Co z…

6 min czytania