Wprowadzenie
Kilka miesięcy temu dowiedzieliśmy się, iż jedna z dużych polskich organizacji padła ofiarą ataku malware, a atakujący jest aktywny w jej sieci. Podczas obsługi incydentu wspieraliśmy zarówno organy ścigania, jak i zaatakowaną organizację w dochodzeniu i usuwaniu skutków ataku.
Chociaż nasza analiza opiera się na danych zebranych w konkretnej firmie, kampanie typu Fake CAPTCHA mają charakter masowy i nie są wymierzone w konkretne organizacje. Incydent ten jest naszym zdaniem dobrym przykładem, pozwalającym pokazać pełny łańcuch ataku oraz to, w jaki sposób pojedynczy zainfekowany użytkownik może zagrozić bezpieczeństwu całej firmy. Dołączyliśmy również szczegółową analizę wykorzystanych próbek złośliwego oprogramowania.
Analiza złośliwego oprogramowania
Podczas analizy jednej ze stacji roboczych zidentyfikowaliśmy katalog
%APPDATA%\Intel, który zwrócił naszą uwagę. Znajdowały się w nim następujące pliki:
Podczas gdy pliki version.dll i igfxSDK.exe były standardowymi plikami systemu Windows, wtsapi32.dll wydał się nam podejrzany, ponieważ taka sytuacja jest charakterystyczna dla tzw. side-loadingu DLL.
Skan dysku wykrył także dwa dodatkowe podejrzane pliki w katalogu /Users/[username]/AppData/Local/:
Wektor infekcji
Najpierw spróbowaliśmy ustalić, w jaki sposób złośliwe oprogramowanie trafiło na stację roboczą ofiary. W logach zidentyfikowaliśmy następujące polecenie:
Fakt wpisania takiej komendy przez ofiarę wyraźnie wskazywał na atak Fake CAPTCHA (ClickFix). W tym ataku atakujący próbuje nakłonić ofiarę do skopiowania złośliwego fragmentu kodu i jego uruchomienia przy użyciu skrótu Win+R. Obserwujemy rosnącą liczbę ataków przeprowadzanych w ten sposób w Polsce.
Podczas poszukiwań tego adresu URL znaleźliśmy próbkę 6673794376681c48ce4981b42e9293eee010d60ef6b100a3866c0abd571ea648 w serwisie VirusTotal. Przeszukując logi pod kątem zdarzeń związanych z tym URL, udało nam się zidentyfikować kolejne złośliwe domeny. Jedna z tych domen była już wcześniej rozpoznana jako domena serwująca Fake CAPTCHA, ponieważ napotkaliśmy ją w przeszłości w innym incydencie. Udało nam się wyciągnąć z niej złośliwy kod:

W kodzie JavaScript osadzonym na tej stronie znaleźliśmy również token Telegrama:
Łatwo zauważyć, iż ten token nie jest prawidłowym tokenem Telegrama - jest zbyt krótki. W związku z tym kod nie mógł nigdy działać zgodnie z zamierzeniem. Możliwe, iż jest to wynik błędu, ale podejrzewamy, iż kod został wygenerowany przez LLM i nie został odpowiednio dostosowany.
Natrafiliśmy także na inne, podobne polecenie w logach:
Szukając podobnych indykatorów odkryliśmy więcej polskich domen zainfekowanych w ten sam sposób. Proaktywne polowanie na zagrożenia tego typu pozwala nam reagować szybciej na ataki.
Oprogramowanie Latrodectus
Po zakończeniu wstępnej analizy przeszliśmy do szczegółowej analizy złośliwego złośliwego oprogramowania, aby poszerzyć naszą wiedzę na temat incydentu i zdobyć dodatkowe wskaźniki IoC. Pierwszą analizowaną próbką była side-loadowana biblioteka DLL:
Uruchomiliśmy ją przy pomocy systemu DRAKVUF Sandbox i zaobserwowaliśmy żądania podobne do poniższych:
Podczas manualnej analizy ustaliliśmy, iż próbka była obfuskowana przy użyciu nieznanego nam obfuskatora. Ładując tę bibliotekę do debuggera i przechwytując odpowiednie wywołanie funkcji VirtualProtect, udało nam się uzyskać czysty zrzut pamięci. Zrzut ten pasował do reguły win_latrodectus_g0 autorstwa Slavo ze SWITCH (udostępnionej na zasadach TLP:GREEN w Malpedii).
Analizując dostępne materiały dotyczące tej rodziny, potwierdziliśmy, że próbka należy do rodziny złośliwego systemu Latrodectus. Warto zauważyć, iż wersja zaobserwowana w URL żądania to 2.3. Nie udało nam się znaleźć żadnych publicznych analiz Latrodectus w wersji 2, a tym bardziej konkretnie wersji 2.3. Niemniej jednak istnieje wiele wysokiej jakości analiz wersji 1, a różnice między wersjami nie są bardzo duże. Nie jest to jednak najnowsza wersja - znaleźliśmy próbki Latrodectus z wersją co najmniej v2.5.
Jedną z interesujących technik utrudniających analizę dynamiczną i stosowanych przez malware jest to, iż program odmawia wykonania kodu w przypadku uruchomienia za pomocą rundll.exe lub regsrv32.exe. Obecne były również inne typowe mechanizmy antydebugowe. Największym z wyzwań było odpinanie hooków na funkcje biblioteki NTDLL (NTDLL unhooking), polegające na samodzielnym odczytaniu pliku ntdll.dll z dysku i ręcznym zaimportowaniu go do procesu, co pozwala na ominięcie typowych mechanizmów wykrywania stosowanych przez AV i debugery. Obeszliśmy to zabezpieczenie wykonując kolejny zrzut pamięci po pełnym wypakowaniu kodu malware, a następnie automatyczne odzyskanie importów.
Na koniec, zaimplementowaliśmy skrypt do deszyfrowania stringów:
Klucz deszyfrujący wyciągnęliśmy manualnie, natomiast plik encrypted.txt zawierał zaszyfrowane ciągi znaków z binarki i został wygenerowany przy użyciu następującego skryptu ghidralib:
Korzystamy tutaj z faktu, iż referencje do zaszyfrowanych ciągów znaków znajdują się prawie zawsze bezpośrednio przed wywołaniem funkcji, dzięki czemu możemy emulować po kilka instrukcji poprzedzających opcode CALL i odczytać stan rejestru ECX.
Po odfiltrowaniu mniej istotnych wyników uzyskaliśmy następującą listę:
Wśród odzyskanych łańcuchów znaków na szczególną uwagę zasługują:
- Kallichore - nazwa grupy
- KK4Yp3894K6jOwLqbvOT035AwCpkKlxZeCzBLsKHt0k3j5yI0REck3FegyF6rcWq - klucz szyfrujący
- CLEARURL, URLS, COMMAND - polecenia C2
- wywołania cmd.exe, które mogą być wykorzystane jako IoC
Ostatnia istotna obserwacja, której dokonaliśmy wspomagając się wpisem na blogu VMRay, dotyczy faktu, iż parametr group w żądaniu HTTP (group=2201209746 w naszym przykładzie) jest hashem FNV-1a nazwy kampanii. Z samego żądania HTTP można więc odzyskać nazwę kampanii, przeprowadzając brute-force na zawartym w nim haszu.
Oprogramowanie Supper
Przeanalizowaliśmy również dwie dodatkowe podejrzane biblioteki DLL znalezione na maszynie. Pierwszą z nich był plik 245282244.dll:
Pierwsza próbka była spakowana tym samym packerem co Latrodectus. Wykonaliśmy manualnie dump pamięci w momencie pierwszego dostępu typu execute do dynamicznie utworzonej sekcji RWX. Pozwoliło nam to uzyskać czysty i łatwy w analizie zrzut pamięci.
Druga próbka była spakowana innym, nierozpoznanym typem packera, co utrudniło analizę i nie uzyskaliśmy czystego zrzutu pamięci. W momencie analizy próbka nie była dostępna w serwisie VirusTotal.
Główną funkcją w rozpakowanych bibliotekach DLL jest DllRegisterServer. Hardkodowane adresy IP serwerów to:
- 85.239.54.130:1080, 85.239.54.130:8080 - z pierwszej próbki, nieaktywne w czasie naszej analizy
- 162.19.199.110:4043 - z pierwszej próbki, aktywny w czasie naszej analizy
- 185.233.166.27:443 - z drugiej próbki
Pozwoliło nam to ustalić, iż złośliwe oprogramowanie należy do rodziny Supper.
Jako mechanizm persystencji próbka dodawała się jako zaplanowane zadanie (Scheduled Task) w systemie Windows:
Aby w pełni zrozumieć możliwości złośliwego oprogramowania, przeprowadziliśmy analizę jego komunikacji sieciowej. Złośliwe oprogramowanie wysyła do serwera C2 następującą wiadomość:
W odpowiedziach otrzymaliśmy wyłącznie komendę 1, podkomendę 0. W tym przypadku złośliwe oprogramowanie wykonuje następujące polecenie shellowe:
Po dwóch bajtach określających komendę znajduje się reszta payloadu:
Ten nagłówek jest "zaszyfrowany" przy użyciu jednobajtowego klucza XOR o wartości "M", natomiast dane są szyfrowane przy użyciu niestandardowego algorytmu przedstawionego poniżej:
Ponownie jedyną komendą, którą otrzymaliśmy była komenda numer 6. Polecenie to aktualizuje listę aktywnych serwerów C2. Aktualnie znane serwery C2 są zapisywane w katalogu %s/orl lub %s/s01bafg (w zależności od próbki). Inne obsługiwane polecenia to między innymi funkcja serwera proxy SOCKS oraz uruchamiania programów wysłanych z serwera C2.
Znajomość protokołu komunikacji pozwoliła nam zaimplementować skrypt automatycznie pobierający kolejne adresy IP C2 i uzyskać następującą listę adresów IP serwerów C2:
- 162.19.199.110: port 4043
- 146.19.49.130: port 8080
- 185.233.166.27: port 443
- 85.239.54.130: nieaktywny
- 171.130.169.141: nieaktywny
- 130.49.19.146: błędny
- 110.199.19.162: błędny
- 27.166.233.185: błędny
Adresy IP oznaczone jako "błędne" stanowią lustrzane odbicie rzeczywistych adresów IP C2 (na przykład 4.3.2.1 zamiast 1.2.3.4). Podejrzewamy, iż operatorzy nie byli pewni jaka kolejność bajtów jest poprawna i zdecydowali się na wszelki wypadek przesłać obie wersje (adres IP jest wysyłany przez serwer jako DWORD).
Poniższy skrypt został użyty do deszyfrowania komunikacji C2:
Poniższa reguła Yara może zostać wykorzystana, aby znaleźć rozpakowane próbki systemu Supper.
Podsumowanie
Chociaż początkowy wektor infekcji jest stosunkowo prosty, ataki typu Fake CAPTCHA stanowią duże ryzyko, dając atakującemu możliwość wykonania dowolnego kodu w kontekście użytkownika.
Mamy nadzieję, iż nasz wpis na blogu zwiększy świadomość tego typu zagrożenia i podkreśli znaczenie edukacji pracowników oraz monitorowania nietypowych zdarzeń w firmie.















