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