Bezpieczeństwo w PowerShell

Autorzy: Michał Gajda


Windows, powershell, cmd, Cmdlet, ActiveDirectory, bezpieczeństwo, MakeCert, certyfikat


PowerShell z racji swoich możliwości pozwala na prawie całkowite zarządzanie środowiskiem IT, dlatego kwestie bezpieczeństwa są tutaj niezwykle ważne. Najczęstszą przyczyną naruszania bezpieczeństwa w PoweShellu nie są pojedyncze polecenia, gdyż te są wykonywane z mniejszą lub większą świadomością użytkownika.

Główny problem takich środowisk, i to niezależnie od rodzaju systemu, to skrypty. W naszym przypadku, zarówno w formie dodatkowych modułów udostępnianych w sieci, jak i zwykłych plików .ps1, gdyż jak zapewne wiemy w sieci krąży wiele treści, która nie zawsze jest tym czym wydaje nam się że jest. Gdyby więc nie wbudowane mechanizmy obronne PowerShella, moglibyśmy zupełnie przypadkowo i nieświadomie uruchomić jakiś złośliwy skrypt, a wtedy może być już za późno.

Zaprezentujmy jednak jak broni się PowerShell, spróbujmy napisać prosty skrypt i wykonajmy go najpierw jako zwykłe polecenie:

 

Write-Host "Hello World"

 

Następnie stwórzmy plik tekstowy z rozszerzeniem .ps1, użyjmy w nim powyższy kod i spróbujmy wykonać taki plik w PowerShellu.

img1.jpg

File P:\hello.ps1 cannot be loaded because the execution of scripts is disabled on this system.

Jak widzimy możliwość wykonania takiego skryptu została zablokowana poprzez wewnętrzny mechanizm obronny PowerShella.

Zanim jednak przejdziemy do etapu zarządzania tymi polisami, dowiedzmy się jakie mamy poziomy zabezpieczeń oraz jak one działają. Wiedzę tutaj przedstawioną będę czerpał z dokumentacji Windows PowerShell dotyczącej polityk wykonywania skryptów.

Get-Help Get-Help About_Execution_Policies

 

Dostępne poziomy polityki wykonywania skryptów:

  • Restricted - czyli domyślnie ustawiona polityka w środowisku PowerShell. Jest to najbardziej restrykcyjna polityka pozwalająca tylko na uruchamianie poszczególnych komend. Jedynym wyjątkiem od tej reguły są natywne moduły dedykowane do zarządzania poszczególnymi technologiami Microsoftu.
  • AllSigned - czyli polityka pozwalająca już na uruchamianie skryptów, ale tylko tych, które zostały podpisane przez zaufanego wydawcę.
  • RemoteSigned - polityka ta pozwala na wykonywanie skryptów z lokalnego komputera bez konieczności ich podpisywania. Jednakże jeśli skrypt pochodzi z Internetu to musi on być podpisany przez zaufanego wydawcę - lub podpisany przez administratora, ale o tym później.
  • Unrestricted - Polityka najmniej zalecana, gdyż zezwala na wykonywanie wszystkich skryptów. Posiada jednak drobne zabezpieczenie, mianowicie w przypadku skryptów ściągniętych z Internetu wyświetla się stosowny komunikat o pochodzeniu skryptu.

Dla ciekawostki istnieją jeszcze dwie dodatkowe polisy, jednakże ich zastosowanie nie jest przeznaczone dla zwykłego użytkownika.

  • Bypass - polityka ta nie blokuje niczego ani nawet nie zwraca  żadnych ostrzeżeń. Jest stosowana tylko do wykonywania konfiguracji Windows PowerShell oraz jest wbudowana w niektóre aplikacje, których podstawą działania jest PowerShell.
  • Undefined - polityka nie zdefiniowana, czyli tak naprawdę przy domyślnym zakresie automatyczne ustawienie polityki na wartość Restricted.

PowerShell nie tylko pozwala na ustawienie poziomu zabezpieczeń, umożliwia on również na decydowanie jaki poziom ma być przypisany do odpowiedniego kontekstu wykonywania zadań. Konkretnie rozróżniamy tutaj 5 zakresów tejże polityki:

  • MachinePolicy - polisa nakładana poprzez GPO dla wszystkich użytkowników danej maszyny.
  • UserPolicy - polisa nakładana poprzez GPO dla obecnie zalogowanego użytkownika danej maszyny.
  • Process - polisa dotycząca obecnie używanej sesji Windows PowerShell.
  • CurrentUser - polisa dotycząca obecnie zalogowanego użytkownika.
  • LocalMachine - polisa egzekwowana w zakresie całej maszyny, tzn. dla wszystkich użytkowników. Jest to domyślny zakres stosowany przy nakładaniu polisy wykonywania skryptów.

W celu zarządzania stanem omawianej polisy możemy posłużyć się cmdletami zawierającymi końcówkę ExecutionPolicy.

Get-Command *ExecutionPolicy

 

Jak już wspominałem wcześniej o budowie cmdletów, do sprawdzania aktualnego stanu służy komenda Get-ExecutionPolicy, natomiast do modyfikowania jej - Set-ExecutionPolicy.

img2.jpg

Jaką ostatecznie polisę wybrać? Jest to pytanie, na które nie ma jednoznacznej odpowiedzi, a głównie zależy ona od typu wykonywanej pracy. Dla administratorów najlepiej jest by wykorzystywali polisę dość restrykcyjną, czyli Restricted lub AllSigned, natomiast dla programistów skryptów PowerShellowych polecałbym rozwiązanie na poziomie RemoteSigned bądź nawet Unrestricted.

Dla ciekawostki jeszcze wspomnę, iż skrypty ściągane z Internetu mają automatycznie ustawioną flagę, gdyż pochodzą z innego źródła niż komputer lokalny. Dlatego nawet w przypadku polisy RemoteSigned nie będzie możliwe wykonanie takich skryptów dopóki na przykład samodzielnie go nie podpiszemy własnym certyfikatem. Alternatywą jest własnoręczne odblokowanie takich plików na każdej maszynie, na którą je pobierzemy. Aby tego dokonać wystarczy zlokalizować plik skryptu, przejść do właściwości takiego pliku i użyć opcji Odblokuj. Tak zmodyfikowany plik będzie mógł być wykonywany przy w/w polisie, gdyż będzie traktowany jako skrypt lokalny.

Podpisywanie skryptów

Aby móc podpisać własny lub pobrany z sieci skrypt, musimy najpierw posiadać odpowiedni certyfikat pozwalający na jego podstawie dokonać tej operacji. Możemy taki certyfikat zakupić u zaufanego dostawcy, dzięki czemu nasze skrypty będą mogły być wykonywane z nałożoną polityką na poziomie AllSigned. Niemniej jednak wiąże się to z pewnymi kosztami oraz dodatkowo trzeba pamiętać, iż takie skrypty mają ograniczony czas ważności. Alternatywnym rozwiązaniem jest samodzielne wygenerowanie takiego certyfikatu. Co prawda nie będzie on zaufany, lecz pozwoli to na podpisywanie skryptów oraz wykonywanie ich na poziomie RemoteSigned.

Poniżej zaprezentuję jak własnoręcznie wygenerować taki certyfikat oraz jak podpisywać nasze skrypty. Jak w poprzednim przypadku całą wiedzę oprę o dokumentację PowerShella dostępną pod komendą:

Get-Help about_Signing

 

W celu wygenerowania własnego certyfikatu będzie potrzebna aplikacja Certificate Creation Tool, czyli MakeCert.exe dostępna w pakiecie Microsoft .NET Framework SDK lub  Microsoft Windows SDK.

Gdy posiadamy już gotowe środowisko możemy przystąpić do generowania certyfikatów. Do podpisywania certyfikatów potrzebne są nam dwa certyfikaty. Jeden certyfikat dla komputera, natomiast drugi, indywidualny certyfikat dla użytkownika.

Do wygenerowania certyfikatu komputera posługujemy się następującą składnią:

.\makecert.exe -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer  -ss Root -sr localMachine

 

Natomiast certyfikat użytkownika generujemy w ten sposób:

.\makecert.exe -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer

 

W obu przypadkach zostaniemy poproszeni o podanie hasła do zabezpieczenia klucza prywatnego, co pozwoli nam by nikt inny nie mógł podpisać skryptów naszym certyfikatem.

W celu sprawdzenia czy proces generowania naszego certyfikatu przebiegł pomyślnie, próbujemy wylistować obiekty z lokacji Certyfikaty dla osobistych certyfikatów bieżącego  użytkownika przy filtrowaniu certyfikatów mogących podpisywać kod źródłowy

Get-ChildItem Cert:\CurrentUser\my -codesigning

 

img3.jpg

Dla tak przygotowanego środowiska możemy przystąpić do podpisywania skryptu.

Stwórzmy sobie więc zmienną przechowującą nasz certyfikat.

$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

 

A następnie użyjmy polecenia Set-AuthenticodeSignature do podpisania konkretnego pliku .ps1.

Set-AuthenticodeSignature p:\hello.ps1 $cert

 

img4.jpg

Proces podpisywania przebiegł pomyślnie na co wskazuje zwrócony parametr Status = Valid. Po otwarciu pliku ze skryptem możemy zaobserwować dopisek będący  niczym innym jak publiczną częścią naszego certyfikatu.

Write-Host "Hello World"

# SIG # Begin signature block
# MIIEMwYJKoZIhvcNAQcCoIIEJDCCBCACAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU3+xIMlU26o3dy8FCiVtkIepB
# smugggI9MIICOTCCAaagAwIBAgIQ53FajQML7bBBXPFKm1WBVjAJBgUrDgMCHQUA
# MCwxKjAoBgNVBAMTIVBvd2VyU2hlbGwgTG9jYWwgQ2VydGlmaWNhdGUgUm9vdDAe
# Fw0xMTAzMTIxNjUwNDdaFw0zOTEyMzEyMzU5NTlaMBoxGDAWBgNVBAMTD1Bvd2Vy
# U2hlbGwgVXNlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp3+CMFOmww5X
# /gTt4Fg1MGMU2aIVw12mx9rbb28nY2LLUSPGrVns6r9VUJM7zaDxTLhi/kptY6pq
# o4hlDiYErpXGFPL+qqSc5AtMNy6vcEXwDcq6KKBM+I1r+x7bzuN+tlSO/WtA9V55
# HoNPH2tpycGRSCfv2VjRfDeMpAUQ/ocCAwEAAaN2MHQwEwYDVR0lBAwwCgYIKwYB
# BQUHAwMwXQYDVR0BBFYwVIAQIzrCjoAvEZWDCAkx9G7ueKEuMCwxKjAoBgNVBAMT
# IVBvd2VyU2hlbGwgTG9jYWwgQ2VydGlmaWNhdGUgUm9vdIIQ7xvxoBMiM4pJSq8a
# OzZNuTAJBgUrDgMCHQUAA4GBAJ8B5p0U379vIpNqsjyA6peiGU26cysGOx+UoQwm
# kcNH9XEpSvAlvNk66aBxo2l57OUE+IMocskn19K8P5inWn7avFAZhK2Y9Y1lx7n1
# T0U8J4FyCwUkxRHylg7EpDGbkjQ6I1pYnOhNypp3tE/lEC74n2FQW1xMQfa2lG/d
# 767xMYIBYDCCAVwCAQEwQDAsMSowKAYDVQQDEyFQb3dlclNoZWxsIExvY2FsIENl
# cnRpZmljYXRlIFJvb3QCEOdxWo0DC+2wQVzxSptVgVYwCQYFKw4DAhoFAKB4MBgG
# CisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcC
# AQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYE
# FAPgExjTbulcnhCiC8B2BIyHgHvGMA0GCSqGSIb3DQEBAQUABIGACAaC+6YNbFal
# qaC29TEQzUAigl+Y3EbWaa6DNEMZjfXoZoLpMMM6tFuLoaHlYYSu2aUnIszvnSD5
# 9Q+PA2kltHzjipbYkKu5+q4bGcyoLK4wsFIavK3F/dAHgT7kXURWEqt5za6Lfbik
# wpCt5V0RlVrenyYMgDV9OEDp117UMmM=
# SIG # End signature block

 

Częstym problemem jaki może wystąpić podczas podpisywania skryptów, jest kodowanie samego pliku ze skryptem. W szczególności problem ten objawia się gdy piszemy skrypty w natywnym narzędziu PowerShellowym, czyli Windows PowerShell ISE. By móc poprawnie podpisać plik ze skryptem powinien on być zapisany w kodowaniu UTF-8, natomiast w/w narzędzie domyślnie zapisuje pliki z kodowaniem UTF-16 BE, co niestety powoduje, iż podczas podpisywania zostaje zwrócony Status = UnknownError. By to skorygować wystarczy otworzyć skrypt w dowolnym narzędziu pozwalającym na zmianę kodowania i zapisać go w poprawnym formacie.

Liczba ocen: 6 | Średnia ocen: 5

Czytaj także

 

Skomentuj

Twój komentarz
Dodaj

Komentarze

Nasz Fanpage

Popularne treści

  • .NET  
  • 3D  
  • 8  
  • ActiveDirectory  
  • AJAX  
  • amazon web services  
  • Android  
  • Android Market  
  • AngularJS  
  • Animacja  
  • API  
  • aplikacje  
  • Aplikacje wielojęzyczne  
  • asembler  
  • ASHX  
  • ASP.NET  
  • ASP.NET MVC  
  • assembler  
  • Automated Installation Kit  
  • Azure  
  • bezpieczeństwo  
  • bing  
  • Blender  
  • C#  
  • certyfikat  
  • chmura  
  • cloud computing  
  • cmd  
  • Cmdlet  
  • Cmdlet’ów  
  • core  
  • CSS  
  • Cycles  
  • developer  
  • Entity Framework  
  • Expression Blend  
  • fitl  
  • google  
  • google app engine  
  • googlemaps  
  • GPU  
  • Grafika  
  • GroupPolicy  
  • hamachi  
  • hyperv  
  • hyper-v  
  • IaaS  
  • ImageX  
  • instalacja aplikacji  
  • interface  
  • interfejs  
  • Iron Speed  
  • java  
  • JavaScript  
  • jQuery  
  • Kinect  
  • Knockout  
  • kolokacja  
  • konsola  
  • LINQ  
  • LINQ to SQL  
  • Linux  
  • MakeCert  
  • maps  
  • microsoft  
  • mobile  
  • moduły  
  • MVC  
  • mySQL  
  • OpenSource  
  • openstreet  
  • openvpn  
  • PaaS  
  • partycja  
  • PHP  
  • pliki apk  
  • pon  
  • powershell  
  • preview  
  • programowanie  
  • przeglądarka  
  • przetwarzanie w chmurze  
  • przewodnik  
  • Qt  
  • RAD  
  • Rendering  
  • SaaS  
  • script  
  • SDK  
  • server  
  • serwer  
  • Skalowanie  
  • SQL  
  • Systemy operacyjne  
  • światłowody  
  • Światłowód  
  • Template  
  • ubuntu  
  • virtual  
  • Visual Studio  
  • vpn  
  • WAIK  
  • WCF  
  • WebAdministration  
  • WebApi  
  • Windows  
  • windows azure  
  • Windows PE  
  • Windows Phone  
  • WinFroms  
  • wirtualizacja  
  • WPF  
  • XAML  
  • zdalny  
  • zdjęcia  

VideoCasty

Komu polecasz tą stronę? (email)
Poleca (twoje imie/pseudonim)
Treść (opcjonalnie) Do Twojej treści zostanie dodany link polecanej strony
POLECAM