cyberbezpieczeństwo i programowanie

CompTIA Security+: Privilege escalation

C

Artykuł jest częścią serii opracowań zagadnień obowiązujących na egzaminie CompTIA Security+ i stanowi wprowadzenie do ataków polegających na eskalacji uprawnień.

Artykuł jest również dostępny w wersji PDF. Jeśli nie chcesz przegapić kolejnych materiałów, to zachęcam do zapisania się na mój newsletter:

Na czym polega eskalacja uprawnień?

Większość systemów komputerowych jest zaprojektowana w taki sposób, żeby mogły być obsługiwane przez wielu użytkowników jednocześnie. Nie jest dobrym pomysłem, żeby każdy użytkownik miał nieograniczony dostęp do systemu i jego wszystkich zasobów, dlatego wprowadzono system przywilejów i uprawnień, które są przypisywane do kont określonych użytkowników. Krótko mówiąc, niektóre konta (np. administracyjne) mają znacznie większe możliwości ingerencji w system niż pozostałe.

W przypadku standardowych kont użytkowników, o tym samym poziomie uprawnień, nie ma możliwości (a przynajmniej nie powinno być) uzyskania dostępu do zasobów innych użytkowników i każde konto powinno mieć swoje wyizolowane środowisko. Wyjątkiem są oczywiście konta administracyjne, które mogą mieć dostęp do zasobów wszystkich użytkowników. Świętym Graalem cyberwłamywaczy jest uzyskanie dostępu do konta administratora systemu (root w systemach uniksowych), które posiada nieograniczoną władzę nad tym systemem.

Eskalacja uprawnień (ang. privilege escalation) polega na wykorzystaniu podatności (ang. vulnerability), błędu lub niepoprawnej konfiguracji w systemie bądź aplikacji, żeby uzyskać szersze (niż normalnie przysługują) uprawnienia/przywileje (ang. permissions/privileges) do chronionych zasobów. Innymi słowy, eskalacja uprawnień następuje w chwili, gdy atakujący ma dostęp do standardowego konta użytkownika o ograniczonych uprawnieniach systemowych, ale jest w stanie uzyskać nieautoryzowany dostęp do konta administracyjnego (vertical privilege escalation) bądź innego użytkownika na tym samym poziomie (horizontal privilege escalation).

W niektórych materiałach można spotkać się z tym, że przejęcie konta administratora bądź innego użytkownika za sprawą złamania hasła lub kradzieży danych uwierzytelniających, również nazywane jest eskalacją uprawnień. Miejmy jednak na uwadze, że w kontekście egzaminu takie działania mają swoją osobną klasyfikację.

Vertical

Vertical privilege escalation to w dosłownym tłumaczeniu wertykalna/pionowa eskalacja uprawnień. Jest to nic innego jak uzyskanie większych/szerszych uprawnień niż są przewidziane dla określonego użytkownika lub aplikacji.

Dobrze obrazują to następujące sytuacje:

  • Konto standardowego użytkownika jest w stanie wykonywać operacje administracyjne, takie jak: tworzenie oraz usuwanie tabel w bazie danych; instalacja/deinstalacja oprogramowania w systemie operacyjnym (to uprawnienie może być wykorzystanie do instalacji złośliwego oprogramowania); zarządzanie kontami użytkowników w systemie itd.
  • Użytkownik, który mógł do tej pory jedynie odczytywać zawartość określonych plików, ma teraz możliwość edytowania oraz usuwania tych plików.
  • Neo, który od pewnego momentu był w stanie zatrzymywać pędzące kule – uprawnienie administracyjne nieprzewidziane przez twórców systemu Matrix, nawet dla kont o podwyższonym poziomie uprawnień (Agentów) ;).
Fragment filmu The Matrix (1999).

Zastanówmy się teraz, w jakich okolicznościach może dojść do omawianej eskalacji uprawnień. Systemy operacyjne często pozwalają na uruchamianie usług bądź aplikacji w kontekście użytkownika/konta, który ma szerszy zakres uprawnień niż standardowe konta. Dzięki temu zwykli użytkownicy, nie posiadający bezpośredniego dostępu do określonych zasobów systemowych, są w stanie wykonywać aktywności wymagające tychże zasobów (oczywiście w sposób kontrolowany). Pamiętajmy też, że zarówno systemy uniksowe (sudo), jak i Windows (runas) pozwalają na uruchomienie aplikacji w kontekście innego użytkownika generalnie (niekoniecznie z wyższym poziomem uprawnień).

W systemie Windows możemy spotkać się z usługami (ang. Windows service), które działają w kontekście specjalnego konta LocalSystem , posiadającego niemalże nieograniczony dostęp do lokalnych zasobów systemowych. Kiedy uruchomimy sobie menadżera usług Windows (services.msc), ujrzymy listę przeróżnych usług działających w naszym systemie. Jeśli w kolumnie Logowanie jako (ang. Log On As) znajduje się wpis System lokalny (ang. Local System), to znaczy, że dana usługa działa w kontekście specjalnego użytkownika systemowego.

Przykładem może być Usługa Windows Defender (ang. Windows Defender Service), czyli wbudowane w system oprogramowanie typu anti-malware. Tego typu aplikacja siłą rzeczy wymaga dostępu do zasobów chronionych przed zwykłymi użytkownikami. Jednakże dzięki temu, że działa w specjalnym kontekście systemowym, każdy użytkownik może sobie w dowolnej chwili uruchomić skanowanie systemu i usunąć wykryty malware.

W systemie Linux (i ogólnie w systemach uniksowych) istnieje podobny mechanizm. Pliki oznaczone flagą setuid są uruchamiane z prawami właściciela pliku, a te z ustawionym bitem setgid z prawami właściciela grupy. Jest to niezbędne do wykonywania zadań wymagających większych uprawnień niż te, które posiadają standardowi użytkownicy (np. zmiana hasła użytkownika wymaga modyfikacji chronionych plików systemowych). Jeśli nie miałeś(-aś) wcześniej do czynienia z uniksowym zarządzaniem uprawnień, to zachęcam do zapoznania się z krótkim wprowadzeniem: Jak nadawać uprawnienia do plików w Linuksie?

Jak już zapewne się domyślasz, aplikacje i usługi przedstawione powyżej są doskonałym wektorem ataku, jeśli celem jest uzyskanie pełnej kontroli nad systemem lub znaczne podniesienie poziomu uprawnień. Teoretycznie działanie aplikacji/usług jest ściśle kontrolowane, ale wystarczy, że jedna z nich ma poważną lukę bezpieczeństwa, która pozwala na wstrzyknięcie złośliwego kodu do jej pamięci. Może to być możliwe np. za sprawą ataku przepełnienia bufora (ang. buffer overflow), do którego jeszcze wrócimy. W takim przypadku aplikacja/usługa wykona czynność zleconą przez atakującego (np. dodanie siebie do grupy administratorów) z wyższymi uprawnieniami, których ten w domyśle nie posiada!

W ramach ciekawostki, warto wspomnieć, że rooting/jailbreaking urządzeń mobilnych (i nie tylko) można zaliczyć do ataków typu privilege escalation. W końcu jest to nic innego jak uzyskanie pełnych uprawnień administratora na urządzeniu :). To samo tyczy się konsol do gier i różnych metod obejścia zabezpieczeń DRM (Digital Rights Management).

Na koniec przykładowe pytanie z książki CompTIA Security+ Practice Tests:

During a penetration test, Cameron gains physicall access to a Windows system and uses a system repair disk to copy cmd.exe to the %systemroot%\system32 directory while renaming it sethc.exe. When the system boots, he is able to log in as an unprivileged user, hit the Shift key five times, and open a command prompt with system-level access using sticky keys. What type of attack has he conducted?

A. A Trojan attack.
[X] B. A privilege escalation attack.
C. A denial-of-service attack.
D. A swapfile attack.

Horizontal

Horizontal privilege escalation (horyzontalna eskalacja uprawnień) to uzyskanie nieautoryzowanego dostępu do zasobów innego użytkownika o identycznym poziomie uprawnień. Mówiąc krótko, eskalacja horyzontalna następuje wtedy gdy standardowy użytkownik systemu może wykonywać operacje, które powinny być dostępne jedynie dla innego standardowego użytkownika. Na przykład, mając dostęp jedynie do swojego profilu Facebook, atakujący miałby możliwość zmiany ustawień profilowych zupełnie innego konta.

Należy pamiętać, że jest to ograniczona forma eskalacji, ponieważ nie wiąże się z rozszerzeniem uprawnień, w przeciwieństwie do wcześniej omówionego ataku vertical privilege escalation. Atakujący nie uzyskuje większych przywilejów niż sam posiada, a jedynie może wykonywać operacje w kontekście innego użytkownika (w sposób nieautoryzowany).

Przykłady ataków na aplikacje webowe

Oprócz systemów operacyjnych, które mogą okazać się podatne na tego typu atak, doskonałym przykładem są aplikacje webowe. Zanim jednak przejdziemy do sedna, zapoznajmy się z kontekstem.

Protokół HTTP(S) jest bezstanowy (ang. stateless), a to znaczy, że każde żądanie (ang. request) HTTP(S), wysyłane każdorazowo kiedy np. klikniesz link w aplikacji czy też podasz swoje dane uwierzytelniające, jest niezależne i teoretycznie nie ma żadnego powiązania z pozostałymi żądaniami. Zauważ jednak, że kiedy korzystasz z jakiejkolwiek aplikacji webowej, w której posiadasz konto użytkownika, nie musisz co chwilę podawać swoich danych uwierzytelniających, nawet jeśli żądanie wymaga potwierdzenia, że na pewno przyszło od Ciebie (np. zmiana danych personalnych po zalogowaniu).

Aby pamiętać działanie użytkownika na stronie, wykorzystuje się mechanizm sesji. Jest to obiekt (w tym przypadku zbiór danych) tworzony dla każdego użytkownika osobno i trzymany gdzieś na serwerze (np. w bazie danych). Zawiera informacje o użytkowniku, który aktualnie korzysta z aplikacji: od prostych ustawień preferencji, po informację o tym czy dany użytkownik jest aktualnie zalogowany (tutaj należy zaznaczyć, że nie zawsze informacje o uwierzytelnieniu użytkownika są przechowywane w sesji, ale ciągle jest to dosyć popularne podejście, więc na nim się skupimy).

Każda sesja ma swój unikatowy, generowany losowo identyfikator (session ID) i jest przypisana do pojedynczego użytkownika. Ten identyfikator jest generowany w momencie rozpoczęcia nowej sesji użytkownika i trafia do klienta, gdzie jest zapisywany w ciasteczku (ang. cookie), czyli prostym pliku tekstowym używanym przez przeglądarkę.

Wartości zapisane w ciasteczkach są później przesyłane do serwera w kolejnych żądaniach HTTP(S) (nagłówek Cookie), więc serwer po ich otrzymaniu, jest w stanie skojarzyć przesłany identyfikator sesji z wartością zapisaną u siebie. Jeżeli jest dopasowanie, to znaczy, że dany użytkownik korzysta właśnie z aplikacji i został już uwierzytelniony wcześniej (jeśli oczywiście informacja o zalogowaniu została zapisana w obiekcie sesji).

Czy dostrzegasz już potencjalne zagrożenie? Wyobraź sobie, że ktoś wykradnie ciasteczko z zapisanym identyfikatorem sesji, czy to poprzez fizyczny dostęp do przeglądarki ofiary, czy też za sprawą ataku XSS (wstrzyknięcie złośliwego skryptu w kod strony internetowej). Jeśli prawowity użytkownik nie zakończył sesji i się nie wylogował, to atakujący może wysłać dowolne żądanie HTTP(S) dołączając przechwycony ID sesji. Serwer stwierdziłby, że otrzymał żądanie od zalogowanego użytkownika i bez wahania je wykonał (zakładając, że po stronie serwera nie ma dodatkowej weryfikacji).

Ważna jest również losowość i nieprzewidywalność identyfikatora sesji generowanego przez serwer. Jeśli ten będzie łatwy do odgadnięcia, a do tego serwer nie będzie posiadał dodatkowych mechanizmów zabezpieczających, to atakujący nie będzie musiał się trudzić z przejmowaniem ciasteczek – po prostu sobie wygeneruje pasujący identyfikator.

Innym ciekawym atakiem jest CSRF (Cross Site Request Forgery), który również pozwala na wykonanie niepożądanej akcji w imieniu zalogowanego użytkownika.
W tym przypadku jednak zamiast przechwytywać lub zgadywać session ID, atakujący podstępem wysyła ofierze spreparowany link, który ma wywołać jakąś niechcianą akcję na określonej stronie internetowej. Jeśli użytkownik jest aktualnie zalogowany na tej stronie (w jego przeglądarce są zapisane ciasteczka świadczące o tym, że został już uwierzytelniony) i kliknie w ten link, to przeglądarka automatycznie dołączy ciasteczka do spreparowanego żądania, a serwer je wykona.

Popularnym remedium na tego typu ataki jest tzw. anti-CSRF-token, czyli specjalny, losowy ciąg znaków, który musi być dołączony do określonych żądań HTTP(S). Jeśli brakuje takiego tokena lub jest nieprawidłowy, żądanie zostanie odrzucone, nawet jeśli użytkownik jest zalogowany.

Powyższe ataki omawiamy w kontekście horyzontalnej eskalacji uprawnień, ale miejmy na uwadze, że mogą dotyczyć również kont administracyjnych. Przedstawione rozważania są w pewnym stopniu uproszczone, ponieważ istnieje szereg dodatkowych zabezpieczeń, które mogą przeciwdziałać takim procederom, ale sądzę, że dobrze obrazują ogólną ideę.

Obrona

Podatności umożliwiające eskalację uprawnień są uważane za krytyczne i istotne jest, żeby jak najszybciej je załatać. Dodatkowym zabezpieczeniem może być dzisiejsze oprogramowanie antywirusowe (i ogólnie anti-malware), które często jest w stanie wykryć złośliwe oprogramowanie wykorzystujące znane luki do eskalacji uprawnień. Pamiętajmy jednak, że nadal podstawową linią obrony są regularne aktualizacje systemu oraz oprogramowania.

Przyjrzyjmy się innym technikom i działaniom, które potrafią skutecznie udaremnić ataki prowadzące do eskalacji uprawnień lub przynajmniej znacząco ograniczyć ich skutki:

  • Sumienne przestrzeganie zasady least privilege (możliwie najmniejsze uprawnienia), zarówno w stosunku do użytkowników, jak i aplikacji działających w systemie. Innymi słowy, użytkownicy/aplikacje powinny mieć tylko takie uprawnienia jakich potrzebują i nic ponadto. Dzięki temu, nawet jeśli atakującemu uda się wykonać złośliwe działanie w kontekście innego konta, może się okazać, że ograniczone przywileje tego konta nie pozwalają na wyrządzenie większych szkód.
  • Błędy oprogramowania umożliwiające eskalację uprawnień, bardzo często są wynikiem niedopatrzenia programistów. Wytwarzanie nowoczesnego oprogramowania jest procesem złożonym, ale przestrzeganie dobrych praktyk pozwala w większości przypadków uchronić końcowy produkt przed poważnymi błędami bezpieczeństwa. Dlatego zaleca się korzystanie z odpowiednich narzędzi, które są w stanie wykryć potencjalne zagrożenia już na etapie pisania kodu. Mowa tutaj o nowoczesnych kompilatorach oraz o narzędziach do statycznej analizy kodu, takich jak Snyk czy SonarQube.
  • Dobrą praktyką jest również wymaganie, żeby kod aplikacji działający w trybie jądra (czyli bardziej uprzywilejowany – kilka słów więcej o trybie jądra można znaleźć w sekcji o rootkitach) był podpisany cyfrowo. Dzięki temu, nawet jeśli ktoś wstrzyknie do aplikacji swój złośliwy kod, system go nie wykona z powodu braku weryfikacji.
  • Mechanizmy chroniące przed wstrzykiwaniem złośliwego kodu do obszaru pamięci, wykorzystywanego przez podatną aplikację. Trochę więcej na ten temat powiemy sobie przy okazji dokładniejszego omówienia ataków typu buffer overflow, a na razie wspomnijmy 2 popularne rozwiązania, do których jeszcze wrócimy:
    • DEP (Data Execution Prevention) – uniemożliwia wykonanie kodu znajdującego się w segmencie danych (data segment) obszaru pamięci określonego programu.
    • ASLR (Address Space Layout Randomization) – losowe rozmieszczenie danych w pamięci uruchomionej aplikacji.

Materiały źródłowe

O autorze

Łukasz Mieczkowski

Programista, który zainteresował się cyberbezpieczeństwem.

Dodaj komentarz

cyberbezpieczeństwo i programowanie

Łukasz Mieczkowski

Programista, który zainteresował się cyberbezpieczeństwem.

Kontakt

Zapraszam do kontaktu za pośrednictwem mediów społecznościowych.