Nie wszystkie kampanie złośliwego oprogramowania nastawione są na masowego klienta. Te przeznaczone dla wąskiego grona odbiorców są także ciekawe. Poniżej znajdziecie analizę kampanii prowadzonej na polskich grupach Facebooka.
Kilka dni temu do cyberlaboratorium naszego siostrzanego serwisu BadCyberLab trafił przypadek złośliwego oprogramowania, które rozsyłane było w dość niecodzienny sposób. W artykule znajdziecie opis jego sposobu dystrybucji oraz wskazówki, w jaki sposób samodzielnie można przeprowadzić analizę użytego w kampanii packera/dropppera.
Praca szuka filmowca
Od jednego z naszych kontaktów otrzymaliśmy informację o trwającej kampanii złośliwego oprogramowania. Wyglądała ona tak:
Post pojawił się facebookowej zamkniętej grupie „samopomoc filmowa”. Post był całkiem solidnie przygotowany. Przede wszystkim autor posługiwał się właściwą dla środowiska filmowców terminologią (operatorka, storyboard). Oferta była także atrakcyjna z komercyjnego punktu widzenia – choć bez przesady – ot, dobry interes ale nie wzbudzający podejrzeń przesadnie wysoką stawką. Co ważne, mogła faktycznie wzbudzić zainteresowanie – posiadanie przez zlecającego scenorysu sugerowało poważny projekt. Nic dziwnego, ze spotkała się z zainteresowaniem uczestników grupy.
Jak widać w ciągu kilku minut co najmniej kilka osób zgłosiło się po szczegóły – a liczba ta może być większa biorąc pod uwagę, że nie każdy musiał o tym powiadamiać całą grupę. Osoby, które skontaktowały się z twórca wiadomości, dostawały linka do pliku w serwisie WeTransfer (link jest obecnie nieaktywny). Link prowadził do pliku o nazwie „Storyboard i scenariusz – Exeme.exe”. Zwróćcie uwagę na nazwę – pojawia się w niej słowo „Exeme”, które zapewne ma być rzekomym tytułem projektu, jednocześnie zmniejszając szanse, że ofiara zwróci uwagę na problem z rozszerzeniem EXE. Skąd taka teoria? Ten sam plik był także rozsyłany pod nazwą „Materialy graficzne – Exetrans.exe” choć w tym wypadku nie udało się nam namierzyć posta do niego prowadzącego.
Samo konto „Grzegorz Trentkiewicz” nie prowadzi zbyt daleko. Osoba o tej tożsamości istnieje, lecz najwyraźniej nie ma z atakiem nic wspólnego oprócz tego, ze ktoś wykorzystał jej personalia. Konto zapisane jest do wielu grup regionalnych:
W żadnej z nich nie udało się nam jednak znaleźć wpisów tego użytkownika – może Wy będziecie mieli więcej szczęścia. W dalszej analizie zobaczycie, że nazwisko Trentkiewicz jeszcze się przewinie.
I Ty możesz analizować złośliwe oprogramowanie!
Niedługo po tym jak do naszego cyberlaboratorium trafiła próbka złośliwego oprogramowania odkryliśmy, że jest to narzędzie do zdalnego zarządzania komputerem (RAT) o nazwie LuminosityLink, który opisywaliśmy przy okazji innej kampanii. Oznacza to, że jedyną ciekawą częścią tego opracowania może być analiza tego, jak RAT został spakowany. Autor kampanii użył do tego celu bardzo prostych i przystępnych dla analityka narzędzi. Dlatego właśnie tym razem cyberlaboratorium podjęło odważną decyzję nauczenia Ciebie (tak, Ciebie!) analizy złośliwego oprogramowania. Ta akurat próbka jest jedną z mniej zaawansowanych, ale, niczym ogry, ma warstwy. Zaczniemy od analizy statycznej, a następnie postaramy się potwierdzić jej wyniki za pomocą analizy dynamicznej. Na koniec postaramy się wyciągnąć wnioski, które pozwolą zidentyfikować i usunąć infekcję z naszego komputera. Zacznijmy od pobrania próbki z serwisu malwr.com. Zakładam, że analizujemy próbkę na systemie z rodziny Linux (np. Ubuntu), ale nie jest to konieczne do wykonania większości poleceń. Po wykonaniu na pobranej próbce polecenia file otrzymujemy następujący wynik:
PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
To oznacza, że złośliwe oprogramowanie jest napisane w języku .NET i mamy do czynienia ze skompilowanym kodem pośrednim (tzw. bajtcodem) tego języka. Pozwala nam to na otwarcie próbki za pomocą oprogramowania o nazwie dotPeek, które zdekompiluje próbkę do (prawie) czytelnego kodu. Uwaga! Zanim zaczniemy jakąkolwiek analizę zainstalujmy sobie oprogramowanie do obsługi maszyn wirtualnych, jak np. VirtualBox, który w przypadku tej analizy zupełnie wystarczy, a ma dosyć przyjemny interfejs użytkownika. Po instalacji VirtualBox pobieramy i importujemy maszynę wirtualną Windows korzystając np. z serwisu modern.ie. Całą dalszą analizę (łącznie z uruchomieniem dotPeek) wykonujemy tyko na maszynie wirtualnej. W ten sposób ustrzeżemy swoją maszynę przed infekcją tym rodzajem złośliwego oprogramowania.
Po uruchomieniu dotPeek i otwarciu próbki zobaczymy po lewej stronie nowy wpis o nazwie „grafikaa”. To właśnie jest wewnętrzna nazwa złośliwego oprogramowania. Otwórzmy klasę, której nazwa rozpoczyna się od „xhhe…”, klikając na niej dwukrotnie. Powinniśmy teraz mieć sytuację w programie podobną do tej przedstawionej na poniższym zrzucie ekranu.
Zacznijmy analizę od funkcji o nazwie actgHqKiTwOPTJgrMtswcXuISTNbA. Ta funkcja, przy odpowiednim spojrzeniu na kod, służy do wykonania następujących czynności:
- Stworzenia tablicy bajtów za pomocą funkcji jocRDdQVGJGYHMHOnyzbQutDfswG().
- Rozdzielenia tej tablicę na dwie: jedną zawierającą wszystko do 74 bajtu i drugą zawierającą resztę bajtów.
- Traktując krótszą tablicę jako klucz, wykonania operacji binarnej XOR na każdym bajcie dłuższej tablicy.
Mówiąc inaczej, równoważny kod w języku Python operacji w punktach 2 i 3 to:
key = table[:74] data = table[74:] result = [] for index, character in enumerate(data): result.append(chr(ord(character) ^ ord(key[index%74])))
Znamy algorytm szyfrowania, ale musimy jeszcze odkryć jak działa funkcja jocRDdQVGJGYHMHOnyzbQutDfswG. Funkcja ta, jeśli się jej uważnie przyjrzymy, ponownie, tworzy tablicę w następujący sposób:
- Odczytuje zasób o nazwie bxOzXIzHUTYdmpK
- Z tego zasobu odczytuje wartość (tablicę ciągów znaków) o nazwie lodpxyirK
- Dla każdego ciągu znaków z tej tablicy odczytuje zasób o tej właśnie nazwie
- Wynik jest konkatenacją zasobów z punktu 3.
Jeśli klikniemy w zasób bxOzXIzHUTYdmpK to zauważymy, że dotPeek udostępnia go nam w formie pliku XML. To powinno ułatwić implementację powyższej procedury odszyfrowywania zasobu. Kopiujemy zatem treść tego pliku XML do pliku tekstowego i piszemy skrypt, który pozwali nam odszyfrować dane.
Zacznijmy od wczytania pliku XML z zasobem i odnalezienia wszystkich wartości tego zasobu. Jak możemy wywnioskować z pliku zasoby są zakodowane za pomocą Base64. Poniżej znajduje się kod który wczyta nam wszystkie wartości.
# parsujemy plik z wejscia tree = etree.parse(sys.argv[1]) root = tree.getroot() # utworzmy slownik z wartosciami zasobu values = {} for data in root.findall('data'): key = data.get('name') value = data.find('value').text # pamietamy zeby odkodowac base64 przed zapisem wartosci zasobu! values[key] = base64.b64decode(value)
Teraz słownik values zawiera wszystkie wartości zasobu, który nas interesuje. Czas zatem wczytać tablicę lodpxyirK i znaleźć w niej wszystkie łańcuchy znaków. Trochę sobie to ułatwimy szukając po prostu ciągów literowych o długości co najmniej 3. Dzięki temu nie musimy wchodzić w szczegóły takie jak sposób serializacji tablicy w języku .NET. Kod, który odczyta tablicę i następnie znajdzie w niej wszystkie ciągi znaków i połączy odpowiednie wartości w jedną dużą tablicę znajduje się poniżej.
for string in re.findall('[A-Za-z]{3,}', lod): table.append(values[string]) table = ''.join(table)
Jedyne co pozostało to odszyfrowanie tablicy (jak w pierwszym kawałku kodu) i zapisanie wyniku. Cały skrypt znajduje się pod tym linkiem. Spróbujcie go uruchomić podając jako pierwszy argument plik XML z odpowiednim zasobem, wyciągnięty z dotPeek, a jako drugi argument plik wyjściowy. Skupiliśmy się tak bardzo na odszyfrowywaniu, że nie wiemy co tak naprawdę odszyfrowaliśmy. Tym razem, znowu, przychodzi nam z pomocą polecenie file. Jeśli wykonamy je na pliku wyjściowym otrzymamy:
out: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
Ha! Znowu .NET. No to wiemy co robić: otwieramy go w dotPeek!
RunPE, czyli kolejna warstwa pakowania
Tym razem wewnętrzna nazwa pliku to „Load” i pod „Root Namespace” mamy trzy klasy: RunPE, Persistence i ExecuteMe. Są one dość przejrzyście napisane i nie ma za wiele zaciemnienia kodu, więc możemy się w nie wczytać dokładnie. Z interesujących funkcji i elementów kodu zauważmy:
- Funkcję „avast()”, której zadaniem jest prawdopodobnie ochrona przez programem antywirusowym Avast. Zadanie dla czytelnika: czy możecie się domyślić w jaki sposób Avast implementuje część swoich funkcji, które są tu wykrywane?
- Wyświetlenie okien dialogowych o treści „Archiwum jest uszkodzone!” oraz „0”. Zadanie dla czytelnika: kiedy takie okna zostaną wyświetlone?
- Zostaje dodany wpis do rejestru gwarantujący autostart. Zadanie dla czytelnika: jaki jest to wpis?
- Plik wykonywalny jest kopiowany w inne miejsce dysku. To miejsce jest też zapisywane w pewnym pliku. Zadanie dla czytelnika: określić gdzie znajdują się oba pliki.
Odpowiedzi na powyższe pytania są poniżej, ale żeby je zobaczyć musicie kliknąć w spojler. Pamiętajcie, żeby nie oszukiwać i najpierw postarać się odpowiedzieć na pytania.
Dodatkowo, zauważmy, że jest zasób o nazwie Xtreme, w którym jest wartość „Comp”. Ta wartość jest wykorzystywana do uruchomienia kolejnego pliku wykonywalnego. Jako proste ćwiczenie pozostawiam odkodowanie tej wartości i otrzymanie kolejnego pliku wykonywalnego. Powinniście umieć to zrobić modyfikując kod, który napisaliśmy poprzednio.W końcu ten plik, po dwóch odszyfrowaniach, jest zaciemnioną wersją LuminosityLink RAT. Można to zauważyć jeśli uważnie przyjrzycie się zasobom (czeka tam na was mała niespodzianka w postaci adresu abuse do twórców LuminosityLink!). Dodatkowo, znajdziemy tam adres osoby, która zakupiła tę wersję RATa. Jedyne co pozostało to ustalenie C&C, ale to już można bardzo łatwo zrobić za pomocą analizy dynamicznej. Skoro o tym mowa…
Potwierdzanie wyników analizy statycznej
Przeprowadziliśmy dosyć rozbudowaną analizę statyczną, ale pozostaje pewnego rodzaju niepewność. Chociaż może to po prostu moja wrodzona cyberniepewność. W każdym razie mamy aż trzy różne pliki wykonywalne. Pierwszy – oryginalny, drugi, w którym kod czytaliśmy z dużą łatwością i trzeci – LuminosityLink. Istnieją dwa sposoby na wykonanie analizy dynamicznej: albo skorzystamy z gotowego rozwiązania, jak hybrid-analysis lub malwr, albo zrobimy to na własnej maszynie wirtualnej. Pierwszy sposób jest dosyć oczywisty, więc spróbujmy zrobić to sami. Uruchomienie pierwszej bądź drugiej próbki powinno z grubsza dać takie same rezultaty. Po uruchomieniu powinniśmy sprawdzić nasze ustalenia z analizy statycznej w następujący sposób:
- Za pomocą SysInternals Autoruns szukamy zidentyfikowanego wcześniej klucza rejestru.
- Za pomocą SysInternals Process Monitor możemy potwierdzić, że zostały utworzone pliki, które zidentyfikowaliśmy wcześniej. Możemy też bardzo dokładnie prześledzić działanie RunPE, co polecam, ale jego wyjaśnienie wykracza trochę poza ramy tego prostego opisu analizy.
Ewentualnie, jak wspomniałem wcześniej, możemy po prostu przeczytać te informacje na stronie Hybrid Analysis. Dodatkowo, obserwując połączenia sieciowe można szybko odnaleźć serwery C&C, z którymi łączy się LuminosityLink, a których wydobycie pominęliśmy. Oczywiście teraz pewnie myślicie, że cała wcześniejsza analiza statyczna byłą niepotrzebna, skoro doprowadziła do tych samych wyników a trwała dużo dłużej. Wszystko zależy od tego jaki macie cel – czy chcecie się czegoś nauczyć i zrozumieć jak działa, czy po prostu chcecie szybko wydobyć pewne informacje o złośliwym oprogramowaniu. Analiza statyczna (jeśli nie oszukiwaliście) pozwoliła Wam zrozumieć jak działa RunPE i jakie metody są wykorzystywane przez autorów złośliwego oprogramowania do utrudnienia pracy nam (tak, Wam teraz już też) – analitykom złośliwego oprogramowania.
Wnioski
Wszystkie te analizy by były tylko całkiem przyjemną zabawą, gdyby nie to, że możemy wyciągnąć z nich wnioski, które pomogą nam nie tylko zidentyfikować infekcję, ale także ją usunąć. Zauważmy, że podczas analizy odkryliśmy klucz rejestru, który jest tworzony przez jedną z warstw „opakowania” złośliwego oprogramowania. Sprawdzenie czy ten klucz występuje na maszynie jest tzw. IoC (Indicator of Compromise – wskaźnik infekcji). Jego usunięcie spowoduje, że złośliwe oprogramowanie nie uruchomi się przy restarcie systemu. Pamiętajmy jednak, żeby najpierw złośliwe oprogramowanie wyłączyć za pomocą Menadżera Procesów. Wiemy przecież jak będzie się nazywać plik wykonywalny, bo to też odkryliśmy w odpowiedziach na pytania. Możemy też usunąć złośliwe oprogramowanie z dysku, bo znamy jego lokalizację. Podsumowując:
- Wyłączamy złośliwe oprogramowanie korzystając z Menadżera Procesów.
- Usuwamy plik z kopią złośliwego oprogramowania z dysku.
- Usuwamy klucz rejestru korzystając z edytora rejestru lub SysInternals Autoruns.
I już. Dzięki naszej analizie i wyciągnięciu z niej wniosków byliśmy w stanie zdiagnozować i usunąć infekcję. Takie to było proste! Na koniec dodamy tylko, że serwer C&C znajdujący się pod adresem domenowym gtrentkiewicz.hopto.org wskazuje na adres IP 185.72.179.25. Ten z kolei adres należy do usługi VPN, umożliwiającej przekierowanie konkretnych portów na wskazany adres IP. Za taką właśnie usługą kryje się prawdziwy serwer C&C przestępcy.
Komentarze
Bardzo ładnie.
Ciekawy case i dobra analiza.
.
Adamie, więcej case’ów/analiz – to lepsze niż weekendowe lektury których nie da się przerobić.
True that ! Dużo i dobrze – lubimy :)
Ja akurat bardzo lubię weekendowe lektury, więc uprzejmie proszę o ich kontynuowanie. :)
*Łukaszu, więcej analiz
trochę słabo to zaplanowali – puszczać .exeka do miejsc, gdzie jest stosunkowo duży odsetek maków…
Świetne case study. Nie mogę się doczekać kolejnych!
Dodac trzeba ze na stronie sysinternals jest duzo innych przydatnych narzedzi. Do deasemblowania/debugowania tradycyjnych programow mozna uzyc x64dbg/x32dbg.
Bardzo fajny artykuł. Mam jedno pytanie – czym mogę sprawdzić, czy mój pc nie został zainfekowany tym bądź podobnym tałatajstwem ? Na rynku jest cała masa programów, ciężko coś wybrać. Czy istnieją w ogóle darmowe programy które dałyby radę to wykryć ?
Pozdrawiam serdecznie
Odpowiedź na to jak wykryć ten konkretny przypadek znajdziesz w sekcji „Wnioski”. Ogólniej, każdy sensowny program antywirusowy powinien sobie poradzić z tego typu zagrożeniami.
Super, więcej takich tutoriali
Od ostatniego razu gdy analizowaliście próbkę mojego Lumino,
jego autor zaktualizował kod tak aby każda próbka miała w souce wpisaną unikalna nazwę użytkownika której użył do rejestracji więc można go bezpośrednio powiązać z autorem znacznie łatwiej.
Do tego autor Luminosity zastrzegł po ostatnich aktualizacjach że nie życzy sobie wykorzystywania jego produktu nie zgodnie z prawem i zrobił to aby łatwiej namierzać takie przypadki i blokować licencje.
Dlatego ja Lumino wgrywam już tylko na pojedyncze komputery sprawdzone wcześniej innym ratem jeśli potrzebuje RDP lub proxy żeby losu nie kusić.
pokoża wom za pora dni (z Bożom pomocom) jak sie psuje światowe n’bezpieczeństwo.
Tak sobie pomyślałem, przecież to byłby świetny wabik na uruchomienie exploit’a na dotPeek’a czy jakiś inny dekompilator :D (exploit byłby w tym wewnętrznym exe).
Ja jestem może jakiś ułomny albo coś… Z Malwr pobieram plik ’.bin’. Jak mam otworzyć binarkę w dotPeek’u?
Jeśli pobrałeś plik .bin, to zmień jego rozszerzenie na .exe i następnie przeciągnij do albo otwórz w dotPeek. To Windows, niektórym programom bardzo zależy na prawidłowym rozszerzeniu.