Rozbrajamy trojana. Część III: wirusy bezplikowe

W naszych poszukiwaniach złośliwych mechanizmów w makrowirusie stopniowo docieramy do kolejnych warstw złożoności. Jak się wkrótce okaże, jest ich naprawdę dużo. Obecnie znajdujemy się na etapie, w którym spreparowany dokument Office uruchamia makro i pobiera z BlogSpota plik HTA, zawierający złośliwe obiekty skryptowe. Owe obiekty na pobranej stronie pracują asynchronicznie: uruchamiane kolejno nie czekają na to, aż poprzednie przestaną pracować. Na potrzeby naszej analizy, oznaczmy badane skrypty jako M4, M3, M2 i M1.

Rozbrajamy trojana. Część III: wirusy bezplikowe (fot. Kamil Dudek)
Rozbrajamy trojana. Część III: wirusy bezplikowe (fot. Kamil Dudek)
Kamil J. Dudek

13.03.2021 | aktual.: 13.03.2021 22:33

Ostatni z czterech skryptów (M4) zajmuje się zamknięciem wszystkich okien dokumentów (Word, Excel, PowerPoint) których makra rozpoczęły infekcję. Minimalizuje teżokna HTA z „blogiem” i dokonuje zmiany rozmiaru jego okna na 0 pikseli. Gdy wszystkie skrypty rozpoczną pracę, okno HTA w ogóle znika, także z paska zadań. Co robią pozostałe skrypty? Wszystkie są dość zaciemnione, ale przestępcy byli na tyle uprzejmi, że pozostawili w kodzie komentarze! Nie są szczególnie pomocne, ale rozwiewają wątpliwości dotyczące intencji, stosując wprost słowo „atak”.

Autouruchamianie

Drugi skrypt (M3) operuje na Rejestrze. Tworzy klucz automatycznego uruchamiania (autostart po zalogowaniu) o nazwie „phulihoja”, instruujący system, by ten po zalogowaniu użytkownika uruchomił nieszczęsny MSHTA.EXE z parametrami. Tutaj wychodzi na jaw, że MSHTA poza nazwą pliku i adresem URL przyjmuje jeszcze trzecią postać argumentów wiersza polecenia, w postaci... treści skryptu JS/VBS. Zachowując się w ten sam sposób, co pasek adresu Internet Explorera, MSHTA potrafi wykonać skrypt VBS gdy przekaże mu się go w wierszu, zaczynając od „vbscript:”. Nie trzeba pobierać pliku z internetu ani ładować żadnej aplikacji. Dzięki temu możliwe jest wykonywanie skryptów VBS nawet w systemie, w którym zablokowano CSCRIPT i WSH, a nawet zapisywanie plików.

Portfel BitCoin okazuje się być dość pusty... (fot. Kamil Dudek)
Portfel BitCoin okazuje się być dość pusty... (fot. Kamil Dudek)

Co robi skrypt przekazywany w poleceniu do MSHTA? Otwiera PowerShella, któremu także w parametrach wiersza poleceń podaje skrypt do wykonania, tym razem, oczywiście, w języku PowerShell, a nie Visual Basic. Skrypt ten także jest króciutki i nakazuje tylko jedną rzecz: wczytać zawartość klucza Rejestru „btfee” i wykonać jako skrypt PowerShell. Tenże klucz jest bardzo, bardzo długi. I na pierwszy rzut oka, kompletnie nieczytelny.

A zatem skąd bierze się klucz „btfee”? On także jest ustawiany przez M3. I ten klucz jest już zauważalnie dłuższym kodem niż poprzednie. Zawiera bardzo długą zmienną tekstową, która następnie jest (głęboki wdech!)

konwertowana na tablicę typu charodwracana łączona z powrotem w łańcuch ponownie przekształcana na tablicę, ale tym razem z usunięciem symbolu procenta używanego jako separator.

Rezultatem jest tablica liczb zapisanych heksadecymalnie. Przez tak powstałą tablicę przechodzi wreszcie iterator i konwertuje każdą pozycję na symbol. Symbole są łączone w łańcuch i wykonywane jako wyrażenie PowerShell. Uff!

Bezplikowy nośnik

Robi się mętnie? A my dalej nie dotarliśmy do końca! Otrzymane wyrażenie odpytuje Schowek, a następnie w martwej pętli umieszcza w nim adres portfela BitCoin. W ten sposób, od momentu uruchomienia komputera w Schowku docelowo przez cały czas znajduje się ten sam element. Powoli staje się jasne, czego dokładnie oczekują przestępcy, a przynajmniej w jakiej postaci chcą otrzymać zapłatę za zaprzestanie swoich działań. Nazwa „btfee” to prawdopodobnie określenie na „BitCoin Fee”, czyli opłatę. Ktoś chce dostać od nas pieniądze.

"Sub to execute our attack" (fot. Kamil Dudek)
"Sub to execute our attack" (fot. Kamil Dudek)

Skrypt M3 oczywiście nie czeka aż do kolejnego zalogowania, by odpalić autostart. Rozpoczyna umieszczanie w schowku adresu portfela już od momentu swojego pierwszego uruchomienia. Sprawdza też architekturę pod którą jest uruchamiany, ale nie to jest w nim najciekawsze. Kunsztem technicznym niniejszego rozwiązania jest to, że jest całkowicie bezplikowe. Skan antywirusowy nie znajdzie żadnego złośliwego pliku na dysku a analizator Rejestru nie wykaże niebezpiecznych dodatków dorzuconych do autostartu, bo przecież na liście znajduje się MSHTA i PowerShell, a więc pliki podpisane przez Microsoft. Dopiero opracowanie definicji dokładnie pod to zagrożenie pozwoli je wykryć. A (jak widać) kod jest napisany tak, że zmiana jednej literki zmienia treść skryptu, a nazwy kluczy są zapewne dobierane losowo i zmieniane przy każdej kampanii.

Program wprost z Rejestru

W międzyczasie działa trzeci skrypt (M2), największy. Na pierwszy rzut oka wydaje się on być główną atrakcją w całej infekcji, ale nawet ten skrypt nie jest jeszcze najważniejszym składnikiem. Jego działanie jest zbliżone do M3. Najpierw próbuje odkręcić łańcuch tekstowy (bardzo, bardzo długi) i zapisać do Rejestru jako klucz tekstowy. A potem dodać klucz autouruchamiania, w którym odpala się PowerShella wykonującego klucz tekstowy jako kod.

(fot. Kamil Dudek)
(fot. Kamil Dudek)

Klucz ten jest już bardziej destruktywny niż poprzedni, który „tylko” wklejał portfel BitCoina do Schowka. Tym razem następuje uruchomienie kodu binarnego, w postaci złośliwego programu, a nie skryptu jak dotychczas. Powtórzmy: przestępcy odkryli sposób na uruchamianie kodu wykonywalnego bezpośrednio z Rejestru. Nie ma konieczności zapisywania żadnego EXE, SCR ani DLL, które mogłyby zostać zablokowane przez antywirusa. W jaki sposób tego dokonać? Ano trzeba się bardzo, bardzo postarać, ale to wykonalne. Oto przepis, wykonywany jako skrypt PowerShell:

Bardzo długi łańcuch tekstowy (zmienna o długości 102 kilobajtów) jest odkodowywany przesunięciem bitowym i konwertowany na tablicę typu Byte Tworzona jest nowa sekcja uruchomieniowa .NET typu AppDomain (szczegóły poniżej) i uzyskiwany jest do niej dostęp Do nowej sekcji uruchomieniowej ładowana jest stworzona wcześniej tablica typu Byte, która okazuje się być... surowym obrazem dla assembly .NET CLR. Dzięki temu następuje „import” metod i własności z tego assembly do środowiska i aktualny runspace PowerShella może sięgać do przestrzeni nazw dostarczonej przez assembly bez przeładowywania (cóż za fantastyczne zdanie, język polski doprawdy lepiej sprawdza się w rozprawianiu o husarii) Runspace uzyskuje dostęp do nowej przestrzeni o nazwie „rerup” i woła z niej metodę „qw5f0”, przyjmującą dwa parametry: nazwę programu oraz długi łańcuch tekstowy Kolejny, bardzo długi łańcuch tekstowy (zmienna o długości 124 kilobajtów) jest odkodowywany przesunięciem bitowym i konwertowany na tablicę typu Byte Tablica ta jest posyłana do funkcji qw5f0 wraz z nazwą systemowego kompilatora Visual Basic (VBC.EXE) Funkcja qw5f0 uruchamia systemowy kompilator VBC.EXE, wstrzymuje proces, dokonuje jego wydrążenia i ładuje do zmapowanej pamięci procesu zawartość innego obrazu wykonywalnego

I w ten sposób, drodzy państwo, bez żadnego pliku na dysku i korzystając wyłącznie ze skryptów, da się uruchomić binarny kod wykonywalny. Nie tylko na dysku nie powstał ani jeden EXE, ale także lista procesów składa się wyłącznie z programów dostarczonych bezpośrednio z Windowsem: MSHTA, PowerShell i VBC.

Kompilator .NET - ale po co?

Nieco dziwi wybranie akurat VBC.EXE. Kompilowanie złośliwego kodu w locie jest znaną techniką omijania zabezpieczeń, stosowane są do tego właśnie kompilatory VB i C#, a ich uruchamianie ma bardzo mało sensowych zastosowań. Dlatego analizatory stacji roboczych są bardzo wrażliwe na VBC (na PowerShella zresztą też), więc spośród wielu programów dołączonych do systemu dałoby się wybrać jakiś mniej podejrzany.

PowerShell na Linuksa to dobry pomysł, jeżeli pracujemy ze skryptem dostarczającym trojana dla Windowsa (fot. Kamil Dudek)
PowerShell na Linuksa to dobry pomysł, jeżeli pracujemy ze skryptem dostarczającym trojana dla Windowsa (fot. Kamil Dudek)

Możliwe też, że wybrano program który nie potrzebuje GUI, a jedynie CONHOST (tryb tekstowy), a uruchomiony bez parametrów pisze tylko na standardowy błąd (stderr). Być może tylko z takimi programami współpracuje qw5f0 lub tylko w taki sposób udało się ukryć wszystkie okna jego instancji. Programów spełniających takie warunki istotnie może być w systemie nieco mniej. Swoją drogą, VBC to kompilator już trzeciej odmiany Visual Basica pojawiającej się w tej historii. Do języków Visual Basic for Applications i Visual Basic Scripting Edition dołączył niniejszym Visual Basic.NET.

Co robi program uruchomiony przez wydrążoną kopię VBC? To dobre pytanie. Funkcja qw5f0 chyba nie uruchamia ładowanych programów wprost, ponieważ obraz ładowany do niej nie jest zwyczajnym plikiem programu. Istotnie jest to „EXE”, ma nagłówek MZ, ale… nie jest w formacie PE. Narzędzie PE Bear nie chce mieć nic do czynienia z tym plikiem, biblioteki parsujące PE nie potrafią wydzielić z niego sekcji, a narzędzie file informuje, że plik jest programem, ale dla MS-DOS. Takiego programu nie da się uruchomić wprost z poziomu Windows, więc qw5f0 wydaje się robić coś więcej.

Podsumowanie części trzeciej

Możliwe jest wykonywanie skryptów bezpośrednio z Rejestru Skrypty VBS uruchamiane wprost z internetu mają możliwość modyfikowania zawartości schowka Nie tylko skrypty, ale i kod wykonywalny może być uruchamiany bezpośrednio z Rejestru Bezplikowe zagrożenia wykorzystują wyłącznie programy dołączone do Windows Wstawki w Rejestrze są tak zaciemnione, że antywirus nie tylko nie znajdzie żadnego pliku na dysku, ale i nie wykaże zagrożeń wykorzystujących Rejestr

Programy

Zobacz więcej
Wybrane dla Ciebie
Komentarze (25)