0x1 Charakterystyka pliku
- Nazwa: SlimAgent
- Format: DLL (x64)
- MD5: 889B83D375A0FB00670AF5276816080E
- SHA1: 5603e99151f8803c13d48d83b8a64d071542f01b
- Entry Point (RVA): 0x921C
- Ilość eksportowanych funkcji: 9
- Biblioteka nie jest podpisana cyfrowo
Biblioteka eksportuje 9 funkcji. Pierwsza funkcja pozwala na bezpośrednie wywołanie złośliwego kodu zaimplementowanego w bibliotece (np. z użyciem rundll32.exe). Pozostałe 8 funkcji jak i entry point są wykorzystywanie do implementacji techniki DLL Proxying i następnie wywołania złośliwego kodu.
Tablica eksportu:
0x2 Metody uruchomienia złośliwego kodu
- Tryb automatycznego uruchamiana w którym Windows ładuje DLL automatycznie - wtedy wywoływana jest funkcja DLLMain.
- Tryb z linii komend w którym wskazana jest konkretna funkcja - w tym przypadku #1.
Tryb 1 - DLL Proxying
W trybie automatycznego ładowania (przez explorer.exe), malware podszywa się pod systemową bibliotekę eapphost.dll.- Malware pobiera ścieżkę do oryginalnej biblioteki %SystemRoot%\System32\eapphost.dll.
- Za pomocą LoadLibraryW() ładuje autentyczny moduł i dynamicznie buduje tablicę adresów funkcji eksportowanych (GetProcAddress).
Wszystkie legalne wywołania systemowe są przekierowywane (proxowane) do oryginalnej biblioteki, co zapobiega awariom systemu i ukrywa obecność złośliwego kodu. Te technika nazywa się DLL Proxying.
Podczas inicjalizacji w tym trybie kluczową rolę odgrywa procedura wywoływana przez dllmain_dispatch(), do której prowadzi punkt wejścia (Entry Point) biblioteki. Poniższy listing dekompilacji przedstawia fragment kodu rozpoczynający się pod offsetem 0x13C0 (przy założeniu domyślnego adresu bazowego ImageBase równego 0x180000000). Analiza kodu potwierdza implementację techniki DLL Proxying: malware ładuje autentyczny moduł eapphost.dll za pomocą funkcji LoadLibraryW(), a następnie w pętli iteracyjnej (zakres 0x40 bajtów z krokiem 8) dynamicznie rozwiązuje adresy ośmiu oryginalnych eksportów przy użyciu GetProcAddress. Pobrane wskaźniki są zapisywane w lokalnej tablicy adresów, co umożliwia transparentne przekierowanie wywołań systemowych.
// Fragment procedury inicjalizującej DLL Proxying (Offset: 0x13C0)
// Alokacja pamięci i przygotowanie ścieżki do oryginalnej biblioteki systemowej
pWVar1 = (LPWSTR)FUN_malloc_base(uVar2);
ExpandEnvironmentStringsW(L"%SystemRoot%\\System32\\eapphost.dll", pWVar1, nSize);
// Ładowanie autentycznego modułu do przestrzeni adresowej procesu
DAT_1800562f0 = LoadLibraryW(pWVar1);
thunk_FUN_180009a4c();
// Pętla dynamicznego rozwiązywania eksportów
uVar2 = 0;
do {
// Pobieranie adresu funkcji z oryginalnej biblioteki na podstawie tablicy nazw
pFVar3 = GetProcAddress(DAT_1800562f0,
*(LPCSTR *)((longlong)&PTR_s_OnSessionChange_1800484f0 + uVar2));
// Zapisywanie wskaźnika do lokalnej tablicy skoków
*(FARPROC *)((longlong)&DAT_180056300 + uVar2) = pFVar3;
uVar2 = uVar2 + 8; // Krok 8 bajtów (architektura x64, wskaźniki 64-bitowe)
} while (uVar2 < 0x40); // Przetworzenie 8 eksportowanych funkcji (8 * 8 = 64 bajty)
// Weryfikacja kontekstu procesu wykonawczego
pWVar1 = (LPWSTR)FUN_malloc_base(0x208);
GetModuleFileNameW((HMODULE)0x0, pWVar1, 0x104);
// Sprawdzenie, czy biblioteka została załadowana przez proces explorer.exe
pWVar1 = StrStrIW(pWVar1, L"explorer.exe");
if (pWVar1 != (LPWSTR)0x0) {
// Inicjalizacja głównego wątku złośliwego oprogramowania
CreateThread((LPSECURITY_ATTRIBUTES)0x0, 0, FUN_main, (LPVOID)0x0, 0, (LPDWORD)0x0);
return 1;
}
Fragment przestrzeni pamięci malware (tablica z adresami oryginalnych funkcji):
Uzupełniona tablica eksportu z malware:
Instrukcja skoku do oryginalnej funkcji - w tym przykładzie OnSessionChange():
Ostatnim etapem w przedstawionym powyżej kodzie jest sprawdzenie, czy biblioteka uruchomiona jest w kontekście procesu explorer.exe. W przypadku pozytywnej weryfikacji, inicjuje główny wątek roboczy za pomocą CreateThread(). Główna funkcja złośliwego kodu znajduje się pod offsetem 0x1230.
Tryb 2 - Wywołanie bezpośrednie
Pozwala na szybkie uruchomienie bez konieczności konfiguracji plików systemowych. Ta komenda też może być dodana do autostart rundll32.exe eapphost.dll,#1
Poniżej fragment wywoływanego kodu i funkcja CreateThread() wywołująca główny kod malware (ponownie trafiamy pod offset 0x1230):
0x3 Funkcjonalność
- Keylogger: Rejestracja sekwencji uderzeń klawiszy przy użyciu GetKeyboardState() wraz z kontekstem aktywnego okna.
- Screen Capture: Wykonywanie zrzutów ekranu i zapisywanie jako jpg.
- Clipboard Monitor: Monitorowanie i przechwytywanie zawartości schowka systemowego.
<img src="data:image/jpeg;base64, [DŁUGI_CIĄG_ZNAKÓW]"/><br>
Zrzut z pamięci z fragmentem raportu:
Wygenerowany raport stanowi chronologiczny zapis aktywności. Zastosowany format pozwala na pełną rekonstrukcję zdarzeń dzięki naprzemiennemu umieszczaniu danych tekstowych i graficznych.
- Logi systemowe i telemetryczne: Wyróżnione w raporcie (kolor czerwony) są komunikaty statusowe generowane przez malware, metadane okien procesów oraz surowe dane przechwycone z klawiatury i schowka systemowego.
- Wizualne potwierdzenie: Pomiędzy wpisami tekstowymi umieszczane są zrzuty ekranu zakodowane w formacie Base64. Dzięki temu każda operacja tekstowa jest bezpośrednio powiązana z kontekstem wizualnym widocznym na pulpicie użytkownika.
0x4 Kryptografia
Klucz publiczny RSA jest wykorzystywany wyłącznie do szyfrowania klucza sesji (unikalnego klucza AES 256 bit). Poniżej fragment kodu, który odpowiada za import klucza publicznego RSA, generowanie klucza AES oraz szyfrowanie klucza AES za pomocą klucza publicznego RSA.
Kluczowym etapem ochrony danych jest asymetryczne szyfrowanie klucza sesji. Wygenerowany klucz AES zostaje zaszyfrowany przy użyciu klucza publicznego RSA atakującego. Proces ten tworzy bezpieczny obiekt, który może zostać odszyfrowany wyłącznie przez atakującego posiadającego odpowiadający mu klucz prywatny.
Właściwa procedura szyfrowania zebranych artefaktów (implementowana w FUN_1800072b0) operuje na wcześniej przygotowanym kluczu AES. Wykorzystanie natywnego interfejsu Windows CryptoAPI pozwala złośliwemu oprogramowaniu na uniknięcie implementacji własnych bibliotek kryptograficznych.
0x5 Zarządzanie plikami
- Nagłówek: Rozmiar całości.
- Zaszyfrowany klucz AES: (Zaszyfrowany przez RSA).
- Zaszyfrowane Dane: (Zaszyfrowane przez AES).
- Wykorzystując funkcję ExpandEnvironmentStringsW(), malware dynamicznie pobiera lokalizację katalogu tymczasowego użytkownika z prefiksem systemowym: %TEMP%\Desktop_. Pliki są umieszczane w lokalizacji C:\Users\<user>\AppData\Local\Temp\.
- W celu zapewnienia unikalności plików malware pobiera czas systemowy za pomocą _Xtime_get_ticks oraz _localtime64. Dane te są formatowane do ciągu znaków według wzorca: %d-%m-%Y_%H-%M-%S (Dzień-Miesiąc-Rok_Godzina-Minuta-Sekunda).
- Kod składa końcową nazwę pliku, łącząc prefix, sformatowaną datę oraz specyficzne rozszerzenie .svc. Ten konkretny wzór to ostatecznie: C:\Users\<user>\AppData\Local\Temp\Desktop_[DATA]_[GODZINA].svc
0x6 Podsumowanie
Dobra implementacja modelu szyfrowania, zaawansowana obsługa błędów, wbudowane logowanie zdarzeń samego malware czy mechanizmy zbierania danych poufnych wskazują na dojrzały komponent wykorzystywany do ataków przez grupę APT.
0x7 Źródła
[2] https://cert.gov.ua/article/6284080








