Współczesne systemy operacyjne, a w tym Windows XP z SP2 oraz Windows Vista umożliwiają pracę na różnych poziomach uprzywilejowania różnym użytkownikom systemu.
Każda aplikacja wymaga działania w określonym środowisku i kontekście. Do poprawnego funkcjonowania potrzebuje dostępu do różnego rodzaju zasobów, w tym plików i folderów czy też kluczy rejestru. Poza wyjątkami, do których zalicza się aplikacje systemowe oraz narzędzia wspierające administrację systemem żadna aplikacja nie powinna wymagać od użytkownika pracy w trybie uprzywilejowanym. Współczesne systemy operacyjne, a w tym Windows XP z SP2 oraz Windows Vista umożliwiają pracę na różnych poziomach uprzywilejowania różnym użytkownikom systemu. Microsoft tworząc programy związane z logo Windows, w tym ‘Certified for Windows Vista’ oraz ‘Works with Windows Vista’ wymaga od dostawców oprogramowania, aby tworzone przez nich aplikacje funkcjonowały w kontekście użytkowników o jak najniższym poziomie uprzywilejowania. W przypadku logo ‘Certified for...’ przekłada się to na bardzo ostry wymóg, który zakłada, że jeśli jakakolwiek część pisanej przez nas aplikacji wymaga pracy w trybie uprzywilejowanym, to musimy ją wydzielić do osobnego .exe oraz uzyskać osobne zezwolenie z Microsoftu, żeby móc uzyskać certyfikat. Tylko narzędzia systemowe mogą starać się o to zezwolenie, żadne aplikacje klienckie, w tym gry, narzędzia wspierające pracę biurową, czy też klienty systemów pocztowych i tym podobne nie będą brane pod uwagę.
Dzisiejsza rzeczywistość
Realia w Polsce są jednak takie, że nierzadko aplikacje pisane są ‘na miarę’, bez starania się o certyfikat Logo Windows. Firma developerska umawia się z klientem na dostarczenie oprogramowania o określonej funkcjonalności, bardzo często zapominając o tym, że program ma pracować w określonym środowisku, a więc również np. przy ograniczonym dostępie do wielu zasobów. Często jest tak, że aplikacja jest kontynuacją rozwiązań sprawdzonych w poprzednich wersjach Windows (w tym również linii Win9x), bądź też jest portem aplikacji pracującej pod systemami non-MS (tu celują przede wszystkim aplikacje graficzne i fotoedytorskie).
Tym samym my, jako odbiorcy oprogramowania często dostajemy produkt nie przetestowany do pracy w środowisku wieloużytkownikowym. Jest to swoiste ‘kukułcze jajo’, z którym administratorzy muszą się jakoś borykać, bo albo nie mają wpływu na proces wytwarzania tej aplikacji (produkt pudełkowy, bądź ‘na zamówienie’, ale już po wdrożeniu), albo po prostu nie mają odpowiedniej siły przebicia i dostawcy oprogramowania traktują wymóg pracy w określonym kontekście jako ‘dodatkowo płatny feature’, na który zarząd nie zamierza się decydować.
Można się sprzeczać o to, czy programista tworzący aplikację powinien pracować w kontekście ograniczonego użytkownika, jednak dla testera aplikacji powinno to być obligatoryjne. Rzeczywistość oczywiście znowuż nas nie zaskakuje i albo to my (odbiorca) testujemy aplikację, albo testerami są sami developerzy, którzy (parafrazując słowa Fowlera) ‘zmieniają czapkę z programisty na testera’, pozostawiając jednak (tu Brzechwa) ‘admina kubraczek’.
OK, więc co możemy w tej sytuacji zrobić?
Dobrze, mamy zatem program, który uruchomiony na koncie administratora działa poprawnie, a gdy tylko przelogujemy się na zwykłego użytkownika i teraz spróbujemy popracować, to dostajemy masę bardzo dziwacznych komunikatów o błędach (wersja optymistyczna), bądź aplikacja w ogóle się nie uruchamia (wersja pesymistyczna, choć dla dalszych analiz najwygodniejsza), lub też dzieje się coś jeszcze innego, jednak program nie spełnia swoich funkcji prawidłowo. Z moich doświadczeń wynika, że najczęściej mamy do czynienia z tego typu sytuacją w przypadku niewystarczających uprawnień do systemu plików, dalej nieodpowiednich uprawnień do rejestru i na samym końcu braku wymaganych przywilejów systemowych. Pozostałe przypadki stanowią tak rzadki margines, że nie warto o nich w tym miejscu wspominać. Poniżej przedstawię pokrótce sposoby radzenia sobie ze wspomnianymi problemami. Zanim jednak przejdziemy do szczegółów, sugeruję zapoznać się z programem autorstwa Marka Russinovicha i Bruce’a Cogswella ‘Process Monitor’ (w skrócie procmon), który jest mariażem ‘File Monitor’a’ (filemon) oraz ‘Registry Monitor’a’ (regmon) ‘na dopalaczach’. Procmon (obecnie wersja 1.01) jest do ściągnięcia z serwisu sysinternals przeniesionego pod koniec 2006 roku na strony technetu. Wspomniane narzędzia diagnostyczne przedstawione są w godzinnym webcaście z TechEd’06. Sam serwis sysinternals. stanowi kopalnię narzędzi diagnostycznych i systemowych, którą ciężko porównywać z jakimkolwiek innym serwisem technicznym poświęconym MS Windows (i nie tylko!). Poza wspomnianymi wcześniej szczególnie polecam ‘Process Explorer’, ‘Autoruns’ oraz zestaw ‘PsTools’. Uwaga! Procmon musi być uruchomiony w kontekście konta należącego do lokalnej grupy administratorów!
Do naszych testów wykorzystamy filemona, którego spróbujemy uruchomić w kontekście zwykłego użytkownika.
Rozwiązywanie problemów z brakiem uprawnień do systemu plików i rejestru systemowego
Najnowsza wersja procmona posiada wiele udoskonaleń w stosunku do swoich poprzedników; na dobrą sprawę aplikacja została przepisana od nowa pozostawiając jedynie znany wszystkim interfejs użytkownika. Zarówno filemon jak i regmon w przypadku dużej ilości wpisów zaczynały się ‘dławić’ i dokładna analiza była bardzo utrudniona (co sprowadzało się do przenoszenia logu sesji do bazy i obróbce w bazie danych). W przypadku procmona ten element został znacząco poprawiony i nic nie stoi na przeszkodzie, żeby pozostawić procmon aktywny przez cały czas analizy.
- Logujemy się na konto zwykłego użytkownika.
- Uruchamiamy procmon jako użytkownik należący do lokalnej grupy administratorów, np. korzystając z menu kontekstowego eksploratora (‘Uruchom jako...’). W przypadku pierwszego uruchomienia potwierdzamy, że zgadzamy się z warunkami licencji.
- Z menu ‘Filter’ wybieramy pozycję ‘Filter’ (ctrl+L). Pojawia się okno dialogowe ‘Process Monitor Filter’.
- Korzystając z list rozwijanych oraz przycisku ‘Add’ dodajemy odpowiednio (Rysunek 1): ‘Process Name’, ‘is’, Filemon.exe, ‘Include’ oraz ‘Result’, ‘is’, ACCESS DENIED, ‘Include’ i klikamy ‘OK’
- W menu ‘File’ upewniamy się, że zaznaczona jest opcja ‘Capture Events’.
- Uruchamiamy filemona (jako zwykły użytkownik) i potwierdzamy komunikat błędu. UWAGA! Rozluźnianie list ACL na katalogach systemowych oraz kluczach Services znajdujących się w gałęzi HKLM wykraczają poza dobre obyczaje administracyjne i podane dalej instrukcje przedstawione są wyłącznie w celach edukacyjnych!
- Przechodzimy do procmona (Rysunek 2)
- Korzystając z menu kontekstowego dla wpisów wybieramy ‘Jump’ (ctrl+J), dzięki czemu szybko trafiamy do odpowiednich miejsc w systemie plików oraz rejestrze.
- Modyfikujemy listy ACL dodając odpowiednie uprawnienia. W przypadku katalogu c:\windows\system32\drivers\ wymagane są uprawnienia do zapisu oraz odczytu dla nieistniejącego pliku FILEM70.SYS, więc decydujemy się na ustalenie ‘Tworzenie plików/Zapis danych’ oraz ‘Odczyt atrybutów’ dla ‘Ten folder i pliki’:
MGRZEGORZEWSKI\test:(OI)(dostęp specjalny:) SYNCHRONIZE FILE_WRITE_DATA FILE_READ_ATTRIBUTES
W przypadku rejestru sprawa jest nieco gorsza, ponieważ filemon usuwa badany klucz przy starcie. Wstępnie ustawiamy dostęp dla użytkowników lokalnych dla całego klucza Services na ‘Full Control’.
- Czyścimy log procmona (ctrl+X)
- Przy ciągle aktywnym procmonie uruchamiamy ponownie filemon. Upewniamy się, że nie pojawiają się dodatkowe wpisy z wynikiem ‘ACCESS DENIED’.
Tę część analizy mamy za sobą.
Rozwiązywanie problemów z niewystarczającymi przywilejami.
To, że filemon wymagał dostępu do zapisu w katalogu sterowników wydaje się być nieprzypadkowe. Swoją intuicję potwierdzamy analizą wymaganego zestawu przywilejów dla konta użytkownika, na którym ma pracować filemon.
W celu ustalenia zestawu przywilejów wymaganych przez tę aplikację wykorzystamy systemowy dziennik zdarzeń.
- Logujemy się na konto zwykłego użytkownika.
- Uruchamiamy mmc.exe jako użytkownik z uprawnieniami administratora.
- Wybieramy Plik-Dodaj/usuń przystawkę
- Klikamy ‘Dodaj’
- W oknie ‘Dodawanie przystawki autonomicznej’ dodajemy ‘Zasady grupy’ (występuje również jako ‘Edytor obiektów zasad grupy’)
- Klikamy ‘dodaj’
- W oknie ‘Wybieranie obiektu zasad grupy’ klikamy ‘Zakończ’ i zamykamy okno z listą przystawek oraz ‘Dodaj/usuń przystawkę’
- Nawigujemy do: ‘Zasady komputer lokalny’-’Konfiguracja komputera’-’Ustawienia systemu Windows’-’Ustawienia zabezpieczeń’-’Zasady lokalne’-’Zasady inspekcji’.
- Klikamy dwukrotnie zasadę ‘Przeprowadź inspekcję użycia uprawnień’ i zaznaczamy obie dostępne opcje (Sukces i Niepowodzenie). Przykładowe ustawienie ilustruje Rysunek 3.
- Uruchamiamy filemon.
- Uruchamiamy eventvwr.msc korzystając z konta uprzywilejowanego.
- Przechodzimy do podglądu zdarzeń Zabezpieczeń.
- W razie potrzeby filtrujemy zdarzenia ustawiając jako źródło ‘Security’ oraz kategorię ‘Wykorzystanie przywilejów’.
- Odnajdujemy wpis dotyczący testowego użytkownika.
Przykładowy wpis w dzienniku zdarzeń zabezpieczeń przy nieudanej próbie załadowania sterownika przedstawiony jest na Rysunku 4.
Typ zdarzenia: Inspekcja niepowodzeń Źródło zdarzenia: Security Kategoria zdarzenia: Wykorzystanie przywilejów Identyfikator zdarzenia: 577 Data: 2007-02-20 Godzina: 17:56:09 Użytkownik: mordor\test Komputer: MGRZEGORZEWSKI Opis: Wywołana uprzywilejowana usługa: Serwer: Security Usługa: - Podstawowa nazwa użytkownika: test Podstawowa domena: mordor Podstawowy identyfikator logowania: (0x0,0xB41513) Nazwa użytkownika klienta: - Domena klienta: - Identyfikator logowania klienta: - Przywileje: SeLoadDriverPrivilege Aby znaleźć więcej informacji, zobacz http://go.microsoft.com/fwlink/events.asp w Centrum pomocy i obsługi technicznej.
Do uaktywnienia wymaganego przywileju skorzystamy z przystawki zasad grupy opisanej uprzednio (punkty 1-6 j.w.).
- Nawigujemy do: ‘Zasady komputer lokalny’-’Konfiguracja komputera’-’Ustawienia systemu Windows’-’Ustawienia zabezpieczeń’-’Zasady lokalne’->Przypisywanie praw użytkownika’
- Dwukrotnie klikamy zasadę ‘Ładowanie i usuwanie sterowników urządzeń’. Pojawia się okno ‘Właściwości: Ładowanie i usuwanie sterowników urządzeń’.
Pomocna podczas modyfikacji może okazać się lista przywilejów wraz z ich polskim opisem. Uwaga! Lista zawiera przywileje występujące w systemie Windows XP SP2 i różni się od odpowiedniej dla innych systemów.
Lista przywilejów wraz z polskim opisem:
sedebugprivilege Analizowanie programów selockmemoryprivilege Blokowanie stron w pamięci semachineaccountprivilege Dodawanie stacji roboczych do domeny seincreasequotaprivilege Dopasowywanie przydziałów pamięci dla procesu setcbprivilege Działanie jako element systemu operacyjnego seauditprivilege Generowanie zdarzeń inspekcji zabezpieczeń seinteractivelogonright Logowanie lokalne seservicelogonright Logowanie w trybie usługi sebatchlogonright Logowanie w trybie wsadowym seloaddriverprivilege Ładowanie i usuwanie sterowników urządzeń sesystemenvironmentprivilege Modyfikowanie zmiennych środowiskowych systemu sedenyremoteinteractivelogonright Odmawiaj logowania za pomocą usług terminalowych sedenynetworklogonright Odmowa dostępu do tego komputera z sieci sedenyinteractivelogonright Odmowa logowania lokalnego sedenyservicelogonright Odmowa logowania w trybie usługi sedenybatchlogonright Odmowa logowania w trybie wsadowym serestoreprivilege Odtwarzanie plików i katalogów seimpersonateprivilege Personifikowanie klienta po uwierzytelnieniu sechangenotifyprivilege Pomijanie sprawdzania przebiegu seprofilesingleprocessprivilege Profilowanie pojedyńczego procesu sesystemprofileprivilege Profilowanie wydajności systemu setakeownershipprivilege Przejmowanie własności plików lub innych obiektów sesyncagentprivilege Synchronizowanie danych usług katalogowych sebackupprivilege Tworzenie kopii zapasowych plików i katalogów secreateglobalprivilege Tworzenie obiektów globalnych secreatepagefileprivilege Tworzenie pliku stronicowania secreatepermanentprivilege Tworzenie stale udostępnianych obiektów secreatetokenprivilege Tworzenie żetonu seundockprivilege Usuwanie komputera ze stacji dokującej senetworklogonright Uzyskiwanie dostępu do tego komputera z sieci seenabledelegationprivilege Włączanie zaufania dla komputera i kont użytkowników do delegowania semanagevolumeprivilege Wykonywanie zadań konserwacji woluminu seremoteshutdownprivilege Wymuszanie zamknięcia systemu z systemu zdalnego seassignprimarytokenprivilege Zamiana żetonu na poziomie procesu seshutdownprivilege Zamykanie systemu sesecurityprivilege Zarządzanie inspekcją i dziennikiem zabezpieczeń seremoteinteractivelogonright Zezwalaj na logowanie za pomocą usług terminalowych sesystemtimeprivilege Zmiana czasu systemowego seincreasebasepriorityprivilege Zwiększanie priorytetu szeregowania
Niestety dodanie przywileju ‘Ładowanie i usuwanie sterowników urządzeń’ nie przyniosło oczekiwanych rezultatów. Z jakiegoś powodu nie zostało odnotowane jeszcze jedno wymaganie w stosunku do zestawu brakujących przywilejów. Do ustalenia brakującego przywileju skorzystamy z narzędzia Token Monitor (tokenmon) (dostępnego ciągle pod starym adresem). Z mojego doświadczenia wynika, że w środowisku Windows XP SP2 PL tokenmon potrafi zachowywać się bardzo nieprzewidywalnie i powodować pady lsass.exe, więc zachęcam do skorzystania wpierw z metody opisanej powyżej i przejścia do tokenmona w ostateczności. Warto zwrócić uwagę na datę kompilacji – 2000 rok. Wiele się od tamtego czasu zmieniło ;)
- Uruchamiamy tokenmon w kontekście użytkownika uprzywilejowanego.
- Korzystając z menu Edit wybieramy pozycję Filter/Highlight i w polu ‘Include’ wpisujemy ‘Filemon*’
- Uruchamiamy filemon.
- Przeglądamy log tokenmona w poszukiwaniu zdarzeń, dla których w polu ‘Request’ występuje ‘ADJUST PRIVILEGES’.
- W polu ‘Other’ znajdują się informacje tekstowe o wymaganych przywilejach. Zauważmy, że poza ‘LOAD_DRIVER’ znajduje się wymaganie w stosunku do przywileju ‘UNDOCK’ oraz ‘DEBUG’. Domyślamy się, że chodzi o przywileje a. seundockprivilege - Usuwanie komputera ze stacji dokującej oraz b. sedebugprivilege - Analizowanie programów W przypadku tego pierwszego nasz user już go posiada (dzięki obecności w lokalnej grupie użytkowników), natomiast brak nam drugiego z nich.
- Dodajemy przywilej ‘Analizowanie programów’. UWAGA! Przywilej ‘Analizowanie programów’ jest bardzo silnym przywilejem, który pozwala np. dzięki funkcji CreateRemoteThread na ‘wstrzykiwanie’ naszego kodu w obszar innego procesu działającego w kontekście innego użytkownika. Potencjalne zastosowania tego przywileju są bardzo duże i należy wystrzegać się udostępniania go zwykłym użytkownikom. Tutaj kolejna uwaga: do debuggowania własnych procesów nie jest wymagany ten przywilej!
- Uruchamiamy filemon.
Działa!
Zakończenie analizy
Uruchomienie aplikacji w kontekście zwykłego użytkownika nie jest końcem analizy. Powinniśmy przejrzeć jeszcze raz wszystkie zmiany w systemie, których dokonaliśmy i począwszy od pierwszej z nich zawężać zestaw wymaganych uprawnień i przywilejów tak, aby aplikacja (w naszym przypadku filemon) dalej funkcjonowała poprawnie, jednak zestaw zmian był jak najmniejszy. W naszym przypadku okazuje się, że pomimo braku dostępu do klucza rejestru, filemon działa poprawnie. Możemy zatem usunąć ‘Full Control’ dla użytkowników lokalnych.
Rozważania końcowe
Opisany sposób analizy jest bardzo powierzchowny i nie musi prowadzić do sukcesu. Poza najczęstszą przyczyną jaką jest ‘ACCESS DENIED’ warto zwrócić uwagę na wszelkie ‘NOT FOUND’, które mogą wskazywać na to, że aplikacja ‘spodziewa’ się jakiegoś zasobu i prawdopodobnie z powodu błędnego procesu instalacyjnego nie może się do niego dostać. Częstą przyczyną bywają uszkodzone pliki konfiguracyjne i wówczas możemy natknąć się na błędy końca pliku, etc., ale tu prawdopodobnie wystarcza przeinstalowanie aplikacji. Zdarzają się również przypadki aplikacji takie jak choćby procmon, kiedy nawet po dodaniu użytkownikowi dowolnego zestawu przywilejów oraz ustawienia list ACL w odpowiednich kluczach rejestru oraz w systemie plików aplikacja dalej nie umożliwia analizowania zdarzeń. Jak się okazuje, procmon stanowi jeden z nielicznych wyjątków aplikacji, kiedy znacznik procesu musi mieć jawnie wyspecyfikowany well-known SID lokalnej grupy administratorów i nie może on mieć atrybutu tylko do odmowy.
Przydatne aplikacje
W swojej praktyce często stosuję narzędzia sysinternals, o których wcześniej pisałem, a także narzędzia dołączone do książek Jeffreya Richtera (2) i innych poświęconych tworzeniu oprogramowania i jego debuggowaniu. W przypadku książki (2) warto wspomnieć o:
- TokenMaster – pomocny przy ustaleniu minimalnego zestawu przywilejów wymaganych do działania aplikacji poprzez tworzenie ograniczonego znacznika
- Trustee Manager – pomocny przy ustawianiu zestawu przywilejów
Zalecana literatura:
Bezpieczny kod. Tworzenie i zastosowanie. Michael Howard, David Leblanc. Polskie wydanie – APN Promise, Warszawa 2002
Programming Server-Side Applications for Microsoft Windows 2000. Jeffrey Richter, Jason D. Clark. Microsoft Press, 2000
The .NET Developer's Guide to Windows Security. Keith Brown. Addison Wesley, 2004. Dostępna online
Autor: Michał Grzegorzewski (mgrzeg)