BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Hardening RemoteApp

09-01-2012 06:00 | Jacek Kochan
Dość często administratorzy serwerów terminalowych opartych o Windows 2008 / 2008 R2 chcieliby udostępniać aplikacje w trybie RemoteApp a równocześnie zabraniać dostępu na w pełni działający pulpit zdalny. W tym artykule przedstawię sposoby, dzięki którym można w pewnym stopniu taki efekt uzyskać.

Wstęp

Dość często administratorzy serwerów terminalowych opartych o Windows 2008 / 2008 R2 chcieliby udostępniać aplikacje w trybie RemoteApp a równocześnie zabraniać dostępu na w pełni działający pulpit zdalny. Dzięki temu użytkownik miałby niby mieć dostęp jedynie do okienka z aplikacją, i niby bez możliwości grzebania we współdzielonym systemie serwerowym. Na wstępie trzeba zaznaczyć, że takowa konfiguracja wspierana nie jest. Jednakże to, że nie jest wspierana nie oznacza, że nie jest do skonfigurowania w pewnym zakresie, by maksymalnie ograniczyć dostęp do systemu, powłoki użytkownika i pulpitu.

Pewnie niektórzy zadają sobie teraz pytania, dlaczego nie jest wspierana? Powód jest prosty. Otóż dlatego, gdyż technologia RemoteApp nie jest dodatkową sferą zabezpieczeń a jedynie sposobem prezentacji pulpitu użytkownika, a właściwie to jej ograniczeniem do otwartych okien z aplikacjami. RemoteApp korzysta z tej samej technologii i protokołów, co i zwykła sesja RDP. To co użytkownik może zrobić przez protokół RDP, teoretycznie może zrobić to samo poprzez RemoteApp. O tym należy pamiętać. Jeśli szukasz sposobu na większy hardening serwera udostępniającego aplikacje w trybie RemotApp, to musisz go traktować identycznie i pod tym samym kontem, jak każdy serwer pulpitów zdalnych. Poniższy sposób można potraktować jako proteza, która ogranicza dostęp do powłoki użytkownika, ale teoretycznie nie uniemożliwia na 100% dostępu do niej jak i do systemu.

Czym właściwie jest RemoteApp?

RemoteApp to taki tryb połączenia pulpitem zdalnym, w którym widoczne jest tylko okno z aplikacją/aplikacjami, a reszta, czyli sam pulpit, jest niewidoczna, a właściwie transparentna, podczas jej prezentacji na komputerze użytkownika.

Za prezentację pulpitu, również w trybie połączenia pulpitem zdalnym, odpowiadają między innymi dwa procesy uruchamiane na serwerze: USERINIT.EXE i EXPLORER.EXE. Natomiast po połączeniu się do usług RDS w trybie RemoteApp nie jest uruchamiana standardowa powłoka Explorer.exe. Zamiast tych dwóch procesów uruchamiane są RDPINIT.EXE i RDPSHELL.EXE. RDPSHELL to proces uruchamiany zamiast Eksploratora Windows, zapewniający jedynie działanie funkcji RemoteApp.

Różnica pomiędzy Pulpitem Zdalnym a RemoteApp tkwi również w zamykaniu sesji. Pulpit Zdalny można rozłączyć, klikając na krzyżyk w prawym górnym rogu okna Pulpitu Zdalnego. Uruchomione programy w tej sesji pozostają aktywne. Natomiast w trybie RemoteApp zamknięcie okna z aplikacją powoduje faktyczne jej zamknięcie, a monitorujący sesję proces RDPSHELL rozłączy sesję RDP, która pozostanie na serwerze w stanie Disconnected (jej wylogowanie powinna zapewnić odpowiednia konfiguracja serwera pod tym kątem). Jak więc użytkownik ma rozłączyć sesję RemoteApp bez zamykania aplikacji? Musi wcisnąć kombinację Ctrl+Alt+End która ukaże opcje menu Ctrl+Alt+Del i wtedy kliknąć na krzyżyk w prawym górnym rogu.

Skąd więc klient RDP ma wiedzieć, w jakim trybie ma się połączyć do serwera RDS? Oczywiście z pliku RDP, a konkretnie z ustawienia: remoteapplicationmode:i:1

Takie ustawienie zawiera plik RDP wygenerowany na serwerze w konfiguracji RemoteApp. Jeśli zmienimy jedynkę na zero, wówczas po uruchomieniu pliku nastąpi połączenie na pulpit zdalny i uruchomiony zostanie w nim dany program, zamiast powłoki Explorer.exe. Dzieje się tak, gdyż tworząc w konfiguracji RemoteApp plik .rdp do danej aplikacji, znajduje się w nim też ustawienie typu: alternate shell:s:||wordpad

Dopiero po wykasowaniu tego ustawienia, klient RDP połączy nas na w pełni działający pulpit zdalny (wnioskuję, że wpis ten znajduje się ze względów zgodności ze starszymi klientami RDP, bodajże z systemem Windows XP SP3, nie jest to jednak sprawdzona informacja na 100%). Za to, jaki program z listy RemoteApp zostanie uruchomiony, odpowiada ustawienie remoteapplicationprogram. Tu dla przykładu Wordpad z predefiniowanej listy konfiguracji roli RemoteApp: remoteapplicationprogram:s:||wordpad. Wartość tego atrybutu powiązana jest z aliasem programu RemoteApp zdefiniowanego na liście programów RemoteApp na serwerze. Spróbujmy zmienić pole Alias we właściwościach tego programu, zamieniając „Wordpad” na np. „Edytorek”.

Ta zmiana spowoduje, że nie połączymy się do serwera i otrzymamy w związku z tym ostrzeżenie:

Dopiero po zmianie ustawienia w pliku rdp na remoteapplicationprogram:s:||Edytorek pozwoli na uruchomienie aplikacji w trybie RemoteApp. Warto zauważyć, że ustawienie alternate shell: w pliku RDP, w trybie RemoteApp jest ignorowane. I odwrotnie. W trybie remoteapplicationmode:i:0, ignorowane są wpisy dotyczące trybu RemoteApp.

Uzbrojeni w tą wiedzę możemy przejść do konfiguracji serwera RDS.

Utworzenie polisy GPO

Całą konfigurację można zawrzeć w jednej domenowej polisie. Będzie tu nadawana konfiguracja użytkownika, ale polisa ma dotyczyć jedynie serwera bądź serwerów terminalowych. Dlatego też, jak zawsze w takiej sytuacji, polisa ma znaleźć się w OU z serwerami terminalowymi z ustawionym trybem sprzężenia zwrotnego zasad użytkownika. Zasada znajduje się w Computer Configuration\Administrative Templates\System\Group Policy\User Group Policy loopback processing mode. Polisę ustawiamy na Enabled, może pozostać w trybie Replace.

Dzięki temu ustawienia umieszczone w "User configuration" zostaną zaaplikowane użytkownikowi logującemu się tylko do tego serwera, do którego dana polisa GPO jest przyporządkowana.

Drugą rzeczą jaką powinniśmy zrobić, to wykluczenie działania polisy na administratorach serwera. W tym celu modyfikujemy ustawienia zabezpieczeń polisy (zakładka Delegation w przystawce GPMC, przycisk Advanced). Tutaj dodajemy grupę administratorów serwerów terminalowych bądź modyfikujemy istniejącą grupę Domain Admins, jeśli w naszym środowisku to wystarczy. Zaznaczamy ptaszek Na Deny przy Apply group policy i gotowe.

Wyłączenie standardowej powłoki użytkownika

Pierwszą rzeczą, jaką zrobimy, by „obejść” problem związany z dostępem do pełnego pulpitu użytkownika, będzie wyłączenie powłoki użytkownika w uprzednio utworzonej polisie. Do tego celu posłużą nam ustawienia w gałęzi User Configuration\Policies\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Remote Session Environment. Ustawiamy:

  • Always show desktop on connection na Disabled
  • Start a program on connection na Enabled i w polu Program Path and file name wpisujemy na przykład C:\Windows\System32\logoff.exe. Spowoduje to automatyczne wylogowanie sesji, jeśli będzie ona podłączana w zwykłym trybie Pulpitu Zdalnego. Można też wpisać ścieżkę do skryptu, który wyświatlałby odpowiedni komunikat użytkownikowi i po jego zamknięciu wylogował sesję.

Konfiguracja ta nie ma znaczenia dla trybu RemoteApp, dlatego otrzymujemy całkiem przyzwoity sposób na niedopuszczenie do uruchamiania zwykłych sesji Pulpitu Zdalnego.

Konfiguracja opcji Ctrl+Alt+Del

Następnym krokiem jest ograniczenie opcji znajdujących się po wciśnięciu kombinacji Ctrl+Alt+End, która jest „zdalnym” odpowiednikiem Ctrl+Alt+Del. Po podłączeniu się do sesji RemoteApp użytkownik przy pomocy powyższej kombinacji ma dostęp do Task Managera oraz opcji zamykania systemu (które to i tak nie zadziałają przy domyślnych uprawnieniach użytkownika, ale wyglądają słabo, a próba zostanie odnotowana w systemowym logu).

Dlatego też w naszej polisie należy skonfigurować:

  • w gałęzi User Configuration\Policies\Administrative Templates\System\Ctrl+Alt+Del Options: Remove Task ManagerEnabled
  • w gałęzi User Configuration\Policies\Administrative Templates\Start Menu and Taskbar: Remove and prevent access to the Shut Down, Restart, Sleep, and Hibernate commandsEnabled

Efekt będzie wyglądał w ten sposób:

Restrykcje na uruchamiane programy

Wszystkie wykonane dotychczas zmiany nie znaczyłyby nic, gdyby pominąć ten właściwie najważniejszy punkt. Mimo wszystkich tych ograniczeń użytkownik nadal ma możliwość uruchomienia czegokolwiek w systemie, do czego ma uprawnienia. Oto przykładowe odpalenie konsoli Powershell w sesji RemoteApp do aplikacji Wordpad:

W ten sposób cały misterny plan diabli wzięli, gdyż mimo pozornego braku dostępu do pełnej powłoki użytkownika, tenże mógłby uruchomić zarówno konsolę jak i Eksplorator bądź cokolwiek innego, korzystając z opcji w menu danej aplikacji.

Dlatego właśnie należy przedsięwziąć takie same środki bezpieczeństwa jak i dla normalnych sesji terminalowych. Można to osiągnąć na wiele sposobów, m.in.:

  • poprzez uprawnienia NTFS
  • korzystając z Software Restriciton Policy lub Applockera
  • jako uzupełnienie konfigurując polisy GPO dla użytkowników

Jako że jest to temat bardzo rozległy i opisywany w wielu innych publikacjach, przedstawię pokrótce podstawową konfigurację zabezpieczeń na poziomie polityk GPO.

Na pierwszy ogień – konfiguracja Software Restriction Policy. Zdecydowałem się na tym przykładzie skorzystać z tej technologii zamiast Applockera z tego względu, gdyż łatwiej jest w ten sposób nadać restrykcje na poziomie konfiguracji użytkownika, na wszystkich użytkowników za wyjątkiem administratorów, gdyż utworzona polityka GPO, którą obecnie modyfikujemy, ich nie obejmuje. Applocker natomiast nadawany jest na poziomie konfiguracji komputera i niestety nie posiada mechanizmu tworzenia wyjątków dla określonych grup użytkowników.

Konfiguracja ta, na wypadek gdyby ktoś już zapomniał, znajduje się w gałęzi User Configuration\Policies\Windows settings\Security Settings\Software Restriction Policies. Po utworzeniu nowej polityki wybieramy domyślny Security LevelDisallowed. W gałęzi Additional Rules znajdują się dwa domyślne wpisy zezwalające dostęp do folderów Windows i Program Files. Sugeruję pozostawić dostęp do Program Files (wpis z ProgramFilesDir) i zabronić dostępu do Windows (wpis z SystemRoot), chyba że ktoś chce tworzyć osobne wpisy dla każdego zainstalowanego programu z osobna.

Jeśli decydujemy się na pozostawienie dostępu do „Program Files”, wypadałoby dodać również regułę dla folderu „Program Files (x86)”. Uniwersalna ścieżka do tego folderu byłaby taka:

%HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86)%, lub zwykła C:\Program Files(x86)

Jeśli chodzi: o folder sytemowy, to po ustawieniu ścieżki do Windows na "Disallowed", należy niestety dodać wyjątki dla kilku binarek, bez których nawiązanie sesji stanie się niemożliwe. Z mojej praktyki wynika, że wymagane są wpisy o wartości Unrestricted dla ścieżek i plików:

  • C:\Users\*\AppData\Local\Temp\*\getpaths.cmd
  • C:\Windows\Application Compatibility Scripts
  • C:\Windows\System32\ie4uinit.exe
  • C:\Windows\System32\logoff.exe
  • C:\Windows\System32\rdpclip.exe
  • C:\Windows\System32\rdpinit.exe
  • C:\Windows\System32\rdpshell.exe
  • C:\Windows\System32\rundll32.exe
  • C:\Windows\System32\runonce.exe
  • C:\Windows\System32\usrlogon.cmd

Proszę zwrócić uwagę, że brakuje tu plików userinit.exe i Explorer.exe. Są one potrzebne do nawiązania zwykłej sesji Pulpitu Zdalnego a ich brak jest kolejną przeszkodą do jej nawiązania. Jako ciekawostka wspomnę, że mimo iż tym sposobem użytkownik ma również zabroniony dostęp do Task Managera, to nie ustrzegłoby to przed jego uruchomieniem z menu Ctrl+Alt+End, jeśli byśmy taką możliwość pozostawili użytkownikowi, nie konfigurując tej opcji w ustawieniach GPO Ctrl+Alt+Del Options.

Radzę monitorować Application Event Log pod kątem zdarzeń ze źródła SoftwareRestrictionPolicies ID 866, czy pojawiają się inne binarki, do których użytkownik powinien mieć również dostęp. Moja przykładowa gotowa lista polityk SRP wygląda więc tak:

Teraz próba uruchomienia Powershella z konta zwykłego użytkownika zakończy się niepowodzeniem:

Proszę pamiętać, że podczas testowania działania polityk użytkownika, po zmianie polityki należy najpierw wylogować jego sesję z serwera, gdyż zamknięcie okna RemoteApp spowoduje pozostawienie sesji w stanie Disconnected. Wówczas ponowne zalogowanie odbędzie się do tej samej sesji a nowa polityka po zmianach nie zostanie wtedy zaaplikowana.

Dodatkowe ustawienia polityk GPO dla użytkowników

W tym miejscu wymienię przykładowe ustawienia, które warto włączyć na serwerze RDS. Tak jak wcześniej wspomniałem, restrykcje GPO na użytkownika to temat na inny artykuł, ale parę istotnych ustawień warto tutaj przytoczyć.

Restrykcje na przeglądarkę Internet Explorer

Aplikacje często poprzez menu Narzędzia umożliwiają uruchamianie pewnych funkcji poprzez domyślną przeglądarkę. Może to być forma licencjonowania, Help, ściąganie tutoriali lub jakichś bibliotek. Jeśli nie życzymy sobie, by użytkownik miał możliwość korzystania z Internetu w sesji zdalnej, musimy taki dostęp zablokować. Można to zrobić na dwa sposoby:

  • Jeśli chcemy, by użytkownik miał dostęp do Intranetu:
    1. Ustawiamy adres serwera proxy na nieistniejący, np. na 127.0.0.1 i ewentualnie wpisujemy wyjątki dla danych adresów. Można to zrobić edytując ustawienia proxy w User Configuration\Policies\Windows Settings\Internet Explorer Maintenance\Connection\Proxy Settings lub tworząc szablon ustawień w preferencjach: User Configuration\Preferences\Control Panel\Internet Settings(aby zadziałało pod IE 9 potrzebny jest hotfix!)

      W tym wypadku użytkownik będzie mógł skorzystać jedynie z serwisu Bing.

    2. Dodatkowo trzeba zabronić użytkownikowi wejścia w te ustawienia. Administrative Templates\Windows Components\Internet Explorer: Disable changing connection settings ustawiamy na Enabled.
  • Sposób drugi to całkowicie wykluczyć możliwość uruchamiania Internet Explorera, dodając reguły do RemoteApp lub Software Restriction Policy. Należy wykluczyć dostęp do ścieżek:
    • C:\Program Files (x86)\Internet Explorer
    • C:\Program Files\Internet Explorer

Niestety istnieją aplikacje, np. Matlab, które wyposażone są we własne przeglądarki, więc blokowanie dostępu do Internet Explorera bądź innych zainstalowanych w tym przypadku nie pomoże. Wówczas trzeba pomyśleć o zablokowaniu dostępu do konkretnej binarki lub pliku dll w tej aplikacji.

Restrykcje na dostęp do liter dysków

Dodatkowym utrudnieniem w dostępie do systemu może być nałożenie restrykcji dostępu do dysków lokalnych. Można to skonfigurować w polisie Administrative Templates\Windows Components\Windows Explorer: Prevent Access to drives from My Computer. Trzeba jednak tu zachować ostrożność, gdyż zablokowanie dostępu do wszystkich dysków może spowodować niestabilność w działaniu aplikacji. Ten scenariusz najlepiej się sprawdza, gdy użytkownik posiada zamapowany katalog domowy do udziału sieciowego, do którego ma dostęp. Wówczas zwykle można zablokować dostęp do dysków lokalnych. Dobrze by było, gdyby aplikacje były instalowane na wydzielonej partycji lub by były uruchamiane poprzez App-V z dysku Q:. Wtedy to z większym spokojem można blokować systemową partycję.

Inne ważniejsze restrykcje

Warto również skorzystać z następujących ustawień ze ścieżki User Configuration\Policies\Windows Settings\Administrative Templates:

  • \Control Panel: Prohibit access to the Control Panel: Enabled
  • \System: Prevent access to the command prompt: Enabled (nie blokuje Powershella)
  • \System: Prevent access to registry editing tools: Enabled

Podsumowanie

Powyższy artykuł jest w formie przykładu, w jaki sposób skonfigurować środowisko użytkownika. Jeśli na przykład ktoś z jakichś powodów zechce dać pełne uprawnienia do dostępu do folderu systemowego, to będzie musiał pomyśleć nad ograniczeniami w dostępie do jego składników, Powershella itd. Można też przemyśleć kwestię nadania uprawnień ntfs, które stanowiłyby doskonalszą barierę dla użytkownika, niż polisy GPO. Jeśli ktoś ma jakieś inne pomysły, zachęcam do dzielenia się nimi w komentarzach.

Komentarze 12

Piotr Pawlik Redaktor
Piotr Pawlik
3486 pkt.
Guru
MVP
09-01-2012
oceń pozytywnie 0
Dzięki Jacku - bardzo dobra lektura do porannej kawy.
unio
unio
129 pkt.
Junior
09-01-2012
oceń pozytywnie 0
A ja aby zabezpieczyć dostęp do pełnego zdalnego pulpitu ustawiam start logoff.exe po zalogowaniu dla danego użytkownika.
unio
unio
129 pkt.
Junior
10-01-2012
oceń pozytywnie 0
tak to jest jak się nie czyta do końca tylko nagłówek :)) widzę, że tu tez jest opisany ten sam sposób logoff.exe :)) sorry za śmiecenie
Kondi
Kondi
69 pkt.
Poczatkujacy
11-01-2012
oceń pozytywnie 0
Świetny art - chapeau bas...
Kondi
Kondi
69 pkt.
Poczatkujacy
11-01-2012
oceń pozytywnie 0
Znalazłem chyba pomyłkę: "w gałęzi User Configuration\Policies\Administrative Templates\System\Ctrl+Alt+Del Options: Remove Task Manager – Disabled" - powinno być raczej na Enable, skoro ma usunąć...
Jacek Kochan Ekspert WSS
Jacek Kochan
3627 pkt.
Guru
14-01-2012
oceń pozytywnie 0
Tak, dzięki za zwrócenie uwagi!
wolfikx
wolfikx
398 pkt.
Junior
30-01-2012
oceń pozytywnie 0
Bardzo ciekawy art !
Darek  Tkaczyk
Darek Tkaczyk
0 pkt.
Nowicjusz
04-02-2012
oceń pozytywnie 0
Czy można to wszystko uzyskać gdy TS nie jest członkiem domeny?Edytowano 1 raz. Ostatnio 2012-02-04 20:34:21 przez jbond007.
Ziemek Borowski
Ziemek Borowski
05-02-2012
oceń pozytywnie 0
@jbond007 GPO istnieje poza domeną, choć zarządzanie nim jest mocno utrudnione. A w ogóle skąd pomysł braku domeny :).
TomekSojka
TomekSojka
8 pkt.
Nowicjusz
25-04-2012
oceń pozytywnie 0
Mam podobne pytanie, opisana konfugiracja działa bardzo dobrze z kontami AD, ale u mnie cześć użytkowników łączy sie poprzez konta lokalne. W Local Group Policy moge wprowadzic takie same ustawienia jak w GPO, ale jak z LGP wykluczyć grupę administratorów lokalnych?
Ziemek Borowski
Ziemek Borowski
25-04-2012
oceń pozytywnie 0
nie robić tego. Teoretycznie (dawno tego nie robiłem i moge coś źle pamiętać) możesz po prostu określonym grupom/użytkownikom zakazać dostępu do plików LGP na serwerze.
Jacek Kochan Ekspert WSS
Jacek Kochan
3627 pkt.
Guru
10-07-2012
oceń pozytywnie 0
Mała errata: Przy Remoteapp dostęp do userinit.exe (w przeciwieństwie do Explorer.exe) również jest potrzebny do inicjacji sesji.
pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.