2 października o 9:34 UTC dwa przekaźniki wyjściowe sieci Tor opublikowały nową politykę wyjścia, której nikt z ich operatorów nie wpisał. Tego samego ranka 333 węzły wyjściowe zaczęły przekierowywać ruch SSH do dwunastu serwerów przechwytujących, a jednocześnie blokowały porty szyfrowanej poczty (25, 465, 587, 993, 995), zostawiając otwarte te nieszyfrowane. Napastnicy byli w środku od 28 sierpnia, od 3:19 nad ranem, kiedy zalogowali się na serwer zarządzający za pierwszym razem, poprawnym hasłem, bez jednej nieudanej próby.
Interesujące jest nie to, co napastnicy zrobili, tylko to, czego nie wykryła żadna standardowa metoda sprawdzania serwera.
Lista kontrolna z oficjalnego ostrzeżenia dała zero trafień
5 października zespół Tor Project rozesłał operatorom ostrzeżenie z listą rzeczy do sprawdzenia: reguły NAT przekierowujące port 22, nowi użytkownicy i wpisy w authorized_keys, zadania cron, jednostki systemd, zmiany w pliku torrc, weryfikacja binarki tor względem pakietu dystrybucji. Operator dwóch faktycznie przejętych maszyn (relaye z rodziny Quetzalcoatl) przeszedł tę listę punkt po punkcie i opisał wynik na liście tor-relays: żaden z tych wskaźników nie wystąpił. Ani NAT, ani nowe konta, ani cron, ani podmieniona binarka.
Weryfikacja pakietów też była czysta, i to nie przez przypadek. Implant to pojedynczy plik z bitem setuid, libkeyutils.so.1.10.2 o rozmiarze 63 368 bajtów, do którego przestawiono dowiązanie libkeyutils.so.1. Oryginalna biblioteka z pakietu pozostaje nietknięta, więc dpkg -V i debsums nie mają czego zgłosić, a sumy kontrolne sshd, sudo i PAM zgadzały się na obu serwerach. Na Debianie 13 bibliotekę ładuje sshd-session przez libkrb5, dlatego proces nasłuchujący sshd wygląda poprawnie także pod ldd.
Zawiodło również narzędzie uznawane za referencyjne. Publiczne wskaźniki ESET dla Ebury kończą się na wersji 1.8.2 i maju 2024 roku, a tutaj działała 1.8.3: nazwy gniazda abstrakcyjnego, którego używa kolektor haseł, nie ma na ich liście, a skrypt detect_ebury.sh tej instalacji nie oznaczył (regułę YARA dopasowaną do konstruktora w libkeyutils nadal trafiała). Każda instalacja wstrzykuje do pliku ośmiobajtowy identyfikator ofiary, więc hasz implantu jest inny na każdym serwerze. Szukanie po sumach kontrolnych z gotowego feedu nie miało prawa zadziałać.
Do tego dochodzi warstwa zacierania śladów: logowania przez backdoora omijają PAM i historię powłoki, 30 września napastnik zrestartował sshd tak, że przestał zapisywać linie o zaakceptowanych logowaniach, część logów na serwerze zarządzającym została obcięta, a daty podrzuconych plików sfałszowane. Operator trafił na intruza po śladach pośrednich: operacjach roota bez odpowiadającego im wpisu sudo, transakcjach apt bez pola Requested-By, sesjach su otwartych przez uid 0 i przeładowaniach Tora, o które nikt z zespołu nie prosił.
Wykryła to obserwacja z zewnątrz, nie audyt hosta
Pierwszy sygnał nie przyszedł z serwera, tylko z sieci. Zespół network health Tor Project zauważył, że opublikowany deskryptor relayów różni się od tego, co operator wdrożył, i sam zapytał go o zmianę polityki wyjścia. Operator potwierdził, że jej nie wprowadzał. Wcześniej, 2 października, niezależny badacz wykrył przekierowanie SSH w najprostszy możliwy sposób: skryptem na bazie exitmap przepuścił własne połączenie SSH przez każdy z około trzech tysięcy węzłów wyjściowych i sprawdzał dwie rzeczy, czy odcisk klucza serwera jest ten co trzeba i czy połączenie dociera z zadeklarowanego węzła. Kilkanaście węzłów podawało fałszywy odcisk, ponad trzysta przekierowywało ruch przez te same serwery pośredniczące.
Obie metody mają wspólną cechę: porównują stan zadeklarowany ze stanem obserwowanym spoza maszyny. Pliki na przejętym serwerze można przepisać, logi obciąć, a narzędzia diagnostyczne okłamać, bo infekcja siedzi wewnątrz procesów, które je uruchamiają. Tego, co widzi klient po drugiej stronie połączenia, przejęty host już nie kontroluje. Otwarta polityka działała około 52 godzin na dwóch relayach przepuszczających mniej więcej 3,4 TiB dziennie.
Dziesięć procent węzłów to nie dziesięć procent ruchu
Liczba 333 krąży w relacjach jako „około 10 procent węzłów wyjściowych Tora”. Sprawdziłem, ile ta proporcja dziś znaczy. W konsensusie opublikowanym 23 października o 18:00 UTC (dane z Onionoo, zapytanie o działające relaye z flagą Exit) jest ich 2725, więc 333 węzły to dzisiaj 12,2 procent ich liczby. Tyle że liczba węzłów jest kiepskim licznikiem: 50 procent prawdopodobieństwa wyjścia przypada na 580 przekaźników, czyli 21 procent z nich, a trzy największe podmioty w zestawieniu po operatorze autonomicznym systemu (Church of Cyberology, Stiftung Erneuerbare Freiheit, Quintex Alliance Consulting) obsługują razem blisko połowę ruchu wyjściowego. Ten sam pomiar potwierdza, że oba przejęte relaye Quetzalcoatl zniknęły z danych sieci.
Koncentracja działa też w drugą stronę i stąd bierze się najpoważniejsze otwarte pytanie tego incydentu. Jak nie wiadomo, skąd napastnicy mieli dostęp do kilkuset maszyn naraz, tak wiadomo, że według zestawienia badacza 26 z 27 pozostałych przejętych relayów stało u jednego dostawcy. Hipoteza o włamaniu na poziomie hostingu jest tylko hipotezą, inni klienci tego dostawcy nie zgłosili niczego podobnego. Zostaje fakt, który jest jednocześnie wskazówką dla każdego, kto rozkłada własną infrastrukturę: dywersyfikacja po lokalizacjach nie jest dywersyfikacją, jeśli wszystkie maszyny kupujesz u jednego operatora i wszystkie ufają temu samemu kluczowi.
Przyczyną źródłową było jedno hasło
Operator opisał to bez owijania: jedno hasło do logowania SSH, do sudo i jako hasło szyfrujące kopię zapasową, trzymane dodatkowo otwartym tekstem w skrypcie pomocniczym na obu serwerach. Na serwerze zarządzającym, wystawionym do internetu, było włączone uwierzytelnianie hasłem. W kopii zapasowej stacji roboczej, leżącej na tym samym serwerze, znajdowały się klucz prywatny operatora, inwentarz Ansible i kopie kluczy głównych Ed25519 relayów, czyli materiał, który z założenia miał być offline. Napastnik rozszyfrował metadane tej kopii 6 września.
Trzy rzeczy, które warto przenieść do siebie:
- Wyłącz logowanie hasłem na maszynach zarządzających i sprawdź efektywną konfigurację przez sshd -T, a nie przez przeczytanie własnego pliku. W tym incydencie wpis PermitRootLogin yes z obrazu dostawcy, zostawiony na początku pliku, wygrywał z PermitRootLogin no dopisanym na końcu przez skrypt wdrożeniowy.
- Wynieś z serwerów sekrety, które są jednocześnie hasłem do sudo i do kopii zapasowych. W świecie Windows odpowiednikiem tego błędu jest współdzielone hasło administratora lokalnego i tam rozwiązaniem jest LAPS, w świecie Linuksa automatyzacja na kluczach i wąsko zakresowane reguły sudo.
- Monitoruj swoje usługi z zewnątrz i alarmuj, gdy opublikowany stan różni się od wdrożonego. To jedyna kontrola z tej historii, która zadziałała, i dokładnie ta, której najczęściej brakuje.
Dla użytkownika końcowego wniosek jest krótszy. Ostrzeżenie REMOTE HOST IDENTIFICATION HAS CHANGED zadziałało dokładnie tak, jak miało: badacz zobaczył je, zanim wpisał hasło. Kto je klika na oślep, oddaje napastnikowi hasło, podgląd wpisywanych poleceń i instalację Ebury na własnym serwerze, bo tak wyglądał łańcuch u ofiar, które warning zignorowały.
Pytanie o finansowanie Tora jest tu nie na miejscu
Przy każdym takim incydencie wraca argument, że Tor jest finansowany przez rząd USA. Liczby z audytu za rok obrotowy 2023/2024 są publiczne: przy przychodzie 7 287 566 dolarów wykazanym w formularzu 990 rząd USA odpowiadał za 35,08 procent, rządy spoza USA za 7,58 procent, razem nieco ponad 42 procent, reszta to firmy, fundacje i darowizny indywidualne. Jednym z projektów finansowanych przez Departament Stanu jest zresztą „Combating Malicious Relays”, czyli ograniczanie aktywności złośliwych przekaźników.
Do tego incydentu nic z tego nie wnosi, bo model zagrożeń Tora od początku zakłada, że węzły wyjściowe są wrogie. Przejęte relaye nie złamały szyfrowania warstwy transportowej i nie zdjęły anonimowości: zbierały to, co użytkownik sam wypuścił bez szyfrowania, i liczyły na to, że ktoś przeklika ostrzeżenie o zmianie klucza. Nie wiadomo nawet, czy próby wymuszenia nieszyfrowanej poczty skończyły się powodzeniem. Jeśli szukasz w tej historii kontroli, która ochroniła ludzi, to był nią klient SSH, a nie struktura przychodów organizacji.