Wieloskładnikowe uwierzytelnianie w Powershell

20 stycznia 2017 at 10:08

Czasami/Często albo nawet i częściej niż często zachodzi konieczność przekazania komuś kompetencji w zakresie danej technologii. Gdy tylko jest to możliwe odbywa się to poprzez delegację uprawnień na poziomie aplikacji. Niestety nie zawsze jest to możliwe i zdarzają się sytuacje, w których nie można/nie da się (lub nie jest to wygodne) wydelegować uprawnień. Wtedy zazwyczaj pojawia się konieczność wydelegowania uprawnień w ramach jakiegoś konta ‚X’ i przekazania poświadczeń tego konta do grupy użytkowników celem wykonania swoich zadań.

Właśnie w tym miejscu pojawia się problem jak zrobić to dobrze aby uniknąć hardcodowania haseł w treści skryptów:

Nie tędy droga – nie idźmy nigdy tą drogą błagam :)

Hasło czystym tekstem w skrypcie to nie jest dobry pomysł. NIGDY! Natomiast próby jego „ukrywania” czy „zaciemniania” są zawsze tylko półśrodkami. Zabieg zapisania hasła w formie:

Może i utrudnia odczytanie takiego hasła wprost, ale umówmy się że nie stanowi najmniejszego problemu aby zrobić „reverse-engeneering” i wyciągnąć hasełko :)

Kolejnym sposobem jest wykorzystanie Secure-String. Pomysł lepszy, ale nadal to szyfrowanie jest słabe i stosunkowo prosto odczytywalne:

Wystarczy wykonać:

I już znamy hasło w postaci czystego tekstu. A dodatkowo w przypadku chęci skorzystania z zapisanych poświadczeń na innej stacji odbijemy się od komunikatów o błędach, ponieważ dane został zaszyfrowane kluczem na stacji źródłowej.

Można by wymieniać jeszcze więcej bardziej wyrafinowanych metod szyfrowania/zaciemniania i utrudniania dostępu do hasła/poświadczeń w Powershellu, ale tak długo jak bazujemy tylko na pojedynczym składniku uwierzytelnienia (dostępie do pliku/skryptu z hasłem) tak długo jest to tylko odwlekanie porażki, na którą jesteśmy skazani.

Rozwiązaniem jest tu zastosowanie 2FA/MFA (2 Factor-Authenticaion / Multi-Factor-Authentication), czyli bazowanie na czymś co musisz znać (hasło zabezpieczone w skrypcie/pliku) oraz czymś co musisz mieć (np. certyfikat).

W najprostszej wersji sprowadza się to do:

Wygenerowania certyfikatu AES256

Następnie zaszyfrowania hasła tymże certyfikatem i zapisanie do pliku:

W takim podejściu przede wszystkim mamy swobodę wykorzystania poświadczeń na dowolnej stacji, bo nie było szyfrowania kluczem prywatnym stacji, tylko wygenerowanym przez nas certyfikatem, ale oprócz tego mamy możliwość wykorzystania MFA. Jak tego dokonać?

  1. Stosujemy wszystkie wcześniejsze zabawy w stylu zaciemniania danych dotyczących wykorzystania plików z poświadczeniami i ścieżek do hasła.
  2. Plik z hasłem umieszczamy na jakimś zasobie sieciowym a dostęp do niego ograniczamy poprzez uprawnienia NTFS i Share bazując na grupach Active Directory. W ten sposób ograniczamy możliwość dostępu on-demand. (Oczywiście można plik skopiować, ale najpierw trzeba być uprawnionym do dostępu do pliku).
  3. Certyfikat przekazujemy tylko uprawnionym do tego użytkownikom – najlepiej na nośniku wymagającym wprowadzenia dodatkowego hasła i przeznaczonym tylko do odczytu.
  4. Skrypt kompilujemy do pliku exe aby nie był wprost edytowalny jak ps1

Co dzięki temu zyskujemy? Przede wszystkim kilka warstw i sposobów zabezpieczeń poświadczeń. (Uprawnienia NTFS, dodatkowy nośnik danych z certyfikatem, zabezpieczenie certyfikatu innym hasłem oraz szyfrowanie właściwych poświadczeń z wykorzystaniem wszystkich ww. mechanizmów). Oczywiście użytkownik, dla którego przeznaczony jest skrypt będzie w stanie odszyfrować hasło do postaci czystego tekstu, ale już atakujący będzie się musiał trochę napocić i złamać przynajmniej 2 różne zabezpieczenia (hasło do nośnika; przejęcie certyfikatu; uprawnienia NTFS do pliku z hasłem) a jak wiadomo atakujący wybierają zawsze najsłabszy punkt i raczej nie lubią się pocić nad lepiej zabezpieczonymi przypadkami :)

Co ważne zyskujemy jeszcze jedno – niesamowitą elastyczność – możemy w dowolnej chwili zmienić hasło „właściwe” i zapisać nowe poświadczenia z wykorzystaniem tego samego certyfikatu do pliku w udostępnionej lokalizacji. Użytkownik korzystający ze skryptu nie będzie o tym nawet wiedział, a my wprowadzamy dodatkową trudność – zmienność poświadczeń na przestrzeni krótkiego czasu. Jeśli natomiast atakujący uzyska dostęp do zasobu z hasłem a certyfikat zostanie wykradziony/skompromitowany to musimy po prostu wygenerować nowy certyfikat, z jego pomocą wygenerować nowe pliki zaszyfrowanych haseł i przekazać je użytkownikom końcowym – w końcu nie ma takiego zabezpieczenia, którego nie da się złamać, a każdy system bezpieczeństwa jest tak silny jak jego najsłabsze ogniwo (użytkownik?) :)

Oczywiście zapisywanie poświadczeń w jakiejkolwiek formie to zawsze ZŁO, ale wykonanie tego w opisany sposób powinno znacząco podnieść poziom bezpieczeństwa i zapewnić niesamowitą elastyczność dla administratorów.

Enjoy :)

A jak skorzystać z tak zabezpieczonego hasła poniżej: