Backdoor xz: nadchodzą zmiany w OpenSSH i systemd
Skuteczne umieszczenie tylnej furtki w bibliotece xz/liblzma było bliskie realizacji ze względu na przepracowanych opiekunów projektu i zastosowanie binarnych plików. Ale liblzma było tylko nośnikiem. Prawdziwą ofiarą było OpenSSH, a było to możliwe przez systemd.
Backdoor CVE-2024-3094, załadowany do pamięci, zmienia stan serwera SSH. Ale żeby było to możliwe, serwer sam musi załadować bibliotekę liblzma, w której ten backdoor się znajduje. A jest ona ładowana tylko dlatego, że jest zależnością wykonawczą innej biblioteki, libsystemd.
Czy OpenSSH ładuje ją sam? Nie… OpenSSH nie jest zależne od systemd samo z siebie. Byłoby to osobliwe zachowanie oprogramowania rozwijanego w ramach OpenBSD, gdzie podejście do bezpieczeństwa jest dość ortodoksyjne. Zależność od systemd jest obecna u odbiorców OpenBSD, takich jak Fedora Project.
Dalsza część artykułu pod materiałem wideo
Obsługa mechanizmu systemd-notify, dodana jest do serwera na potrzeby informowania systemd o zakończeniu jego aktywacji. Systemd może określać gotowość usługi do pracy na podstawie komunikatów, a nie tylko na podstawie uruchomienia procesu. Samo działanie procesu nie musi bowiem oznaczać, że serwer potrafi już poprawnie obsługiwać połączenia. W praktyce jednak, systemd-notify rozwiązuje problem, gdzie systemd zakłada zbyt wiele na temat procesu i śledzi stan na podstawie przesłanek, które nie zawsze są słuszne.
Choć repozytorium OpenSSH zawiera sekcję "contrib", służącą do adaptowania serwera na potrzeby odbiorców, nie ma w niej pliku definicji usługi. Ten pochodzi z Projektu Fedora i to tam dodawany jest wpis o typie uruchomienia "notify". Obsługa powiadomień wciąga zależność od libsystemd, otwierającą pole do działania wykrytemu niedawno backdoorowi xz. Jeżeli bez obsługi systemd nie ma problemu, to szczególnie interesujące jest, co o tym myślą obie zainteresowane strony: projekt OpenSSH i opiekun systemd - Lennart Poettering.
systemd vs OpenBSD
Odpowiedź z systemd można odnaleźć w komentarzach w dyskusji na Hacker News. Poettering stwierdził, że cały problem nie wystąpiłby, gdyby aplikacje same implementowały protokół powiadamiania systemd, bez konieczności ładowania w tym celu bibliotek. Choć stwierdzenie to może się początkowo wydawać nieco aroganckie, jest w nim wiele racji. Po pierwsze, protokół sd_notify jest zawrotnie prosty w implementacji. Po drugie, wcale nie musiałby tego robić projekt OpenSSH - mógłby to być kolejny patch w SRC.RPM Fedory.
I tutaj interesująca jest decyzja po stronie OpenSSH, do którego zaproponowano zaimplementowanie obsługi systemd-notify. Po siedmiu latach, dyskusja została odkurzona i zaproponowano nową poprawkę, dodającą wysyłanie komunikatów sd_notify, odblokowywaną poprzez opcjonalny parametr środowiska budowania (--with-systemd-notify). Poprawka została zaakceptowana (!) i obsługa systemd pojawi się w OpenSSH 9.8 na przełomie czerwca i lipca.
"Brzydkie, ale działa"
Trwające wiele lat, ogólnoświatowe patchowanie OpenSSH by nadawało się do użytku z systemd, nieco przerażające, dobiegnie teraz końca. Ładowanie ciężkich bibliotek do generowania prostych powiadomień zakończy się. Łatanie cudzych błędów we własnych projektach nie jest rzadkie - jest zaakceptowaniem stanu faktycznego i trwa od lat. Tak jak kiedyś naprawiano błędy Adobe'a w bibliotece glibc, dziś naprawia się błędy Hyper-V w kernelu Linuksa. A słabości systemd - w OpenSSH.
Nie oznacza to, że obyło się bez zmian w systemd. Ładowanie bibliotek kompresorów będzie się teraz odbywać za pomocą dlopen(), a więc pojawią się one w pamięci tylko gdy są naprawdę używane. Nie jest to cudowne panaceum, bowiem środowisko wykonawcze staje się w ten sposób mniej przewidywalne. Ale uchroni przyszłe wersje OpenSSH przed rodzajem nadużyć znanym z wykrytego niedawno backdoora.
Kamil J. Dudek, współpracownik redakcji dobreprogramy.pl