Unikanie sieci

https://chacker.pl/

Po ustanowieniu kanału C2 musimy być w stanie uniknąć wykrycia w sieci. Istnieją dwa obszary kontroli, których zazwyczaj musimy unikać. Pierwszy to IDS/IPS, a drugi to wykrywanie proxy. Większość organizacji nie odszyfrowuje danych TLS wewnętrznie, ale mogą odszyfrować dane TLS wychodzące poza organizację. Wiedząc o tym, mamy wiele obszarów, w których można zastosować szyfrowanie i unikanie zabezpieczeń.

 

Kompilowanie i testowanie launcherów Nim

https://chacker.pl/

W laboratorium Nim będziemy używać tej samej konfiguracji, co w poprzednich dwóch laboratoriach, z naszym modułem obsługi Metasploit Meterpreter nasłuchującym i budującym nasz kod na maszynie Kali. Aby skonfigurować nasze moduły dla naszego kodu Nim, musimy zainstalować moduł. Nimble jest menedżerem modułów Nimble, więc z naszego katalogu Shells instalujemy moduł winim za pomocą Nimble, w następujący sposób:

Pakiet winim zawiera moduły systemu Windows i definicje potrzebne do uruchomienia naszego kodu powłoki. Nie jest instalowany domyślnie, więc musimy go zainstalować. Następnie rzucimy okiem na nasz kod Nim w pliku nim.template w katalogu powłoki. Ten kod jest oparty na wielu przykładach OffensiveNim autorstwa Byt3bl33der. Wyeliminujemy wiele sprawdzania błędów i przesyłania wiadomości, aby zaoszczędzić miejsce:

Funkcja Patchntdll zastępuje funkcjonalność funkcji EtwEventWrite kodem powrotu, dzięki czemu nie wykona żadnego zawartego w niej kodu. Funkcja EtwEventWrite rejestruje zdarzenia Event Tracing for Windows (ETW), więc zapobiegnie zapisaniu żadnego z nich, ukrywając w ten sposób nasz kod przed jakąkolwiek instrumentacją, która go używa. Aby to zrobić, zaczynamy od uzyskania informacji o funkcji, dzięki czemu wiemy, co musimy nadpisać. Funkcja LoadLib (1) ładuje bibliotekę ntdll.dll do naszego kodu. Funkcja symAddr (2) pobiera adres funkcji EtwEventWrite. Funkcja VirtualProtect (3) ustawia lokalizację pamięci, którą nadpisujemy, na Odczyt/Zapis/Wykonanie, abyśmy mogli (4) zastosować nadpisane bajty do tej pamięci. Na koniec przywracamy pierwotny tryb ochrony do pamięci zapisanej w zmiennej origProtect za pomocą funkcji VirtualProtect (5) . Po wyłączeniu ETW musimy wstrzyknąć nasz kod powłoki. Aby to zrobić, użyjemy funkcji injectCreateRemoteThread do wstrzyknięcia naszego kodu powłoki w nowy proces:

Część tego kodu widzieliśmy już wcześniej, a wzór wygląda znajomo. W tym przykładzie uruchamiamy nowy proces (1) (w tym przypadku notepad.exe), w którym wstrzykniemy nasz kod. Musimy zawiesić proces, aby nie był widoczny i nie dawał użytkownikowi kontroli. Zamiast tego otworzymy nasz proces (2), abyśmy mogli nim manipulować i zapisać w nim nasz kod powłoki (3). Resetujemy (4) ustawienia ochrony pamięci, aby nie wyglądała dziwnie, a następnie tworzymy (5) wątek. Wątek będzie nadal działał, a nasz kod powłoki zostanie wykonany, podczas gdy normalna funkcjonalność procesu będzie nadal zawieszona i niewidoczna dla użytkownika. Na koniec musimy powiązać te informacje w jedną całość. Robimy to w odpowiedniku funkcji main dla Nim:

Oznacza to, że jeśli nie dołączymy tego kodu jako biblioteki, a jest to główny moduł projektu, to załata bibliotekę DLL, a następnie wstrzyknie kod powłoki. Możemy zbudować kod powłoki za pomocą polecenia build_nim.sh. Plik binarny /tmp/nim_dropper64.exe powinien teraz znajdować się w katalogu /tmp, a kiedy uruchomimy go w systemie Windows, nie powinniśmy zobaczyć żadnych wyników, ale powinniśmy zobaczyć powrót sesji w Metasploit:

Tworzenie wyrzutni Nim

https://chacker.pl/

Nim to kolejny skompilowany język, który obsługuje wiele systemów operacyjnych i wykorzystuje niektóre popularne części Pythona i innych języków, aby stworzyć bardziej przyjazny dla użytkownika język, który kompiluje się do C, C++, Objective-C i JavaScript. Dzięki temu kod można skompilować do jednego z języków pośrednich i włączyć do innych projektów, a także sam skompilować do formatu binarnego. Elastyczność Nim jest częścią jego popularności, podobnie jak fakt, że sygnatury plików binarnych będą na tyle różne, aby ominąć wiele tradycyjnych wykryć AV. Obecnie nie ma zbyt wielu repozytoriów korzystających z Nim, ale przyciągnęło to uwagę zarówno podmiotów zagrażających, jak i etycznych hakerów. Jedną z osób, która przeprowadziła świetne badania na temat ofensywnego Nima, jest Marcello Salvati, znany w Internecie jako Byt3bl33der. Jego repozytorium Offensive Nim pod adresem https://github.com/byt3bl33d3r/OffensiveNim zawiera próbki implementacji wielu technik uruchamiania i unikania kodu powłoki.

Kompilowanie i testowanie programów uruchamiających Go

https://chacker.pl/

Pliki binarne systemu Windows w Go można skompilować krzyżowo z Kali Linux przy użyciu pakietów mingw. Po zainstalowaniu pakietów golang i mingw wystarczy, że określimy architekturę i system operacyjny, a Go zajmie się za nas większością instrukcji kompilacji. W tym laboratorium będziemy nadal używać naszego detektora Meterpretera i będziemy używać plików build_go.sh i go.template w katalogu Shells. Kod Go w tym laboratorium wykorzystuje nieco inną technikę niż w poprzednim laboratorium. Zamiast wątków używamy światłowodu do uruchomienia naszego kodu. Włókno jest podobne do nici. Jest to strumień wykonania oddzielony od głównej części kodu. Jednak wątki są planowane przez aplikację. Dwa wątki nie muszą robić nic specjalnego, aby oba działały w tym samym czasie. Światłowody wymagają harmonogramu do obsługi wielozadaniowości. W rezultacie, kiedy uruchomimy nasze włókno, będzie ono działać aż do zakończenia działania lub do chwili, gdy nasz kod zrzeknie się kontroli nad resztą aplikacji. Ponieważ nasz kod powłoki nie wie, że znajduje się we włóknie, efektem końcowym jest to, że nasz kod będzie zawieszony do momentu zakończenia działania kodu powłoki. Kod Go będzie wyglądał podobnie do tego, co zrobiliśmy w C#, ponieważ używa również bibliotek Windows kernel32.dll i ntdll.dll. Kod ten jest modyfikowany na podstawie przykładów światłowodów ired.team, a także kodu z repozytorium Ne0nd0g wspomnianego wcześniej. W tym przykładzie będziemy kodować nasz kod powłoki w base64, co pozwala nam łatwo umieścić go w składni Go:

Tutaj używamy biblioteki base64 i dekodujemy ciąg znaków, który ustawiliśmy za pomocą naszego kodu powłoki, sc i zapisujemy go w zmiennej kodu powłoki. Jeśli zwrócone zostaną jakiekolwiek kody błędów, zostaną one zapisane w zmiennej err. Operator := służy do jednoczesnego tworzenia i przypisywania zmiennych, gdzie = służy do przypisania wartości już utworzonej zmiennej:

Aby wykonać nasz kod powłoki, musimy wykonać kilka kroków. Pierwszym krokiem jest przekształcenie naszej głównej nici w włókno. Robimy to za pomocą funkcji ConvertThreadToFiber (1) , która, jeśli zostanie określona bez opcji, pobiera bieżący wątek i konwertuje go na włókno. Musimy to zrobić, ponieważ tylko włókna mogą tworzyć dodatkowe włókna. Następnym krokiem jest przydzielenie pamięci dla naszego kodu powłoki za pomocą funkcji VirtualAlloc (2). Tutaj tworzymy pamięć jako Odczyt/Zapis/Wykonanie w jednym kroku. Może to być postrzegane jako szkodliwe dla niektórych produktów obronnych, dlatego zawsze możemy umożliwić zapis, kopiując kod powłoki, a następnie usuwając bity zapisu za pomocą programu VirtualProtect, aby wyglądało to mniej podejrzanie. Teraz, gdy mamy już pamięć, możemy skopiować do niej kod powłoki za pomocą wywołania RtlCopyMemory (3). Jedną z rzeczy, na które warto zwrócić uwagę w przypadku Go, jest to, że stara się chronić Cię przed niektórymi konwersjami typów, które mogą być niebezpieczne, więc użycie niebezpiecznej biblioteki ominie te zabezpieczenia. Następnym krokiem jest utworzenie nowego włókna do harmonogramowania za pomocą funkcji CreateFiber (4). Zauważ, że na potrzeby tego wywołania tworzymy nowe włókno wskazujące lokalizację pamięci naszego kodu powłoki, które zwraca adres nowego włókna. Mając ten adres możemy ustawić wykonanie na nowym włóknie za pomocą wywołania SwitchToFiber (5). Od tego momentu nasz kod będzie wykonywany aż do zakończenia światłowodu lub kodu z powrotem do głównego włókna. Teraz, gdy rozumiemy, co robi nasz kod, możemy uruchomić skrypt build_go.sh z katalogu powłoki w naszym hostowanym Kali. Spowoduje to utworzenie pliku /tmp/CreateFiber.exe, który możemy uruchomić z naszego okna Windows. Linia kompilacji samego pliku binarnego Go określa architekturę i system operacyjny w wierszu poleceń ze zmienną środowiskową, którą można ustawić w środowisku użytkownika lub w samym wierszu poleceń:

Teraz, gdy działa nasz słuchacz msfconsole, możemy uruchomić kod w systemie Windows:

W naszej sesji Linux Meterpreter powinniśmy teraz zobaczyć nową sesję, z którą możemy wchodzić w interakcję i używać jej do wykonywania poleceń:

Nasz plik binarny w systemie Windows będzie nadal wykonywany, dopóki nie wyjdziemy z sesji Meterpretera, a następnie powinien zakończyć się. Możesz sprawdzić dodatkowe przykłady w katalogu go-shellcode w swojej instancji Kali i możesz spróbować zmodyfikować inne przykłady, aby działały również w polu docelowym.

Tworzenie programów uruchamiających Go

https://chacker.pl/

Popularność Go rośnie ze względu na możliwości pracy na wielu platformach. Go można skompilować na mobilne i tradycyjne platformy komputerowe, w tym iOS, Linux, Windows, macOS, Solaris, a nawet z/OS. Ponieważ Go jest skompilowany, jest to dobry sposób na wprowadzenie programów uruchamiających, których tradycyjne podpisy mogą nie przechwycić. Go może używać wbudowanych bibliotek i konstrukcji systemu Windows i innych systemów operacyjnych do wykonywania kodu powłoki bez stosowania tradycyjnych wzorców, których mogą szukać wykrycia oparte na sygnaturach. Jednym z projektów GitHub, który ma dobre przykłady dla Windows, jest repozytorium go-shellcode Russela Van Tuyla (https://github.com/Ne0nd0g/goshellcode), które ma różne wzorce wykonywania napisane w Go. Są to dobre odniesienia do tworzenia własnego programu uruchamiającego Go, a także do przenoszenia tych wzorców na inne języki.

Kompilowanie i testowanie programów uruchamiających C#

https://chacker.pl/

Jednym z najbardziej podstawowych sposobów uruchomienia kodu powłoki jest umieszczenie go w wątku. Wątek to zestaw kodu, który działa równolegle z innym fragmentem kodu. Kiedy uruchamiamy kod w wątku, czy to w naszym bieżącym procesie, czy w innym procesie, główna część aplikacji nadal działa, podczas gdy nasz kod powłoki jest uruchamiany w tym samym czasie. W tym laboratorium będziemy nadal używać konfiguracji multi/handler Metasploit z poprzedniego laboratorium i dodamy kod powłoki do szablonu. W instancji Kali znajduje się podkatalog powłoki. Przeglądając ten katalog, widzimy dwa pliki, których będziemy używać w tym laboratorium: build_csharp.sh i csharp.template. Plik szablonu zawiera treść kodu z fragmentem umożliwiającym wstawienie naszego kodu powłoki. Skrypt build_csharp.sh zawiera polecenie msfvenom służące do utworzenia 64-bitowej powłoki odwrotnego protokołu TCP Meterpretera, która łączy się z naszym modułem obsługi, a następnie kompiluje powstały kod za pomocą kompilatora Mono C#, mcs. Powstałe dwa pliki to plik csharp.cs i plik csharp_dropper.exe w katalogu /tmp. Przyjrzyjmy się plikowi szablonu:

Nasz kod C# zaczyna się od (1) , gdzie tworzymy pamięć o rozmiarze naszego kodu powłoki. Ta pamięć jest pusta, więc w (2) kopiujemy do niej zawartość naszego kodu powłoki. Aby go wykonać, pamięć musi być oznaczona jako wykonywalna i VirtualProtect robi to (2) za nas. Stamtąd w (3) tworzymy wątek uruchamiający kod powłoki. Na koniec czekamy, aż kod powłoki zakończy się za pomocą polecenia WaitForSingleObject, a po jego zakończeniu program będzie mógł zakończyć działanie. Teraz, gdy przeanalizowaliśmy, co robi, zbudujmy go za pomocą następujących poleceń:

Kiedy uruchamiamy plik powłoki, na ekranie pojawiają się dane wyjściowe msfvenom, a wynikowy plik csharp_dropper64.exe znajduje się w katalogu /tmp. Możemy uzyskać do niego dostęp z okna Windows za pośrednictwem naszego udziału. Gdy Metasploit nadal działa i czeka na połączenia, uruchommy ten plik binarny:

W konsoli Metasploit na Kali powinniśmy zobaczyć naszą nową powłokę:

Aby sprawdzić, czy działamy jako nowy proces, możemy użyć polecenia getpid , aby uzyskać bieżący identyfikator procesu, a następnie użyj ps -S <nazwa procesu>, aby   sprawdzić, czy pasuje do naszego identyfikatora procesu:

Widzimy, że nasz kod działa w naszym launcherze C# i mamy możliwość uruchamiania poleceń w Metasploit. Może to być dowolny ładunek, jaki chcemy, taki jak ładunek Covenant lub inny typ ładunku C2.

Tworzenie programów uruchamiających C#

https://chacker.pl/

Domyślne programy uruchamiające z Metasploit i innymi narzędziami C2 są często wykrywane przez AV, wykrywanie i reagowanie na punkty końcowe (EDR) oraz inne narzędzia bezpieczeństwa. Aby temu zaradzić, wielu etycznych hakerów i przestępców używa programów uruchamiających kod powłoki, aby ukryć swój kod powłoki. Te programy uruchamiające mogą używać różnych technik do uruchamiania kodu powłoki, w tym wstrzykiwania do innych procesów, używania szyfrowania i wielu innych technik lub kombinacji technik, aby wyglądać na tyle inaczej, że kontrole bezpieczeństwa nie mogą być łatwo wykryte. W języku C# utworzono wiele wzorców uruchamiania kodu powłoki, w tym platformy takie jak SharpSploit, które można dołączyć jako biblioteki do innych narzędzi, które oferują wiele sposobów uruchamiania kodu powłoki, których można używać za pośrednictwem funkcji. Rozszerzalność i możliwość dołączania funkcji z zewnętrznych bibliotek DLL napisanych w C++ i innych językach ułatwiają korzystanie z funkcji wyższego poziomu języka C# w celu wykonania większości operacji w programie uruchamiającym podczas przełączania do funkcji C++ z systemowymi bibliotekami DLL w celu wykonywania określonych zadań .

Zaciemnianie ładunków za pomocą msfvenom

https://chacker.pl/

W tym laboratorium przyjrzymy się różnym metodom kodowania i zaciemniania, których można użyć z msfvenom do ukrycia ładunków. W pierwszym przykładzie przyjrzymy się użyciu kodowania do zmiany wyglądu samego ładunku. Aby to zrobić, użyjemy powszechnego kodowania „shikata_ga_nai”, co w języku japońskim z grubsza oznacza „nic nie da się z tym zrobić”. Na początek przyjrzyjmy się niektórym ciągom znaków będącym częścią Meterpretera z naszego początkowego pliku msf1.exe. Te ciągi znaków są częścią funkcji manipulacji tokenami i możemy użyć tej funkcji do śledzenia ukrywania Meterpretera dla przyszłych plików binarnych:

Widzimy nazwy funkcji do otwierania tokenów procesów i wątków oraz dostosowywania uprawnień. Następnie dodajmy trochę kodowania, aby zobaczyć, jak to wygląda:

Określamy dodatkowe opcje -e z typem naszego kodera i -i z liczbą iteracji, które chcemy uruchomić. Widzimy, jak koduje trzy razy i zapisuje plik binarny. Jeśli chcesz użyć innego kodera, kodery msfvenom -l pokażą Ci opcje. Zauważ, że każdy z nich jest poprzedzony platformą typu kodera, a tutaj generujemy pliki binarne x86. Kiedy ponownie uruchomimy naszą komendę strings, nie otrzymamy niczego w zamian, co pokazuje, że tekst w samym ładunku Meterpretera jest zaciemniony:

Dzieje się tak, ponieważ szablony tych plików binarnych są identyczne. Nie jest to optymalne, ponieważ rozmiar jest dobrym wskaźnikiem. Jedną rzeczą, którą możemy zrobić, to wybrać plik binarny systemu Windows, którego moglibyśmy użyć jako szablonu, który byłby inny. Kali ma już w systemie kilka plików binarnych Windows, więc użyjmy pliku binarnego wget.exe jako naszego szablonu:

Błąd wynika z tego, że msfvenom próbuje wstrzyknąć ładunek do sekcji .text pliku binarnego, a jeśli ta sekcja nie istnieje, mamy problem. Rzućmy okiem na sekcje znajdujące się w pliku binarnym dla wget.exe:

Błąd wynika z tego, że msfvenom próbuje wstrzyknąć ładunek do sekcji .text pliku binarnego, a jeśli ta sekcja nie istnieje, mamy problem. Rzućmy okiem na sekcje znajdujące się w pliku binarnym dla wget.exe:

ednym z efektów ubocznych tej techniki jest to, że wget w rzeczywistości nie będzie próbował robić rzeczy, które robiłby normalnie, więc ktoś może nabrać podejrzeń. Możemy użyć flagi -k, aby zachować funkcjonalność w pliku binarnym. Utwórzmy nowy plik binarny z flagą -k:

Działało to z typem exe, ponieważ wstrzykiwał nowy nagłówek sekcji do przechowywania kodu. Przyjrzyjmy się wynikom objdump:

OK, więc teraz, gdy mamy już kilka plików binarnych, uczyńmy je wykonywalnymi i uruchommy msfconsole, aby przechwycić nasze powłoki:

Do naszego polecenia dodaliśmy dwa nowe aspekty. Pierwszym z nich jest ustawienie wartości ExitonSession na false (1) . Typowym zachowaniem jest zaprzestanie słuchania, gdy tylko odzyskamy pierwszą skorupę. W naszym przypadku chcemy przechwycić wiele powłok, aby wypróbować każdy z naszych plików binarnych. Innym zachowaniem, które chcemy naprawić, jest natychmiastowe przejście do sesji po ponownym nawiązaniu połączenia przez powłokę. Aby to zrobić, podajemy opcję -j (2) w poleceniu exploita, aby poinformować Metasploit, że chcemy, aby działał w tle jako zadanie. Teraz, gdy otrzymamy powłoki, zobaczymy komunikat informujący o podłączeniu nowej powłoki, ale nie będziemy musieli od razu z nią wchodzić w interakcję. Wróćmy teraz do naszego okna Windows i uruchommy kilka naszych nowych powłok:

Do naszego polecenia dodaliśmy dwa nowe aspekty. Pierwszym z nich jest ustawienie wartości ExitonSession na false (1) . Typowym zachowaniem jest zaprzestanie słuchania, gdy tylko odzyskamy pierwszą skorupę. W naszym przypadku chcemy przechwycić wiele powłok, aby wypróbować każdy z naszych plików binarnych. Innym zachowaniem, które chcemy naprawić, jest natychmiastowe przejście do sesji po ponownym nawiązaniu połączenia przez powłokę. Aby to zrobić, podajemy opcję -j (2) w poleceniu exploita, aby poinformować Metasploit, że chcemy, aby działał w tle jako zadanie. Teraz, gdy otrzymamy powłoki, zobaczymy komunikat informujący o podłączeniu nowej powłoki, ale nie będziemy musieli od razu z nią wchodzić w interakcję. Wróćmy teraz do naszego okna Windows i uruchommy kilka naszych nowych powłok:

Użyliśmy polecenia session, aby wejść w interakcję z otwartą sesją 2 i w miejscu wpisania exit pojawia się znak zachęty Meterpretera. Wracając do systemu Windows, kontrola powróciła. W naszym systemie Windows spróbujmy uruchomić plik binarny msf4.exe, który używa wget.exe z flagą -k, aby zachować funkcjonalność:

Kiedy po raz pierwszy uruchamiamy plik binarny, wyświetla się komunikat o błędzie wskazujący na konieczność określenia adresu URL. Jest to typowa funkcjonalność wget, ale nie odzyskujemy powłoki, ponieważ plik binarny nigdy nie dotarł do naszego kodu powłoki. Kiedy ponownie spróbujemy użyć adresu URL, zobaczymy, że wget próbuje pobrać plik do naszego udziału SMB, ale nie może zapisać. Na naszej konsoli Metasploit powinniśmy zobaczyć coś takiego:

Sesja natychmiast umarła, ponieważ kiedy plik binarny się zakończył, zabiła także naszą powłokę. Moglibyśmy poprosić o naprawdę dużą stronę, co zajęłoby dużo czasu, ale mamy dodatkowe opcje. W opcjach zaawansowanych (które można wyświetlić dla dowolnego ładunku poprzez –list-options) znajduje się opcja PrependMigrate, która doda migrację do nowego procesu na początku kodu, dzięki czemu nasza powłoka będzie działać dłużej niż sam proces . Zbudujmy jeden z nich i wypróbujmy go:

W naszym systemie Windows po uruchomieniu msf5.exe powinniśmy zobaczyć takie same dane wyjściowe jak msf4.exe, ale w Metasploit widzimy coś innego:

Proces, w którym działa nasz kod powłoki, to nie msf5.exe, ale rundll32.exe. Nasz plik binarny uruchomił nowy proces i wstrzyknął go, pozostawiając sesję nieaktywną, mimo że plik msf5.exe został zakończony. Dzięki tym technikom możemy lepiej ukryć ładunki Metasploit w innych plikach binarnych za pomocą dodatkowego zaciemniania, aby zapobiec ich wykryciu przez silniki antywirusowe oparte na sygnaturach. Mamy jednak więcej opcji niż tylko szablony dla msfvenom. Przyjrzyjmy się alternatywnym strategiom.

msfvenom i zaciemnianie

https://chacker.pl/

Zastanawialiśmy się już nad użyciem msfvenom do zbudowania podstawowego ładunku, ale msfvenom ma mnóstwo różnych funkcji, które pomagają przekształcić ładunki wbudowane w narzędzie. msfvenom ma kodery, które pomogą zakodować ładunek przy użyciu różnych technik, aby uniknąć wykrycia opartego na sygnaturach AV. Istnieje również licznik iteracji, którego można użyć do wielokrotnego kodowania ładunku w celu utworzenia dodatkowych odmian oryginalnego ładunku.

Zaciemnianie ładunku

https://chacker.pl/

Jednym z największych wyzwań, przed którymi stoimy jako etyczni hakerzy, jest to, jak wyprzedzić powszechne kontrole. Wielu przestępców będzie korzystać z niestandardowych narzędzi, aby wyprzedzić te kontrole, ale często nie mamy czasu na tworzenie niestandardowego oprogramowania do różnych testów. Wielu dostawców oprogramowania antywirusowego (AV) szuka publicznie dostępnych narzędzi i tworzy dla nich metody wykrywania, dlatego ważne jest, aby znać wskazówki i triki umożliwiające zmianę ładunku na różne sposoby, abyśmy mogli korzystać z tych narzędzi bez natychmiastowego wykrycia.