Poniżej opiszemy jak uzyskać część z w/w informacji w sposób bardziej zautomatyzowany.
Z roku na rok zauważamy wzrost złośliwego oprogramowania, które przeznaczone jest dla 64 bitowego systemu operacyjnego. Zajmiemy się plikiem, który jest wykrywany przez część z programów AV jako EMOTET (niektóre komponenty działają wyłącznie na 64 bitowym systemie operacyjnym). Dodatkowo twórcy malware w celu utrudnienia analizy szyfrują komunikację pomiędzy zainfekowaną stacją roboczą a serwerami C&C.
Pod koniec ubiegłego roku na jednej z konferencji w Warszawie pokazywaliśmy jak monitorować/modyfikować działanie malware za pomocą pakietu Microsoft Detours. Pakiet ten ma jedną wadę – wersja 64 bitowa jest płatna.
Jest co najmniej kilka rozwiązań, które mogą być alternatywą dla Detours włączając również Microsoft Debugging Tools. My dzisiaj opiszemy bibliotekę MinHook.
Zasada działania MinHook jest taka sama jak biblioteki Detours. Nadpisywane są pierwsze instrukcje funkcji które chcemy monitorować lub modyfikować (ang. „hooking”). Początek funkcji nadpisywany jest instrukcją JMP i wskazuje na nasz kod.
Na podanej poniżej stronie umieściliśmy szablon biblioteki, którą będziemy wstrzykiwali w proces, który chcemy monitorować. Należy również pobrać skompilowana wersję lub kod źródłowy biblioteki MinHook.
Dodawanie funkcji, którą chcemy monitorować składa się z kilku kroków:
- Deklarujemy i tworzymy wskaźnik do oryginalnej funkcji:
CRYPTDECRYPT fpcryptdecrypt = NULL;
- Definiujemy funkcję, która zostanie wywołana zamiast oryginalnej funkcji:
{
LoggerW(L"CryptDecrypt call");
WriteToLogFile("Before CryptDecrypt call: ",pbData, rozmiar);
dane = fpcryptdecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
WriteToLogFile("After CryptDecrypt call: ",pbData, rozmiar);
return dane;
}
WriteToLogFile() to kolejna przygotowana przez nas funkcja. Jej celem jest zapisywanie istotnych informacji dot. przechwytywanych funkcji. Czasami warto funkcję WriteToLogFile() wywołać dwa razy (przed wywołaniem oryginalnej funkcji i po jej wywołaniu - tutaj przykład z funkcją CryptDecrypt() wykorzystywaną przez analizowany malware).
pbData[in, out] to wskaźnik do bufora zawierającego dane do odszyfrowania co oznacza że zapiszemy w pliku dane przed odszyfrowaniem i po odszyfrowaniu.
- Odczytujemy i zapisujemy adres funkcji, która będziemy modyfikowali:
pcryptdecrypt = GetProcAddress(GetModuleHandleA("Advapi32.dll"), "CryptDecrypt");
- Wywołujemy MH_CreateHook(), która modyfikuje funkcję ale jeszcze nie aktywuje jej:
- Włączamy wszystkie modyfikacje:
Analogicznie powtarzamy punkty 1-4 dla innych funkcji, które pozwolą nam zidentyfikować zachowanie złośliwego oprogramowania. Aby sprawdzać co jest wysyłane i odbierane przez analizowany malware przechwycimy 3 funkcje:
- CryptDecrypt()
- CryptEncrypt()
- CrypthashData()
Uruchamiamy program, który załaduje bibliotekę do wskazanego procesu:
C:\simple_injector.exe
Podaj PID: 1148
Injecting DLL to PID: 1148
Sprawdzamy, czy w przestrzeni adresowej znajduje się nasza biblioteka.
Poniżej fragment szyfrowanej komunikacji pomiędzy malware a serwerami C&C.
Poniżej fragment pliku z odszyfrowaną komunikacją:
- Wysyłane dane przez malware przed zaszyfrowaniem:
- Odebrana i odszyfrowana komunikacja z serwera C&C:
Analizowany malware co kilka minut pobierał nową konfigurację. Oprócz nazw banków, skryptów, serwerów C&C znajdowały się również adresy polskich serwerów na których umieszczone jest złośliwe oprogramowanie.
Źródła:
[1] https://github.com/TsudaKageyu/minhook
[2] https://github.com/Prevenity/malware_monitor
[3] MD5: BBB080336BC3BFA054D9C8491DB5E2D4
[4] http://research.microsoft.com/en-us/projects/detours/