Dwudziestoletnia luka w usługach tekstowych Windows pozwala na eskalację uprawnień
W ramach inicjatywy Google Project Zero opublikowano niedawno zaskakujący i bardzo rzetelny artykuł na temat komponentu Windows odpowiedzialnego za obsługę tzw. zaawansowanych usług tekstowych (CTF). W architekturze i zachowaniu owego składnika odnaleziono szereg słabości, umożliwiających "porwanie" okna i wykorzystanie go do podniesienia uprawnień (uruchomienia kodu na prawach bardziej uprzywilejowanego użytkownika). Autorem opracowania jest angielski specjalista ds. zabezpieczeń Tavis Ormandy, znany między innymi z odnalezienia luk bezpieczeństwa u dostawcy infrastruktury CloudFlare.
Dziurawy CTFMON
Podatność została odnaleziona w programie-usłudze CTFMON.EXE. Jest to monitor odpowiedzialny za informowanie aplikacji o zmianach w trybie wprowadzania tekstu, np. przełączeniu układu klawiatury. Program ten jest obciążony solidnym bagażem archaicznego i pełnego wyrzeczeń kodu, głównie ze względu na historię swojego pochodzenia. To doskonały przykład klątwy, która ciąży nad wieloma składnikami Windows: CTFMON powstał między innymi po to, by aplikacje pakietu Office były w stanie udźwignąć rosnącą złożoność mechanizmów wprowadzania tekstu, zarówno pod względem sprzętowym (HID), tekstowym (CTF) oraz alfabetycznym (IME). Nowa, rozbudowana funkcjonalność została po raz pierwszy wprowadzona w pakiecie Office XP.
Mało znanym faktem na temat pakietu Office XP jest to, że działał on również na systemie Windows 98. Podczas gdy klasyczne systemy Windows (a więc te oparte o MS-DOS i VMM) nie obsługiwały bardzo wielu rzeczy dostępnych w nowocześniejszych systemach NT. Należą do nich uprawnienia, przywileje, usługi, wbudowane mechanizmy wprowadzania oraz taki detal, jak Unicode. Z tego powodu, warstwa obsługi metod wprowadzania nie została zaimplementowana jako nowe API albo usługa NT, a jako "zwykły", działający w przestrzeni użytkownika program. Wszystko dlatego, że Microsoft bał się zerwać zgodność z Windows 98 tak szybko. Przyszedł na to czas dopiero nieco ponad rok później.
Eskalacja uprawnień w ramach sesji
Na czym polega problem z programem CTFMON? Aby zrozumieć naturę podatności, należy prześledzić sposób, w jaki Ormandy dokonał swojego odkrycia. Postawił on pytanie, czy jest możliwa komunikacja między oknami, gdy należą one do dwóch użytkowników o różnych prawach (np. kamilek oraz SYSTEM, wielkipiec i Administrator, DWM-1 i TrustedInstaller). Dokumentacja mechanizmów izolacji uprawnień informuje, że komunikacja między różnymi uprawnieniami jest zakazana, chyba że dotyczy komunikatów należących do krótkiej listy dozwolonych, "bezpiecznych" sygnałów. Środowisko komunikacji jest zapewniane przez przestrzeń NT USER32 w ramach NtUserPostMessage.
Rodzaje komunikatów mają oczywiście swoje identyfikatory. Ormandy zdecydował się więc posłać wiadomości o wszystkich możliwych wartościach identyfikatora, ignorować awarie i zobaczyć, czy lista "dopuszczalnych" pokrywa się z listą tych, które zadziałały. To żmudna praca i dla wielu ludzi pozbawionych wyobraźni (co jest wbrew pozorom powszechną plagą w branży IT, zwłaszcza wśród skostniałych fachowców uznających się za "pragmatyków) – strata czasu. Tymczasem okazało się, że istnieje nieudokumentowany rodzaj wiadomości przepuszczanych przez okna mimo różnicy uprawnień.
Niniejsze komunikaty są wiadomościami wysyłanymi przez monitor CTF. Działa to w następujący sposób: każdy nowy "pulpit", czyli nowe interaktywne zalogowanie się do systemu jako użytkownik, tworzy nową sesję programu CTFMON. Każdy skomplikowany mechanizm wprowadzania, czyli np. pismo odręczne pisane piórem cyfrowym lub edytor chińskich znaków, potrzebuje pośrednika zajmującego się tłumaczeniem wejścia na rozkazy dla edytora (nie piszemy bowiem bezpośrednio). CTFMON odpowiedni dla danej sesji zajmuje się zorganizowaniem właśnie takiej warstwy pośredniczącej. Aby każdy program mógł się dogadać z takim złożonym mechanizmem wejścia, każde nowe okno w sesji woła funkcję CtfHookProcWorker(), odpowiedzialną za zgłoszenie go do zarządcy CTF.
Niekontrolowany mechanizm komunikacji
To jeszcze nic strasznego. Ale jak możemy się dowiedzieć, monitor CTF pozwala na dwukierunkową komunikację między procesami a monitorem oraz między wszelkimi zarejestrowanymi w monitorze oknami. A więc CTFMON nie tylko umie informować okna o zaawansowanych metodach wprowadzania, ale także przesyłać komunikaty między oknami. Ta koncepcja spłaszcza model uprawnień: dozwolona komunikacja w ramach CTF odbywa się między oknami o dowolnych uprawnieniach, jeżeli tylko są podpięte do jednej sesji użytkownika. A więc jeżeli na pulpicie użytkownika znajduje się okno należące do administratora, użytkownik może posłać mu rozkaz w ramach mechanizmu CTF. Ale co takiego strasznego może zostać przesłane w ramach narzędzia służącego do obsługi układów klawiatury? No cóż...
Przede wszystkim, monitor CTF rejestruje nowe okna za pomocą struktury zawierającej identyfikatory procesu, wątku i wskaźnik na okno (HWND, typ void* HANDLE). Zakłada jednak, że okna poprawnie informują o swoim pochodzeniu i nie próbują zarejestrować swojej sesji, podając się za kogoś innego. Co gorsza, można rejestrować własne monitory CTF, bo przecież czemu nie. Wreszcie, zawartością komunikatu przesyłanego w ramach CTF może być cały obiekt COM, co oznacza bardzo dużą dowolność w formułowaniu treści.
Dalszym krokiem było badanie, co potrafią obiekty COM obsługiwane przez CTF. Za pomocą obiektu ITfInputProcessorProfileMgr możemy komunikować się w ramach COM z usługami tekstowymi. Aplikacje robią to zazwyczaj w tle, za naszymi plecami, ale Ormandy napisał narzędzie, które pozwala złożyć taki obiekt samodzielnie. Za jego pomocą próbował następnie wywołać wszystkie dostępne (eksponowane przez API) funkcje CTF. Udało mu się odnaleźć własność potencjalnie pozwalającą na wykonanie kodu w ramach komunikatu CTF.
Eskalacja uprawnień
W skrócie oznacza to, że w ramach usług tekstowych i przesyłania komunikatu do innego okna, możliwe jest wysłanie takiego obiektu, który wykona kod w ramach innego procesu, bo CTF kazał mu się tak zachować. Ogranicza nas lista klientów zgłoszonych do CTF, czyli sesja, a nie użytkownik. Jeżeli mamy np. okno Wiersza Polecenia "Uruchomione jako Administrator", inne, nieuprzywilejowane okno może kazać mu wykonać kod w ramach mechanizmu CTF. To poważne naruszenie zabezpieczeń, ale czy zawsze w ramach sesji użytkownika znajdują się okna i programy, które pracują z wyższymi uprawnieniami?
Tak. Są przynajmniej dwa okna-programy, które rejestrują się do lokalnej sesji CTF, ale pracują z uprawnieniami użytkownika ZARZĄDZANIE NT\SYSTEM. Są to LogonUI.exe oraz consent.exe. Co to takiego? Otóż... ekran blokady oraz okienko zgody Kontroli Konta Użytkownika. Konsekwencją tego faktu jest możliwość eskalacji uprawnień jeżeli użytkownik zablokuje ekran. Ewentualnie, można bezczelnie poprosić o uprawnienia, których użytkownik odmówi, ale ponieważ okienko consent.exe zostało wyświetlone, prawa użytkownika system udało się już nabyć.
Zresztą nie trzeba nawet bawić się w podnoszenie uprawnień. Już samo to, że cudze okna mogą wpisywać tekst i kombinacje klawiszy innym oknom oraz np. podsłuchiwać wpisywane hasła jest wystarczającym problemem i poważnym uchybieniem w mechanizmie zabezpieczeń. Podniesienie uprawnień do poziomu SYSTEM to wisienka na tym torcie, a natura ataku każe zakładać, że podobnych podatności jest znacznie, znacznie więcej. I czają się w Windows niezauważone od dwudziestu lat.
Odpowiedź z Redmond
W niniejszej aferze interesujące są jeszcze dwie inne kwestie. Pierwszą z nich jest reakcja Microsoftu na zgłoszenie (naturalnie miało ono miejsce już kilka miesięcy temu). Odpowiedź była przekładana wielokrotnie, aż do dotarcia do deadline'u, po którym luka miała zostać opublikowana niezależnie od obecności łatki. Microsoft poinformował o wprowadzeniu weryfikacji rejestrowania do modułu CTF (nie można będzie kłamać z identyfikatorem okna i procesu). Jeżeli chodzi o naruszenie pamięci, problem jest niemożliwy do rozwiązania w Windows 7 bez złamania zgodności, więc łatka nie powstanie. W systemie Windows 10 możliwe jest po prostu wyłączenie całego podatnego mechanizmu i Microsoft dostarczy odpowiednie ograniczenia.
Microsoft CTF Exploitation Demo (Windows 10 x64 1903)
Nie zaoferowano jednak rozwiązania dla podatności pozwalającej ukraść hasło z okienka UAC. Prace nad rozwiązaniem trwają, dobrym obejściem problemu jest stosowanie menedżerów haseł i biometrycznego oraz wieloskładnikowego uwierzytelniania. Załatanie części odkrytych słabości zostało dostarczone w sierpniowych aktualizacjach, opisanych w biuletynie CVE-2019-1162 o kompletnie postrzelonej nazwie "Windows ALPC Elevation of Privilege Vulnerability". Warto też dodać, że sierpniowe aktualizacje łatają też 92 inne dziury w zabezpieczeniach produktów Microsoftu.
Na koniec cennym jest zwrócić uwagę, jak Tavis Ormandy dokonał swoich odkryć. Poświęcił on bardzo dużo czasu na coś, co jest rzekomo udokumentowane i sprawdzone. Szukał odpowiedzi na pytania, które teoretycznie istniały już od dawna. Włożono zatem absurdalnie dużo wysiłku w coś, co mogło się okazać marginalnie istotne lub wręcz być ślepą uliczką. Dlatego też artykuł na temat słabości CTF zaczyna się cytatem, brzmiącym w tłumaczeniu: [quote]“Hakowanie jest nierzadko po prostu poświęceniem na coś znacznie większej ilości czasu, niż ktokolwiek by się spodziewał”[/quote]. To bardzo dobre podsumowanie badań bezpieczeństwa i badań w ogóle. Często nie trzeba być geniuszem lub kimś nieziemsko wykształconym (choć Ormandy jest niewątpliwym zawodowcem!). Należy po prostu wykazać się pracowitością oraz konsekwencją i nie zwracać uwagi na, tak częste przecież, hasła "po co dalej tyle nad tym siedzisz!?".