Firma Qualys wykryła lukę (CVE-2021-4034) w systemowym komponencie Polkit (dawniej PolicyKit), używanym w dystrybucjach do organizacji wykonywania działań przez użytkowników bez uprawnień, które wymagają podwyższonych praw dostępu. Luka umożliwia nieuprzywilejowanemu lokalnemu użytkownikowi podniesienie swoich uprawnień do roota i uzyskanie pełnej kontroli nad systemem. Problem ten otrzymał kodową nazwę PwnKit i jest notable z powodu przygotowania działającego exploita, który funkcjonuje w konfiguracji domyślnej w większości dystrybucji Linux.
Problem występuje w dołączonym do PolKit narzędziu pkexec, dostarczanym z flagą SUID root, które jest przeznaczone do uruchamiania poleceń z uprawnieniami innego użytkownika zgodnie z określonymi zasadami PolKit. Z powodu błędnego przetwarzania argumentów linii poleceń przekazywanych do pkexec, nieuprzywilejowany użytkownik mógł obejść autoryzację i uruchomić swój kod z prawami roota, niezależnie od ustalonych zasad dostępu. Dla ataku nie ma znaczenia jakie ustawienia i ograniczenia w PolKit zostały przypisane, wystarczy aby dla wykonywalnego pliku narzędzia pkexec był ustawiony znacznik SUID root.
Pkexec nie sprawdza poprawności licznika argumentów linii poleceń (argc) przekazywanych podczas uruchamiania procesu. Wydawcy pkexec zakładali, że pierwszy element tablicy argv zawsze zawiera nazwę procesu (pkexec), a drugi albo NULL, albo nazwę uruchamianego przez pkexec polecenia. Ponieważ licznik argumentów nie był weryfikowany pod kątem zgodności z faktyczną zawartością tablicy i zakładano, że zawsze jest większy od 1, w przypadku przekazania do procesu pustej tablicy argv, co jest dozwolone przez funkcję execve w Linux, pkexec traktował wartość NULL jako pierwszy argument (nazwę procesu), a następnie pamięć poza buforem jako dalszą zawartość tablicy. |———+———+——+————|———+———+——+————| | argv[0] | argv[1] | … | argv[argc] | envp[0] | envp[1] | … | envp[envc] | |—-|—-+—-|—-+——+——|——|—-|—-+—-|—-+——+——|——| V V V V V V «program» «-option» NULL «value» «PATH=name» NULL
Problem polega na tym, że zaraz po tablicy argv w pamięci znajduje się tablica envp, zawierająca zmienne środowiskowe. W ten sposób, w przypadku pustej tablicy argv, pkexec pobiera dane o wykonywanym z podwyższonymi uprawnieniami poleceniu z pierwszego elementu tablicy zmiennych środowiskowych (argv[1] staje się identyczne z envp[0]), którego zawartość może kontrolować atakujący.
Po uzyskaniu wartości argv[1], pkexec próbuje, uwzględniając ścieżki plików w PATH, określić pełną ścieżkę do pliku wykonywalnego i zapisać wskaźnik na ciąg z pełną ścieżką z powrotem do argv[1], co prowadzi do nadpisania wartości pierwszej zmiennej środowiskowej, ponieważ argv[1] jest identyczne z envp[0]. Poprzez manipulację nazwą pierwszej zmiennej środowiskowej, atakujący może zamienić inną zmienną środowiskową w pkexec, na przykład zmienną środowiskową „LD_PRELOAD”, która nie jest dozwolona w programach suid, i zorganizować załadunek swojej dzielonej biblioteki do procesu.
W działającym exploicie następuje podstawienie zmiennej GCONV_PATH, która służy do określenia ścieżki do biblioteki kodowania znaków, ładowanej dynamicznie podczas wywołania funkcji g_printerr(), w kodzie której używana jest iconv_open(). Nadpisując ścieżkę w GCONV_PATH, atakujący może wymusić załadunek nieoficjalnej biblioteki iconv, a jej obsługi będą realizowane w czasie wyświetlania komunikatu o błędzie, gdy pkexec wciąż działa z uprawnieniami root i zanim sprawdzone zostaną uprawnienia uruchomienia.
Zauważono, że pomimo tego, że problem spowodowany jest uszkodzeniem pamięci, można go niezawodnie i powtarzalnie eksploatować, niezależnie od używanej architektury sprzętowej. Przygotowany exploit został pomyślnie przetestowany w systemach Ubuntu, Debian, Fedora i CentOS, ale może być również używany w innych dystrybucjach. Oryginalny exploit nie jest obecnie dostępny publicznie, co świadczy o tym, że jest trywialny i może być łatwo odtworzony przez innych badaczy, dlatego w systemach wieloosobowych ważne jest, aby jak najszybciej zainstalować aktualizację z poprawką. Polkit jest również dostępny dla systemów BSD i Solaris, ale badania nad możliwością eksploatacji w nich nie były prowadzone. Wiadomo jedynie, że atak nie może być przeprowadzony w OpenBSD, ponieważ jądro OpenBSD nie pozwala na przekazywanie zerowej wartości argc przy wywołaniu execve().
Problem istnieje od maja 2009 roku, od czasu wprowadzenia polecenia pkexec. Poprawka dla luki w PolKit jest obecnie dostępna w postaci łatki (poprawny wydanie nie zostało jeszcze utworzone), ale ponieważ deweloperzy dystrybucji zostali wcześniej poinformowani o problemie, większość dystrybucji opublikowała aktualizację równocześnie z ujawnieniem informacji o luce. Problem został naprawiony w RHEL 6/7/8, Debianie, Ubuntu, openSUSE, SUSE, Fedora, ALT Linux, ROSA, Gentoo, Void Linux, Arch Linux i Manjaro. Jako tymczasowe rozwiązanie w celu zablokowania luki można usunąć flagę SUID root z programu /usr/bin/pkexec („chmod 0755 /usr/bin/pkexec”).
Źródło: opennet.ru
