Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Adminie… Czy znamy Twoje grzechy? ;-) Sprawdź!
Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Adminie… Czy znamy Twoje grzechy? ;-) Sprawdź!
Usługi systemowe Windows (Windows services) to szczególne procesy działające w systemie, zarządzane przez specjalny proces o nazwie Service Control Manager (SCM). Komunikacja z nimi odbywa przez dedykowane API (Services API), które z założenia umożliwia zdalny dostęp do usług (innymi słowy, można zarządzać usługami działającymi na innym serwerze).
W przeciwieństwie do zwykłych aplikacji, uruchamianych przez użytkownika i działających tylko wtedy, gdy użytkownik jest zalogowany, usługi Windows mogą uruchamiać się bez interwencji użytkownika i działać w tle, również po jego wylogowaniu.
Ze względu na swoje właściwości, Windows services mogą być wykorzystane do umieszczenia backdoora w systemie:
Ataki na usługi systemowe raczej nie służą do eskalacji uprawnień, ponieważ aby nimi zarządzać na dzień dobry potrzebne są odpowiednie uprawnienia administracyjne. Chyba, że ze względu na błędną konfigurację dostępu do plików uda nam się podmienić plik wykonywalny usługi, która działa z wyższymi uprawnieniami niż złośliwy użytkownik.
Jest to specjalny proces (%SystemRoot%\System32\services.exe) uruchamiany automatycznie na wczesnym etapie startu systemu operacyjnego. Jego zadaniem jest zarządzanie (m.in. uruchamianie i zatrzymywanie) usługami systemowymi Windows oraz komunikacja z tymi usługami.
Jeśli chcemy wysłać jakiś komunikat do wybranej usługi, odbywa się to za pośrednictwem SCM, dlatego każda usługa powinna zawierać kod odpowiedzialny za obsługę przychodzących komunikatów. Do wysyłania komunikatów (kodów kontrolnych) używana jest funkcja ControlService i jak wynika z jej dokumentacji, pierwsze 127 wartości (wliczając w to kody takie jak SERVICE_CONTROL_PAUSE czy SERVICE_CONTROL_STOP) jest zarezerwowanych przez system Windows. Pozostałe wartości (128 – 255) mogą zostać wykorzystane w dowolny sposób przez programistów.
Lista zainstalowanych usług, zarządzanych przez SCM, znajduje się w specjalnej bazie danych przechowywanej w rejestrze systemowym: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Podczas startu systemu, menadżer uruchamia procesy potomne zgodnie z regułami zapisanymi w tej bazie (przechowywanych w kluczach rejestru). Zawiera ona m.in. informacje o tym jak dana usługa ma zostać uruchomiona (automatycznie; ręcznie; z opóźnionym startem etc.).
Warto również wspomnieć o tym, że wspomniana wcześniej baza danych zawiera nie tylko listę usług, ale też sterowników (drivers). Rozróżnia się je po wartości Type.
Aby mieć wgląd do podstawowej konfiguracji nie musimy zaglądać do rejestru, bo możemy skorzystać z wbudowanego w system narzędzia GUI services.msc. Za jego pomocą możemy też łatwo dostrzec zależności między usługami, czyli które są potrzebne do działania tej konkretnej oraz które jej potrzebują. Można to zbadać za pomocą wspomnianego narzędzia po wejściu we właściwości wybranej usługi, w zakładce Dependencies.
W kontekście systemu Windows, sesje (sessions) stanowią kontener na procesy danego użytkownika. Innymi słowy, każdy użytkownik, który loguje się do systemu otrzymuje osobną sesję, zaczynając od numeru 1 (pierwszy użytkownik – sesja 1; drugi użytkownik – sesja 2 itd.). Istnieje jeszcze specjalna sesja 0 (session 0), która jest tworzona zawsze podczas startu systemu i to w jej kontekście uruchamiane są wszystkie usługi systemowe Windows.
W dawnych czasach Windows XP i Windows Server 2003, możliwe było uruchomienie standardowych aplikacji użytkownika w ramach sesji 0, co stanowiło potencjalne zagrożenie bezpieczeństwa ze względu na możliwy dostęp do procesów systemowych oraz innych chronionych zasobów. Aby uniknąć ryzyka, zaczynając od wersji Windows Vista oraz Windows Server 2008, Microsoft odizolował sesję 0 od interaktywnych aplikacji. Oznacza to, że w sesji 0 mogą pracować jedynie usługi oraz procesy systemowe nie wymagające interakcji z użytkownikiem (ze względu na brak wsparcia dla UI).
Żeby zapewnić wsteczną kompatybilność po tej zmianie, przez jakiś czas w systemie Windows był obecny proces Interactive Services Detection (UI0Detect.exe) działający w tle, który miał za zadanie wykrywać w sesji 0 usługi wymagające interakcji z użytkownikiem. Jeśli takową znalazł to uruchamiał dla niej bardzo proste GUI w kontekście sesji 0. W najnowszych wersjach systemu Windows już nie ma tego procesu, ponieważ generalnie usługi nie powinny używać GUI do komunikacji.
Więcej na temat sesji 0 można znaleźć w następujących materiałach:
Procesy chronione (ang. protected processes) to koncept specjalnych usług wprowadzony od wersji Windows 8.1. Jego założeniem jest szczególna ochrona krytycznych usług systemowych, których zadaniem jest wykrywanie złośliwego oprogramowania (anti-malware services). Celem tej ochrony jest upewnienie się, że tylko zaufany kod może być załadowany i wykonany w ramach chronionej usługi.
Cechą charakterystyczną procesów chronionych jest fakt, że nie mogą być one kontrolowane przez inne procesy niechronione, nawet te z uprawnieniami administratora! Innymi słowy, nawet administrator teoretycznie nie jest w stanie zabić takiego procesu – może go co najwyżej zawiesić (ang. suspend).
Taki proces wydaje się idealnym miejscem do ukrycia backdoora, ale w praktyce jest to raczej niewykonalne, ponieważ aby uruchomić usługę w trybie chronionym, jej kod musi być podpisany specjalnym certyfikatem. Na szczęście zdobycie takiego certyfikatu przez atakującego jest niemalże niemożliwe.
Więcej informacji na temat procesów chronionych można znaleźć w dokumentacji: Protecting anti-malware services.
Zestaw uprawnień do usług systemowych może różnić się w zależności od typu użytkownika (np. inne będzie miał administrator, a inne zwykły zalogowany użytkownik). Można je zmodyfikować na kilka sposobów. Jednym z nich jest modyfikacja uprawnień bezpośrednio za pomocą API (np. z użyciem narzędzia sc.exe, o którym powiemy sobie za chwilę) oraz specjalnego języka SDDL (Security Descriptor Definition Language).
Jeśli język SSDL jest dla kogoś zbyt enigmatyczny, to może posłużyć się narzędziem GUI o nazwie Process Explorer. Jest to rozbudowana przeglądarka procesów działających w systemie Windows. Aby dostać się do okienka z rzeczywistymi uprawnieniami, należy znaleźć interesującą nas usługę i z menu kontekstowego (prawy przycisk myszy) wybrać następujące opcje: Properties -> Services -> Permissions -> Advanced -> Edit -> Show advanced. Uprawnienia mogą również zostać ustawione z poziomu kontrolera domeny Group Policy Management (gpmc.msc), ale tylko w systemach Windows Server.
Przy definiowaniu uprawnień należy pamiętać, że dobrą praktyką jest przypisywanie użytkowników do grupy, a następnie nadanie odpowiednich uprawnień tej grupie. Dużo łatwiej zarządza się uprawnieniami poszczególnych grup niż pojedynczych użytkowników. Dodatkowo, należy zwrócić szczególną uwagę na te 3 uprawnienia:
Warto raz na jakiś czas przeprowadzić audyt uprawnień usług systemowych i żeby nie robić tego ręcznie, można wykorzystać skrypty PowerShell napisane i udostępniony przez Grzegorza Tworka (autora szkolenia):
Jeśli zdejmiemy uprawnienie do odpytywania stanu usługi (Query Status) wybranej grupie użytkowników, to dla nich dana usługa nie pojawi się na liście ani nie zostanie zwrócona przez narzędzie sc.exe, pomimo tego, że usługa jest zapisana w bazie, a jej proces ciągle działa w tle. Warto o tym pamiętać, ponieważ ten zabieg może posłużyć do ukrycia czegoś niechcianego w naszym systemie.
Jak zostało już wspomniane wcześniej, do zarządzania usługami systemowymi służy Services API, czyli generalnie zestaw dedykowanych funkcji Win32 API, które odpowiadają za komunikację z SCM. Ich użycie może być skomplikowane, ale na szczęście w systemie Windows jest natywnie dostępny wrapper w postaci narzędzia CLI o nazwie sc.exe. Jeśli interesuje nas w jaki sposób poszczególne komendy sc.exe są mapowane na funkcje API, możemy zapoznać się z tym artykułem: SC and its quirky cmd line args.
W przypadku użycia PowerShella pamiętajmy o dodaniu rozszerzenia, ponieważ w PS polecenie sc jest aliasem do Set-Content. Poniżej znajduje się lista wybranych poleceń:
Jeśli interesuje nas napisanie i zainstalowanie własnej niskopoziomowej usługi, możemy skorzystać z kodu i instrukcji przygotowanych przez Grzegorza: NoRebotSvc.
Pamiętajmy, że Services API umożliwia również zdalną komunikację. Jeśli chcielibyśmy porozmawiać z SCM znajdującym się na zdalnym serwerze, możemy to zrobić również za pomocą wspomnianego narzędzia: sc.exe <SERVER> [COMMAND] [SERVICE_NAME]. Jeśli chcielibyśmy jednak zablokować możliwość zdalnego zarządzania usługami, możemy to zrobić poprzez dodanie odpowiedniego wpisu w rejestrze systemu: DisableRemoteScmEndpoints.
Wyzwalacze (triggers) mogą być ciekawą metodą obejścia braku uprawnień do uruchomienia danej usługi (poprzez standardowe polecenie start). Jeśli użytkownik jest w stanie podejrzeć triggery dla danej usługi, może wykorzystać jeden z nich do jej uruchomienia. Przykładem predefiniowanego zdarzenia wyzwalającego (ang. predefined trigger event) może być zmiana dostępności na wybranym porcie sieciowym firewalla.
Usługi mogą również nasłuchiwać zdarzeń ETW (Event Tracing for Windows). W dużym skrócie: ETW jest systemowym mechanizmem logowania zdarzeń, które mogą później służyć w celach diagnostycznych. Częścią tego mechanizmu są aplikacje typu Providers, które generują te zdarzenia. Jeśli usługa jest zapisana jako konsument (Consumer) zdarzeń emitowanych przez wybranego providera, to zareaguje w określony sposób kiedy te zdarzenia rzeczywiście wystąpią.
Dobrym przykładem jest usługa Windows Error Reporting Service (wersvc). Możemy sprawdzić na jakie triggery reaguje:
sc.exe qtriggerinfo wersvc
W odpowiedzi otrzymujemy informację:
| SERVICE_NAME: wersvc START SERVICE CUSTOM : e46eead8-0c54-4489-9898-8fa79d059e0e [ETW PROVIDER UUID] |
Wiemy już, że usługa może zostać uruchomiona jeśli provider o tym konkretnym identyfikatorze GUID (e46eead8-0c54-4489-9898-8fa79d059e0e) wyemituje zdarzenie. Za pomocą polecenia (w PS): logman.exe query providers | select-string ‘e46eead8-0c54-4489-9898-8fa79d059e0e’, dowiadujemy się, że tym konkretnym providerem jest Microsoft-Windows-Feedback-Service-TriggerProvider. Aby wygenerować odpowiednie zdarzenie, możemy posłużyć się tym kodem: StartByEtw.c.
Innym ciekawym mechanizmem (choć mało praktycznym), który może zostać wykorzystany do wybudzenia usługi jest WNF (Windows Notification Facility). Jest to mało znany, bo praktycznie nieudokumentowany, komponent systemu odpowiedzialny za propagację powiadomień w tymże systemie. Okazuje się, że usługa wersvc również jest w stanie odpowiedzieć na odpowiedni komunikat WNF, co można sprawdzić za pomocą tej małej aplikacji: StartByWNF.c. Cała sztuczka polega na zidentyfikowaniu i wysłaniu odpowiedniego komunikatu, ponieważ na inne usługa nie zareaguje. Jest to trudne zadanie, bo brak dokumentacji wymusza zastosowanie inżynierii wstecznej (ang. reverse engineering) do zidentyfikowania adekwatnego komunikatu.
Przy okazji omawiania SCM zostało wspomniane, że pełnoprawna usługa musi zawierać fragment kodu odpowiadający za prawidłową komunikację z menadżerem i obsługę komunikatów. Żeby ograniczyć konieczność pisania powtarzającego się kodu oraz ze względów wydajnościowych, Microsoft wprowadził boilerplate w postaci procesu svchost.exe będącego tzw. hostem usługi. Idea polega na tym, że szkielet usługi systemowej znajduje się w tym procesie, a kod wykonujący konkretne zadanie jest ładowany do jego pamięci w postaci biblioteki DLL.
Podstawowym założeniem takiego podejścia było zmniejszenie zużycia zasobów systemowych, ponieważ pojedynczy proces svchost.exe mógł być hostem dla więcej niż jednej usługi (pamiętajmy, że ten mechanizm został wdrożony jeszcze w czasach Windows 2000). Co prawda zyskaliśmy na wydajności, ale równocześnie straciliśmy tak ważną pod względem bezpieczeństwa separację. W związku z tym, kiedy dostępna moc obliczeniowa komputerów zaczęła szybko rosnąć, mogliśmy sobie pozwolić na uruchomienie osobnego procesu svchost.exe dla każdej z usług, odzyskując w ten sposób pożądaną separację. Oczywiście dalej możliwe jest współdzielenie procesu hosta, np. kiedy w systemie zaczyna brakować pamięci RAM.
Proces uruchamiania usługi svchost.exe jest stosunkowo złożony i wygląda następująco:
Usługi svchost.exe są o tyle ciekawe, że mogą stanowić dobre miejsce do ukrycia jakichś niestandardowych aktywności. Na pierwszy rzut oka, w systemowym menadżerze zadań, widnieje tylko proces o nazwie svchost.exe, który raczej nie wzbudza podejrzeń. Dopiero kiedy przyjrzymy się jakie biblioteki zostały załadowane do procesu (np. używając wspomnianego wcześniej narzędzia ProcessExplorer), możemy znaleźć coś co ewentualnie przykuje naszą uwagę.
Warto wiedzieć, że z procesu hosta usług korzystają głównie usługi ściśle związane z systemem Windows (nawet rozwiązania MS, które nie są integralną częścią systemu, używają przeważnie swoich dedykowanych procesów). Dodatkowo, załadowane biblioteki DLL są też przeważnie podpisane przez Microsoft. Oznacza to, że jeśli namierzymy usługę svchost.exe, która nie jest usługą stricte systemową bądź załadowany plik DLL nie jest podpisany przez MS, powinno to wzbudzić nasze podejrzenia.
Autor szkolenia (Grzegorz Tworek) jak zwykle stanął na wysokości zadania i udostępnił skrypt PS, który wyświetla listę bibliotek DLL załadowanych przez usługi svchost.exe i wyróżnia te, które nie zostały podpisane: Get-ServiceDlls.ps1.
Przykład kodu biblioteki DLL, którą można załadować do procesu svchost.exe, znajdziemy tutaj: sekurak/svc.c. Jej zadanie to okresowe odczytywanie i wykonywanie poleceń z pliku znajdującego się w określonej ścieżce (w tym konkretnym przypadku: c:\malware\malware.txt). Dodatkowo, usługa wypisuje komunikaty, które mogą być odczytane za pomocą narzędzia DebugView.
Proces instalacji tej usługi przebiega następująco (kiedy kod został już skompilowany do postaci biblioteki DLL):
Kiedy usługa już działa, możemy dodać do wspomnianego wcześniej pliku tekstowego polecenie, które np. stworzy nam nowego użytkownika w systemie:
net user [USER] /add [PASSWORD]
Dodatkowe materiały:
Skoro wiemy już jak działają usługi systemowe Windows oraz jak mogą zostać wykorzystane do ukrycia złośliwej działalności w systemie, przyjrzyjmy się podstawowym elementom, na które należy zwrócić uwagę jeśli jesteśmy administratorami:
Więcej na temat obrony można znaleźć w artykule Usługi systemowe Windows w kontekście cyberincydentu.
~Łukasz Mieczkowski
Szkolenie jest w modelu “płać ile chcesz”. Oznacza to, że możesz zapisać się zupełnie za darmo lub wesprzeć pomysł serii dowolną kwotą. Szkolenie odbędzie się 15 maja 2023 r.
Zapisy pod tym linkiem: https://sklep.securitum.pl/poznaj-bezpieczenstwo-windows-2–lokalne-uwierzytelnianie-i-autoryzacja
Za takie notatki należy się góra kubków sekuraka :D
Po prostu miodzio :D
Do kolegi wysyłamy czarną bluzę sekuraka :)
To ode mnie chociaż Bóg zapłać :-)
Dziękuję za ten materiał. Nie znajduję słów aby wyrazić swoje uznanie i podziękowanie. Jesteś niesamowity.