Ramnit rozpoczął swoją działalność w 2010 roku. Rozprzestrzeniał się wtedy głównie infekując pliki wykonywalne i dołączając się do plików HTML. Rok później ukazała się jego groźniejsza wersja – autor wykorzystał kod złośliwego oprogramowania Zeus, który wyciekł w 2011 r. Wykorzystanie elementów kodu Zeusa pozwoliło dodać do Ramnita nowe funkcje, które ostatecznie uczyniły go pełnoprawnym trojanem bankowym.
Obecnie Ramnit posiada dużo więcej funkcji:
- Wykonywanie ataków Man-in-the-Browser
- Wykradanie haseł FTP i ciasteczek z przeglądarek
- Wykorzystywanie DGA (Domain Generation Algorithm) do znalezienia serwera C&C (Command and Control)
- Ręczne dodawanie wyjątków w programach antywirusowych
- Eskalacja uprawnień za pomocą podatności CVE-2013-3660 oraz CVE-2014-4113 (privilege escalation)
- Wykonywanie zrzutów ekranów
- ApplyExploit
- CheckBypassed
- start
- zaszyfrować dane większe niż 4 bajty z użyciem rc4 oraz klucza odzyskanego z xora
- zapakować dane w chunki
- połączyć wszystkie chunki razem
- zapakować ostateczny bufor do pakietu
- https://www.virusbulletin.com/virusbulletin/2012/11/ramnit-bot
- https://www.symantec.com/content/dam/symantec/docs/security-center/white-papers/w32-ramnit-analysis-15-en.pdf
- d290225dde1b18bf68c4c42e06638a61fb336c91a2c4e6dd007bcbe7327fcbae
- c2cae7d9ef91dfcc1ae8f542e0ac64ce66c526d5a4154241855020612d358ee8
- 1f3fbca46a599b4f221ead7785606451365db45bbbc537ee0c4d019e8984d106
- 9d723bb1dc375834ebb907271b83dffab44e98b82fa73da6267037f019e4bc83
- f3567e2b5fc521987f0dd79aff6f3b1328db8e03fa825c3c030080a8b5819564
- 7689465ba010537b0c29cf18d32a25962bd1605b717733f5953eb1b1eb0a68c9
- f98ca50b7d07682ac359b97dd68eb924c4cbd825db72c1a132458e9bb765fa1e
- 4b00b0ece480267af051e7907458381d8a9e8506c7da67b8a8e1d74d45773d68
- 6ac47d82134385fa73386ff3cd7b2eb7008da2205b3f5af7b41fab45c63f9046
- 6a1fc689d2ef32ee6288498f8a875c6dc880d7494f46c05d25d0e1f627984e8e
- 522e935b91307b8c01e0ea8a724985f5b4e01227a761aeccb63b00f0d964f7e9
- b3e67b5ee899c53f90c9da772592a4709372192542e1297bbce4929a8e1d5c69
- 71d92cc6dc9273d162a969960b1021e5f18cf39b2c48043e5c5e49db5a58d955
- da15c2a89334496910b6d966bf91fa25a1c9526c53796e06d166416abe7cf2f4
- e4353bda9692581ea9743165dfd843238c23bb92e24b778983de80e90ac650a3
-
AvTrust:
- b5a95a9bf419eab69d24b87ec561c657291d944acead30b25d004842db63338a
-
Chrome reinstall:
- 862e690b2b24ed9f0394b88a6698f92ee6a3d2c511f76794a749611110cf9835
-
CookieGrabber:
- 6e91c0cb5de7e8bdc5ad47581e07911424cfc784d38cd14dd9da0fa02fb0712c
-
FtpGrabber2:
- 4a8c064fce1d8cf4017dc95c484fc058594d0e11cb6304cc5b3fed0561223514
-
Hooker:
- a88151b3bf825e26ded28f94addeada095d2cd13791b2153a9594b26d9cfb85e
-
VNC IFSB:
- b9cd5010f807caa133f133dad436cb7874d4433e36038c39537297b25efe7887
Pomimo zamknięcia trzystu serwerów C&C przez Europol w 2015, Ramnit nadal ma się dobrze. Ostatnio jest dystrybuowany za pomocą exploit-kita RIG EK z seamless gates.
Działanie
Główny plik wykonywalny jest spakowany w pewnego rodzaju matrioszce: pierwsza (wierzchnia) warstwa to autorskie pakowanie, z kolei druga to normalny UPX.
Pomimo tego, że plik binarny jest zaszyfrowany, odzyskanie oryginalnej formy nie jest względnie trudne. Wystarczy uruchomić program ładujący w debuggerze, ustawić breakpoint zaraz po wypakowaniu się kodu i wejść do nowo powstałej funkcji.
Jeśli przeanalizujemy kod znajdujący się zaraz za końcem instrukcji odpowiedzialnych za załadowanie pliku wykonywalnego możemy łatwo zauważyć charakterystyczną sygnaturę formatu PE „MZ”:
Po odszyfrowaniu pliku wykonywalnego i dekompresji UPX można zauważyć 3 główne funkcje:
ApplyExploit
W dużym skrócie jest to funkcja, której zadaniem jest sprawdzenie czy aktualnie zalogowany użytkownik jest administratorem i czy program posiada odpowiednio wysoki poziom Windows Integrity Level. W sytuacji, gdy uprawnienia są zbyt niskie, stara się je podnieść korzystając z CVE-2013-3660 (załatane w MS13-053) oraz CVE-2014-4113 (załatane w MS14-058). Przed uruchomieniem exploita złośliwe oprogramowanie sprawdza czy aktualizacje łatające te podatności są zainstalowane w systemie operacyjnym.
Jeśli procesowi uda się uzyskać prawa administratora przechowuje wartość „TRUE” w kluczu rejestru HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\jfghdug_ooetvtgk.
CheckBypassed
W tej części kodu sprawdzane jest czy funkcji ApplyExploit udało się podnieść uprawnienia. Jeżeli wartość we wspomnianym wyżej kluczu rejestru nie została ustawiona, nadpisuje ją i uruchamia funkcję odpowiedzialną za dodanie wyjątków do Zapory sieciowej Windows.
start
Koordynuje działanie funkcji ApplyExploit i CheckBypassed. W przypadku udanego podniesienia poziomu uprawnień tworzy dwa procesy o nazwie „svchost.exe” i uruchamia w nich kod z bibliotek: modules.dll i rmnsoft.dll
Funkcja CheckBypassed jest wykonywana przed ApplyExploit, więc aby program w pełni się wykonał, musi zostać wykonany drugi raz.
Konfiguracja statyczna
Ramnit szyfruje komunikację z C&C za pomocą algorytmu RC4. Klucz wykorzystywany w komunikacji i identyfikator botnetu są dołączane do komunikatu w postaci zakodowanej z użyciem operacji XOR i stałego klucza osadzonego w próbce. Kodowanie pomija pierwszy znak klucza, a sam ciąg przetwarzany jest od końca.
Kod:
Wywołanie funkcji xor:
Podawane w argumentach długości wiadomości są zazwyczaj za długie i musimy polegać na terminacji stringów nullbyte’ami:
Konfiguracja DGA wydaje się być zawsze deklarowana na początku sekcji data
Mechanizm perzystencji
Program kopiuje sam siebie do C:\Users\User\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\.
DGA
Ramnit generuje listę potencjalnych domen C&C przy użyciu prostego generatora liczb pseudolosowych LCG (linear congruential generator):
Generowanie domen:
Kod algorytmu DGA Ramnita zapisany w Pythonie:
Komunikacja
Ramnit komunikuje się z serwerami C&C przez port 443, nie używa jednak standardowego HTTPS, lecz swojego własnego protokołu:
Struktura pakietu:
Struktura danych zawartych w żądaniu:
Jeśli więc chcemy wysłać własny pakiet z danymi musimy:
Przykład ruchu sieciowego:
Niektóre rozpoznane komendy:
Command | Byte Value | Description |
---|---|---|
COMMAND_OK | 0x01 | Server’s response that the command executed successfully |
GET_DNSCHANGER | 0x11 | Get DNS-changer payload |
GET_INJECTS | 0x13 | Get web injects |
UPLOAD_COOKIES | 0x15 | Upload stolen cookies (zip format) |
GET_MODULE | 0x21 | Get a specific module |
GET_MODULE_LIST | 0x23 | Get a list of downloadable modules |
REGISTER_BOT | 0xe2 | Register bot (send 2 md5s) |
UPLOAD_INFO_GET_COMMANDS | 0xe8 | Upload detailed machine info |
Rejestracja jako bot
Jeśli program chce się zarejestrować jako nowy bot wysyła rozkaz 0xe2 wraz z dwoma hashami md5 które bazują na strukturach:
Implementacja w Pythonie:
Jeśli rejestracja się powiodła i host zwrócił COMMAND_OK, bot wysyła pusty pakiet 0x51.
Odpowiedź zawiera podpisaną wiadomość za której pomocą klient, korzystając ze zapisanego klucza publicznego może stwierdzić czy nikt się nie podszywa pod serwer.
Moduły
Ramnit może wysłać żądanie o listę dostępnych modułów i pobrać poszczególne indywidualnie:
Antivirus Trusted Module v2.0
Dodaje wyjątki do określonej listy antywirusów:
Chrome reinstall module (x64-x86) v0.1
Odinstalowuje Google Chrome
I instaluje go ponownie:
Cookie Grabber v0.2 (no mask)
Kradnie ciasteczka z różnych lokalizacji systemowych i wysyła je spakowane w archiwum zip do C&C za pomocą rmnsoft.dll.
Hooker
Wykorzystywany do wykonywania ataków Man-in-the-Browser i podpinania się pod funkcje związane z HTTP.
Webinjecty
Webinjecty są stosunkowo nowym dodatkiem do Ramnita, korzystają jednak ze standardowego formatu używanego przez Zeusa:
Obfuskacja / Unikanie detekcji
Ramnit próbuje się ukryć przed Windows Defenderem dodając następujące wartości w rejestrze:
Instrukcje NOP są dodawane w losowych miejscach. Utrudnia to m.in. stworzenie reguły Yara, która byłaby w stanie odnaleźć kluczowe fragmenty kodu.
Aktualizacja
Podczas tworzenia tego artykułu natknęliśmy się na wariację Ramnita potocznie zwaną clickbideu. Program ładujący jest kompletnie inny, ale moduł służący do komunikacji (rmnsoft.dll) pozostał taki sam, z paroma małymi zmianami:
DGA dodaje 3 różne TLD (Top-Level Domain) cyklicznie zamiast jednego:
Zapis w Pythonie:
Nowa wersja używa portu 8001 zamiast 443, zauważyliśmy również wersje korzystające z portu 442.
Dodatkowo, inna wartość („fE4hNy1O”) jest wykorzystywana do wyliczenia drugiego skrótu md5