niedziela, 30 listopada 2014

Banking trojan - analiza loader-a .NET



Od mniej więcej dwóch miesięcy można zauważyć, że część rozsyłanego złośliwego kodu wykorzystuje ciekawy mechanizm utrudniający analizę. Wstępna analiza pokazuje, że malware jest aplikacją utworzoną w .NET. Po uruchomieniu ładowany jest payload z tablicy (czasami też dodatkowo zabezpieczany, aby nie można było go poddać procesowi deasemblacji) a dopiero następnie uruchamiany.

Za pomocą ILSpy możemy wykonać dekompilacje kodu pliku wykonywalnego .NET. Inną przydatną funkcją ILSpy jest możliwość zapisu kodu źródłowego do projektu Visual Studio - skorzystamy z tej funkcji innym razem przy opisie innego ciekawego przypadku malware napisanego częściowo w .NET).

Poniżej fragmentu zrzutu ekranu z ILSpy:

 

Funkcja main() wywołuje metodę egSRqQdTEfs(). W tej metodzie możemy zidentyfikować trzy główne fragmentu kodu:  1 – ładowanie kodu z tablicy, 2 – alokacja pamięci dla kodu niezarządzanego oraz kopiowanie danych (metoda Marshal.Copy zwraca wskaźnik do pamięci z kodem), 3 – uruchomienie kodu niezarządzanego – czyli kodu malware (payload). Przed uruchomieniem wywoływana jest metoda Marshal.GetDelegateForFunctionPointer. Metoda ta konwertuje wskaźnik funkcji kodu malware na strukturę danych która wskazuje statyczną metodę.


Oznacza to, że ostatecznie będzie uruchamiany kod z tablicy znajdującej się w analizowanej aplikacji.






W celu zlokalizowania miejsca w pamięci, gdzie będzie załadowany kod malware (payload) oraz przekazana kontrola ustawiamy breakpoint na funkcji  VirtualAlloc.
Weryfikując odwołania do funkcji VirtualAlloc (wywołania inne niż z mscorwks.dll) jesteśmy w stanie bardzo szybko zlokalizować kod zarządzany malware (tzw. loadera) oraz miejsce gdzie będzie znajdował się payload złośliwego oprogramowania. Można zauważyć, że sekwencja instrukcji mov, dwóch call związana jest z wykonywaniem kodu object.Equals(wartość, wartość) - kilkadziesiąt takich funkcji jest między innymi w main aplikacji .NET.




Poniżej znajduje się fragment kodu który do rejestru ECX przenosi adres pierwszej instrukcji malware (jest to miejsce w pamięci gdzie znajduje się payload):

002E06D2   8BCE             MOV ECX,ESI
002E06D4   8BD7             MOV EDX,EDI
002E06D6   E8 F563C166      CALL mscorlib.66EF6AD0
002E06DB   8B4D E4          MOV ECX,DWORD PTR SS:[EBP-1C]
002E06DE   FF15 34612500    CALL DWORD PTR DS:[256134]
002E06E4   B9 0CABF966      MOV ECX,66F9AB0C
002E06E9   E8 2E19F4FF      CALL 0022201C
002E06EE   8BF8             MOV EDI,EAX

Po wyjściu z funkcji możemy znaleźć pod tym adresem załadowany kod malware (payload).





Poniżej fragment związany z wywołaniem funkcji Invoke(), która wywoła kod malware:

002E0D61   C747 04 65000000 MOV DWORD PTR DS:[EDI+4],65
002E0D68   8BCF             MOV ECX,EDI
002E0D6A   C746 04 16000000 MOV DWORD PTR DS:[ESI+4],16
002E0D71   8BD6             MOV EDX,ESI
002E0D73   E8 585DC166      CALL mscorlib.66EF6AD0
002E0D78   8BCB             MOV ECX,EBX
002E0D7A   8B41 0C          MOV EAX,DWORD PTR DS:[ECX+C]
002E0D7D   8B49 04          MOV ECX,DWORD PTR DS:[ECX+4]
002E0D80   FFD0             CALL EAX
002E0D82   B9 0CABF966      MOV ECX,66F9AB0C

Poniżej fragment funkcji modułu mscorwks.dll, która ostatecznie wywołuje malware (w niniejszym przypadku umieszczony pod adresem 0x310000).


MD5: B5BB7193977CBD3D592A07E114700634