Badając różne metody eksfiltracji danych, natknęliśmy się na pewien ciekawy proof of concept, który postanowiliśmy przetestować i opisać w dzisiejszym artykule. Tym razem skupiliśmy się na możliwości przesłania ładunku (shellcode) za pomocą protokołu ICMP i zaimplementowanej w systemach funkcji ping.
Na temat eksfiltracji danych przy użyciu różnych metod i protokołów pisaliśmy już wcześniej w kilku artykułach tutaj. Ostatnim jaki opisaliśmy było użycie protokołu Finger do wykradania i pobierania danych z Internetu.
Czas opisać kolejny atak z użyciem ICMP.
Możliwości ICMP do przeprowadzania ataku
Jeśli nie czytaliście naszego poprzedniego artykułu o ataku ICMP, to gorąco polecamy. Opisaliśmy w nim sam protokół ICMP i pokazaliśmy tunelowanie.
Specjalnej uwagi wymaga fakt, że w ICMP można dostarczyć bufor, który może pomieścić aż 65 500 bajtów! Mając tak duży limit, możemy łatwo przemycić kod powłoki (shellcode) do naszego żądania ICMP, a następnie wstrzyknąć go do procesu po stronie słuchacza (ang. listener), czyli inaczej komputera, na którym jest uruchomiony program kliencki.
W kontekście ataku i eksfiltracji danych z sieci powyższa informacja oznacza, że odpowiednio przygotowane złośliwe oprogramowania na komputerze klienckim może załadować (przygotować) pakiety ICMP z zawartością pliku lub dane i przekazać je dalej w postaci pakietów żądań ICMP do miejsca docelowego. Miejsce docelowe to na ogół program nasłuchujący (serwer nasłuchujący C2), który odczytuje i rozpakowuje pakiety ICMP. Inną metodą może być przechwytywanie pakietów, takie jak TCPDUMP – nasłuchiwanie pakietów ICMP z adresu IP inicjującego klienta.
Zaczynając od dostarczania ładunku (shellcode), wymagana jest tylko kompilacja lokalnie kodu w C# w programie Visual Studio lub przy użyciu wbudowanego w Windows programu „csc.exe”. Musimy pamiętać o zaimportowaniu zależności. Jedyny potrzebny pakiet to „System.Net.NetworkInformation”.
Poniżej prezentujemy kod klienta i serwera C2, który należy skompilować i uruchomić w celu umożliwienia komunikacji i przesłania shellcode.
Kod serwera ICMP
Kod serwera to nic innego jak funkcja sendShellcode, przesyłająca shellcode określany w zmiennej „buf” do adresu IP podanego w wywołaniu funkcji Send. TTL ustawiony jest na 64 a timeout na 1000. To pozwoli nam przesłać w interwałach czasowych przez ping kod do drugiego hosta.
Kod klienta ICMP
Kod klienta jest nieco dłuższy niż serwera, ponieważ po jego stronie leży przetwarzanie i uruchomienie schellcode. Implementuje dwie funkcje. Jedna do pobierania kodu (getShellCode) druga do jego uruchomnienia (shellCodeInjection). Klient wykorzystuje także zewnętrzne klasy biblioteki Windows „kernel32.dll”: OpenProcess, VirtualAllocEx, WriteProcessMemory oraz CreateRemoteThread.
Cała komunikacja odbywa się po Socket.
Scenariusz przesłania shellcode po ICMP
W naszym scenariuszu będziemy chcieli przesłać za pomocą ICMP kod z serwera C2 o adresie IP: 172.16.215.100 do klienta o adresie IP:172.16.215.3 ładunek (shellcode) pozwalający uruchomić na nim kalkulator Windows. W tym celu musimy wykonać następujące kroki.
Krok 1. Przygotowanie ładunku i kompilacja kodu serwera c2
Zanim skomplikujemy kod serwera najpierw wygenerujemy ładunek (shellcode). Wykorzystamy do tego serwer Kali i narzędzie metasploit. Za pomocą przełącznika „-f csharp” wygenerujemy shellcode dla C#, który posłuży nam jako kod do pliku źródłowego.
Zaznaczoną na biało sekcję kodu shellcode należy przekopiować do pliku serwera „shellcodeInjector.cs”. Należy tez zmienić adres IP wskazując na adres IP klienta Windows 10.
Krok 2. Kompilacja i uruchomienie kodu na kliencie (komputerze ofiary)
Kopiujemy na maszynę kliencką Windows 10 plik „pingInjection.cs”. Musimy w nim zmienić dwie wartości:
– adres IP lokalnej maszyny, w funkcji getShellCode() w wywołaniu Bind. Bind wykonywany jest do lokalnego adresu IP z portem o wartości 0.
– Numer pid procesu programu Windows, pod który chcemy wstrzyknąć shellcode. Wartość parametru „notepadIPID”.
Kompilację kodu uzyskamy poprzez poniższą komendę.
Podobnie musimy zrobić z kodem na kliencie Windows 10 z plikiem „pingInjection.cs”.
Po udanej kompilacji i uruchomieniu obu programów na kliencie Windows 10 oraz na serwerze C2 powinniśmy zobaczyć uruchomione okno kalkulatora Windows: