ethical.blue Magazine

// Cybersecurity clarified.

Wstęp do PowerShell dla użytkowników systemu Microsoft Windows

...
Windows // // Dawid Farbaniec
Ostatnia modyfikacja:

Spis treści

Podstawowe informacje

Powłoka systemowa (ang. shell) pełni rolę pośrednika pomiędzy użytkownikiem, a systemem operacyjnym i programami. Może mieć postać tekstową i przyjmować polecenia np. Wiersz polecenia (%SystemRoot%\System32\cmd.exe), Windows PowerShell (%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe) lub formę graficzną jak np. Eksplorator Windows (%SystemRoot%\explorer.exe).

...
Przykładowe powłoki systemowe w Microsoft Windows (Wiersz polecenia, Windows PowerShell oraz Eksplorator)

Innym przykładem przekazywania poleceń do systemu operacyjnego przez powłokę jest Terminal GNOME w systemie Ubuntu Desktop z rodziny Linux.

...
Terminal w systemie Ubuntu Desktop z rodziny Linux

Powłoka PowerShell dla Windows, Linux i macOS

Powłoka Windows PowerShell jest wbudowana w system Windows, ale istnieje też osobne, wieloplatformowe rozwiązanie, które jest nazywane po prostu PowerShell. PowerShell bardzo się różni od zwykłego Wiersza polecenia (cmd.exe), ponieważ jest oparty o środowisko wykonawcze .NET, a polecenia to nie są zwykłe pliki wykonywalne tylko skrypty stworzone w PowerShell lub innym języku zgodnym z .NET. Warto też zaznaczyć, że polecenia PowerShell (ang. cmdlet) wykonują operacje na obiektach platformy .NET, a nie zwykłym tekście.

Instalacja PowerShell w systemach Windows i Linux

W celu rozpoczęcia eksperymentów należy zainstalować PowerShell w wersji odpowiedniej dla swojego systemu.

Jeśli korzystamy z systemu Ubuntu z rodziny Linux można użyć polecenia:

sudo snap install PowerShell --classic

Po instalacji zakończonej sukcesem w celu uruchomienia PowerShell należy wpisać pwsh.

...
Instalacja PowerShell w systemie Linux (Ubuntu Desktop)

W przypadku systemu Windows w celu instalacji PowerShell można użyć wbudowanego Windows PowerShell, wpisać polecenie winget search Microsoft.PowerShell, aby odnaleźć dostępne wersje, a następnie użyć polecenia winget install --id Microsoft.PowerShell --source winget w celu rozpoczęcia instalacji.

...
Instalacja PowerShell w systemie Windows (za pomocą Windows PowerShell)

Format polecenia (ang. cmdlet) w PowerShell

Polecenia PowerShell nazywane są po ang. command-let, w skrócie cmdlet. Znajdują się w modułach i mogą być tworzone w języku skryptowym PowerShell lub innym języku zgodnym z .NET. Istnieją też funkcje oraz aliasy, czyli inne nazwy dla istniejących poleceń. Format polecenia to Verb-Noun, czyli Czasownik-Rzeczownik. Niech przykładem będzie Get-Command za pomocą którego można przeglądać zainstalowane na urządzeniu polecenia. W celu znalezienia poleceń z określonym czasownikiem można użyć parametru -Verb. Natomiast w przypadku określania rzeczownika stosuje się parametr -Noun, czyli Get-Command -Noun 'Host' odnajdzie polecenia z rzeczownikiem Host.

...
Przykład wyszukiwania zainstalowanych poleceń po rzeczowniku za pomocą Get-Command
...
Przykład wyszukiwania zainstalowanych poleceń po rzeczowniku i czasowniku za pomocą Get-Command

W celu uzyskania pomocy na temat określonego polecenia można użyć Get-Help podając dalej nazwę szukanego polecenia (tutaj przykład dla Write-Host) oraz parametr -Online.

...
Przykład uzyskiwania pomocy dla polecenia Write-Host korzystając z Get-Help

Operacje na ciągach tekstowych

Za pomocą operatorów -is oraz -isnot można sprawdzić jakiego typu jest obiekt. Należy zaznaczyć, że wszystkie typy w .NET dziedziczą po object, czyli liczba całkowita też jest obiektem, co można zweryfikować za pomocą polecenia:

PS C:\> 4 -is [object]
True
PS C:\>

Idąc dalej można zauważyć, że liczba całkowita nie jest ciągiem znaków (napisem).

PS C:\> 4 -is [string]
False
PS C:\> 4 -is [int]
True
PS C:\> 4 -isnot [int]
False

Napisy są umieszczane w cudzysłowie lub otoczone apostrofami. Dlatego ta sama liczba poniżej jest już traktowana jako ciąg znaków (napis).

PS C:\> "4" -is [string]
True
PS C:\> '4' -is [string]
True

Pojedynczy znak domyślnie jest typu string, ale nic nie stoi na przeszkodzie, aby wykonać konwersję typu ze string na char. Zmiana typu przez rzutowanie może zostać wykonana umieszczając nazwę typu w nawiasach prostokątnych przed wartością.

PS C:\> '4' -is [char]
False
PS C:\> [char]'4' -is [char]
True

Ciąg znaków np. "ethical.blue" jest obiektem typu string, czyli za pomocą kropki można uzyskać dostęp do jego właściwości. W ten sposób można np. odczytać długość (ang. length) tego napisu.

PS C:\> "ethical.blue".Length;
12

Wartości mogą być wplatane w napisy. Poniżej do zmiennej $magazine przypisano wartość "Magazine" (ciąg znaków), aby później wartość ta została wpleciona w napis "ethical.blue $magazine". Powoduje to, że polecenie Write-Host wyświetla na konsolę tekstową ciąg ethical.blue Magazine.

PS C:\> $magazine = "Magazine"; Write-Host "ethical.blue $magazine";
ethical.blue Magazine
PS C:\>

...
Przykład dla ciągów znakowych (napisów) w PowerShell

Poniżej zaprezentowano bardziej zaawansowany przykład. Celem ćwiczenia jest przejście za pomocą pętli przez znaki w napisie i wyświetlenie na konsoli tekstowej każdego znaku oraz kodów ASCII znaków w systemach dziesiętnym oraz szesnastkowym (heksadecymalnym).

A oto wspomniany fragment:

[char[]]"abc" | % { [string]::Format("$_ | 0x{0:X8} | {0}", [int]$_); }

Pora rozłożyć to na czynniki pierwsze. Idąc od lewej. Napis abc jest rzutowany na typ tablicy znaków char[]. Znak pionowej kreski oznacza tutaj potok, czyli kolekcja znaków jest przekazywana do pętli (% to alias dla ForEach-Object) przechodzącej po obiektach przekazanych potokiem. Do każdego obiektu (znaku) w pętli można się odwołać za pomocą $_. Typ [string] posiada statyczną metodę Format do której można się dostać znakami ::. Ciąg formatujący wyświetla znak ($_), kod ASCII w postaci szesnastkowej z przedrostkiem 0x dopełniony zerami do ośmiu pozycji ({0:X8}, parametr o indeksie zero, format szesnastkowy, osiem zer wiodących) oraz kod ASCII w postaci liczby dziesiętnie ({0} oznacza parametr o indeksie zero). Parametrem metody [string]::Format jest obiekt przetwarzany w pętli ($_) rzutowany na wartość typu liczba całkowita (int).

...
Przykładowa, bardziej złożona operacja na ciągu znaków z użyciem PowerShell

Odczytywanie podstawowych informacji o urządzeniu

Informacje zawarte w CIM można odczytać poleceniem Get-CimInstance.

Dalej zaprezentowano przykładowe fragmenty kodu pozwalające uzyskać informacje o urządzeniu i systemie.

<# Informacje o systemie BIOS #>
Get-CimInstance -ClassName CIM_BIOSElement

<# Informacje o procesorze #>
Get-CimInstance -ClassName CIM_Processor

<# Informacje o karcie graficznej #>
Get-CimInstance -ClassName CIM_VideoController

<# Informacje o karcie sieciowej #>
Get-CimInstance -ClassName CIM_NetworkAdapter

<# Informacje o kontach użytkowników #>
Get-CimInstance -ClassName Win32_SystemUsers

Można też użyć bardziej ogólne polecenie jak np. Get-ComputerInfo

Przegląd podstawowych elementów składniowych PowerShell

Komentarze

W skryptach i poleceniach PowerShell można umieszczać komentarze, które mają cel informacyjny i są pomijane przy wykonywaniu skryptu. Komentarz jednoliniowy rozpoczyna się znakiem kratki # i kończy wraz z linią. Natomiast komentarz wieloliniowy rozpoczyna się znakami <# i kończy znakami #>.

Zmienne

W celu utworzenia zmiennej o określonej nazwie i nadania jej wartości należy użyć znaku dolara. Na przykład $ethicalblue = 3; tworzy zmienną o nazwie ethicalblue i wartości trzy typu liczba całkowita. Jeśli zmienna ma skomplikowaną nazwę, to można użyć nawiasów klamrowych. Na przykład ${ethical.blue Magazine} = 'ethical.blue'; tworzy zmienną o podanej nazwie, która zawiera ciąg znaków ethical.blue.

Nic nie stoi na przeszkodzie, aby utworzyć tablicę obiektów np. $a = 4,3,'a',1,512 (pięć elementów). Można też stworzyć kolekcję np. $c = @{ x = 'ethical'; y = 'blue' } (kolekcja zawiera dwa elementy, takie jak x i y).

Obiekt może przyjąć wartość $null, która oznacza, że nie przypisano żadnej wartości.

Zmienne i ich wartości można wyświetlić poleceniem Get-Variable.

...
Przykładowe zmienne w PowerShell i polecenie Get-Variable

Inny przykład. Można stworzyć kolekcję $c = @{ x = 'ethical'; y = 'blue' } oraz zmienną $text, aby zaprezentować sklejanie napisów. Tworzony napis to element x kolekcji $c do którego wartości doklejana jest kropka ('.') oraz wartość elementu y kolekcji $c i tekst Magazine. W ten sposób w zmiennej $text powstaje napis ethical.blue Magazine. Zawartość zmiennej można wyświetlić np. poleceniem Write-Host.

Utworzone zmienne i ich wartości można wyszukiwać poleceniem Get-Variable. Wpisując Get-Variable t* na konsoli tekstowej wyświetlają się zmienne z nazwą rozpoczynającą się literą t.

Zawartość zmiennej można wyczyścić poleceniem Clear-Variable podając jako parametr jej nazwę.

...
Przykładowe zmienne w PowerShell i polecenia Get-Variable oraz Clear-Variable

ForEach-Object

Polecenie ForEach-Object, którego alias to %, pozwala iterować po obiektach kolekcji, które można przekazać np. przez potok (|). Przykład poniżej przekazuje kolekcję dwóch napisów przez potok do polecenia ForEach-Object wyświetlając każdy element za pomocą znaków $_.

'ethical.blue', 'Magazine' | % { $_; }

...
Przykład. Przekazanie kolekcji przez potok do polecenia ForEach-Object

Jednostki informacji pamięci komputerowej

Przykład poniżej prezentuje jak za pomocą PowerShell można przeliczać jednostki informacji pamięci komputerowej takie jak bajty, kilobajty, megabajty, gigabajty, terabajty i petabajty. Użycie tej składni jest bardzo proste np. wpisując 3KB zwrócona zostanie liczba bajtów odpowiadająca trzem kilobajtom.

...
Przeliczanie jednostek takich jak bajty, kilobajty, megabajty, gigabajty, terabajty i petabajty za pomocą PowerShell

Napisy wieloliniowe

Za pomocą znaków @''@ oraz @""@ można tworzyć w skryptach napisy wieloliniowe.

...
Napisy wieloliniowe w PowerShell

Znak ucieczki w PowerShell (ang. backtick)

W celu wplatania wartości zmiennych do napisów można zastosować znaki cudzysłowu "". Przykład poniżej prezentuje jak nazwa zmiennej w napisie jest zamieniana na jej wartość. Warto dodać, że zastosowanie apostrofów powoduje, że zmienne nie są zamieniane na ich wartości. Można też zastosować sekwencję ucieczki (znak backtick, `) w napisie, aby nazwa zmiennej nie była zamieniana na wartość.

...
Znak ucieczki w PowerShell (ang. backtick)

Podstawowe operatory

Operatory logiczne takie jak koniunkcja, alternatywa, alternatywa wykluczająca i negacja to odpowiednio -and, -or, -xor i -not. Poniżej przedstawiono tablice prawdy dla poszczególnych operatorów.

Koniunkcja (-and) w PowerShell
$a $b $a -and $b
$false $false $false
$false $true $false
$true $false $false
$true $true $true
Alternatywa (-or) w PowerShell
$a $b $a -or $b
$false $false $false
$false $true $true
$true $false $true
$true $true $true
Alternatywa wykluczająca (-xor) w PowerShell
$a $b $a -xor $b
$false $false $false
$false $true $true
$true $false $true
$true $true $false
Zaprzeczenie (-not, !)
$a -not $a
$false $true
$true $false

Podstawowe operatory bardzo często spotykane w skryptach PowerShell to m.in.:

...
Przykładowe wywołania wybranych operatorów dostępnych w PowerShell
...
Podstawowe operatory do działań na bitach w PowerShell

Przykładowe polecenia

Poniżej przedstawiono przykładowe polecenia PowerShell.

Polityka wykonywania skryptów

Nieuregulowane pozwolenie na wykonywanie skryptów może być zagrożeniem dla urządzenia, ponieważ ułatwia uruchomienie złośliwego kodu. Informacje na temat bieżących ustawień można uzyskać poleceniem Get-ExecutionPolicy.

...
Przykład dla polecenia Get-ExecutionPolicy w PowerShell
AllSigned
Bypass
Default
RemoteSigned
Restricted
Undefined
Unrestricted

Politykę wykonywania skryptów można zmienić poleceniem Set-ExecutionPolicy.

...
Przykład dla polecenia Set-ExecutionPolicy w PowerShell

Format-Hex

Za pomocą polecenia Format-Hex można w łatwy sposób wyświetlać obiekty w postaci heksadecymalnej.

Przykład poniżej przedstawia przekazanie potokiem ciągu znaków do polecenia Format-Hex.

"ethical.blue Magazine" | Format-Hex

...
Przekazanie potokiem danych do polecenia Format-Hex w PowerShell

Polecenie Format-Hex znajduje też często zastosowanie przy odczytywaniu fragmentów plików, aby sprawdzić np. określone właściwości, zawartość czy rozpoznać typ przechowywanych danych (format pliku).

Format-Hex -Path .\ethicalblue.LNK -Offset 0x7D1 -Count 7

...
Odczytanie fragmentu pliku pod określonym przesunięciem (ang. offset) w PowerShell

Get-FileHash

W celu weryfikacji integralności danych można użyć polecenia Get-FileHash, które zwróci wynik funkcji skrótu (ang. hash). Polecenie jest też przydatne podczas identyfikacji próbek złośliwego oprogramowania (ang. malware).

Przykładowe wywołanie przedstawione poniżej oblicza funkcję skrótu SHA512 z pliku o nazwie ethicalblue.lnk z bieżącego katalogu (.\).

(Get-FileHash .\ethicalblue.LNK -Algorithm SHA512).Hash;

...
Obliczanie funkcji skrótu (ang. hash) z określonego pliku w PowerShell

Get-Uptime

Za pomocą polecenia Get-Uptime można otrzymać obiekt typu TimeSpan, który reprezentuje przedział czasu od ostatniego uruchomienia urządzenia.

...
Wyświetlenie za pomocą PowerShell czasu od ostatniego uruchomienia urządzenia (tutaj ponad pięć godzin)

Test-Connection

Polecenie Test-Connection pozwala w łatwy sposób zweryfikować możliwość połączenia się z określoną maszyną podając adres sieciowy.

...
Prosta weryfikacja możliwości połączenia się z określoną maszyną (podając adres sieciowy)

Get-HotFix

Za pomocą polecenia Get-HotFix można zweryfikować czy lokalne lub zdalne maszyny mają zainstalowane najnowsze poprawki bezpieczeństwa.

...
Prosta weryfikacja zainstalowanych poprawek bezpieczeństwa za pomocą PowerShell

Wykaz literatury

  1. [1] https://learn.microsoft.com/en-us/powershell/scripting/overview [dostęp: 2025-01-15]
  2. [2] Windows PowerShell Language Specification Version 3.0 by Microsoft