McRat Malware Analysis – Part1

In this issue we are going to analyze McRat, a user’s data and passwords stealer. This malware is interesting since it makes use of some anti-debugging techniques and several encryption/obfuscation layers in order to prevent us from analyzing its code; the analysis will be divided in two parts, during the the first part we will bypass the anti-debugging protection and during the second we will discuss malware’s behavior.

Tools:

Analysis

The file we are going to analyze can be found on malware databases by hash search, our has been kindly provided by emd3l:

  • MD5: 4d519bf53a8217adc4c15d15f0815993
  • SHA1: fa9674bab61c37717f8232ebd47af915f9eb9e49

First of all let’s take a first look at PE sections and header with PEiD:

McRat_p1_sshot-1

PEiD

McRat_p1_sshot-2

PE Details

After opening the file with ollydbg you can see some code including INT3 commands, so if we try to debug this we will soon face a problem. This is something similar to nanomite protection to prevent us from debugging. The program uses an exception handler to bypass such errors, so if we try to put a breakpoint on that we can evade the protection, btw for finding exception handler just take a look at the 4th line in ollydbg code window.

00401D9A . 68 E81E4000 PUSH McRAT.00401EE8 ; SE handler installation

After adding a breakpoint on 00401EE8 just hit F9 once to stop at the exception handler. After analyzing the routine line by line I’ve found out that the call at 00401F6B is important for us:

00401F6B |. FF548F 08 |CALL DWORD PTR DS:[EDI+ECX*4+8] ; McRAT.00401DC6

After stepping into the call you’ll find another call:

McRat_p1_sshot-3

Call to dropper function

In 004018F0 you can see you can see the main dropper routine, in this function the malware creates its own dlls and services and tries to alter some registry keys so let’s analyze this function in depth. In 401906 the malware checks if the current user is an administrator or not by calling IsUserAnAdmin() api. As my user level is Administrator, the jump after this command won’t be followed.

004018FD :  PUSH EBX
004018FE :  PUSH ESI
004018FF :  MOV ESI,DWORD PTR DS:[<&SHELL32.#680>] ; shell32.IsUserAnAdmin
00401905 :  PUSH EDI
00401906 :  CALL ESI ; shell32.IsUserAnAdmin; <&SHELL32.#680>
00401908 :  TEST EAX,EAX
0040190A : JE McRAT.00401C39

Call at 00401910 checks if malware is running on 64Bit OS or not:

004018A0 :  PUSH ECX ; ntdll.7C91003D
004018A1 :  PUSH ESI
004018A2 :  PUSH McRAT.00403328 ; /ProcNameOrOrdinal = "IsWow64Process"
004018A7 :  PUSH McRAT.00403314 ; |/pModule = "kernel32"
004018AC :  MOV DWORD PTR SS:[ESP+C],0 ; ||
004018B4 :  CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; |\GetModuleHandleW
004018BA :  PUSH EAX ; |hModule
004018BB :  CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
004018C1 :  MOV ESI,EAX
004018C3 :  TEST ESI,ESI
004018C5 :  JE SHORT McRAT.004018DC
004018C7 :  LEA EAX,DWORD PTR SS:[ESP+4]
004018CB :  PUSH EAX
004018CC :  CALL DWORD PTR DS:[<&KERNEL32.GetCurrent>; [GetCurrentProcess
004018D2 :  PUSH EAX
004018D3 :  CALL ESI
004018D5 :  TEST EAX,EAX
004018D7 :  JNZ SHORT McRAT.004018DC
004018D9 :  POP ESI
004018DA :  POP ECX
004018DB :  RETN
004018DC :  MOV EAX,DWORD PTR SS:[ESP+4]
004018E0 :  POP ESI
004018E1 :  POP ECX
004018E2 :  RETN

Again IsUserAdmin() is called. There is a call at 00401960 which seems to be interesting, so we can step into it. McRat calls OpenSCManagerW() to get access to windows services. Then it gets the services names and compare each service name with “Brower” in a loop:

McRat_p1_sshot-4

Looking for Brower

Maybe that’s a typo for “Browser”? Then it searches for svchost.exe -k netsvcs in services and the first service that it finds is AppMgmt. McRat then looks for AppMgmt’s service dll from the registry that is located in:

  • “%SystemRoot%\System32\appmgmts.dll”

Later it modifies the service options and gives high privileged to the service. These options can be controlled from the windows registry:

McRat_p1_sshot-5

Modified service options

After returning from the call, McRat puts AppMgmt’s service dll name as input for a call to wsprintf() and then it generates the following:

  • “%USERPROFILE%\AppMgmt.dll”

In 004019CD it reads some data from its registry. After analyzing it I’ve found out that its a dll located in BIN directory. McRat extracts this dll to User Profile and renames it to AppMgmt.dll. Then it modifies ServiceDLL value from the registry, it also saves its droppers address there:

McRat_p1_sshot-6

Dropper path

Now the function at 0040100 is invoked. At this time the service is stopped, by calling this function McRat starts AppMgmt, so in turn this starts its main functions which are located in that dll. After this call the malware terminates itself with an ExitProcess(). So for now don’t run the service, as we don’t want to get infected yet :D.

  1. Open the dll with ollydbg or a hex editor.
  2. Jump to the entrypoint and then patch it with EB FE, this is a technique we have already used for other analysis.
  3. You are ready to run the service manually.

With Process Hacker you can now find the svchost that runs this dll (just check the CPU usage, that instance will be using all the CPU) and attach to it from ollydbg.

  1. Open the Threads windows in ollydbg.
  2. Patch back the entrypoint with the original code.
  3. Actualize the thread.

As you see at first it calls GetModuleHandleW() and then it creates a thread by calling CreateThread(). So let’s put a breakpoint on thread function which is 1000163F in my machine, to find this address simply take a look at the function arguments. McRat checks if the dll is called by mcproxy.exe or not, if the jump is not taken, the process will be terminated so we need to modify the je to a nop.

McRat_p1_sshot-7

McRat Thread

After stepping into the call,  McRat decrypts some of its code by xoring the data with key 75h:

MOV ESI,078B8h @appmgmt_10001443:
MOV CL,BYTE PTR DS:[EAX+010003000h]
XOR CL,075h
MOV BYTE PTR SS:[EBP+EAX+0FFFF13E0h],CL
INC EAX
CMP EAX,ESI
JL @appmgmt_10001443

Then it allocates some space and copies its decrypted code there by calling function at 1000149E. On my machine these code is located at 000A1980. Then it calls CreateThread() to start the decrypted code. We can now set a breakpoint on 000A1980 to analyze it. In the decrypted code, the first loop is a second layer of xor decryption:

000A198C: ADD EAX,11
000A198F: XOR BYTE PTR DS:[EAX],6C
000A1992: INC EAX
000A1993: INC ECX
000A1994: CMP ECX,789C
000A199A: JNZ SHORT 000A198F

After tracing with F7 we will reach a third loop:

000A1BD5: INC ECX
000A1BD6: LODS DWORD PTR DS:[ESI]
000A1BD7: ADD EAX,EBP ; kernel32.7C800000
000A1BD9: XOR EBX,EBX
000A1BDB: MOVSX EDX,BYTE PTR DS:[EAX]
000A1BDE: CMP DL,DH
000A1BE0: JE SHORT 000A1BEA
000A1BE2: ROR EBX,0D
000A1BE5: ADD EBX,EDX
000A1BE7: INC EAX ; kernel32.7C804B9C
000A1BE8: JMP SHORT 000A1BDB
000A1BEA: CMP EBX,DWORD PTR DS:[EDI]
000A1BEC: JNZ SHORT 000A1BD5

Within this loop the malware finds the address of VirtualAlloc() and puts it on EAX then it calls EAX straight away.

000A1C04: PUSH 40
000A1C06: PUSH 1000
000A1C0B: PUSH DWORD PTR DS:[EDI+4]
000A1C0E: PUSH 0
000A1C10: CALL EAX
000A1C12: PUSH EAX
000A1C13: PUSH EAX
000A1C14: ADD EDI,8
000A1C17: PUSH EDI
000A1C18: CALL 000A19A1

After the call to EAX there is another call, after analyzing that I’ve found out that McRat decrypts another part of it code and copies them to an address obtained through a call to VirtualAlloc() and then it jumps there:

00BC0000: CALL 00BC0015
00BC0005: CMP AL,0
00BC0007: ADD BYTE PTR DS:[EAX],AL
00BC0009: SUB AL,4
00BC000B: ADD BYTE PTR DS:[EAX],AL
00BC000D: POP SS ; Modification of segment register
00BC000E: MOV EDI,10000000
00BC0013: INC EAX
00BC0014: ADD BYTE PTR DS:[EBX+55],BL
00BC0017: MOV EDX,DWORD PTR DS:[EBX]
00BC0019: MOV ECX,DWORD PTR DS:[EBX+4]
00BC001C: MOV EAX,DWORD PTR DS:[EBX+8]
00BC001F: MOV EBP,DWORD PTR DS:[EBX+C]
00BC0022: ADD EBX,EDX
00BC0024: SUB EBX,5
00BC0027: LEA ESI,DWORD PTR DS:[EBX+ECX*4]
00BC002A: SUB EBP,ESI
00BC002C: PUSHAD
00BC002D: MOV EDI,DWORD PTR DS:[EBX+ECX*4-4]
00BC0031: SUB DWORD PTR DS:[EDI+ESI],EBP
00BC0034: LOOPD SHORT 00BC002D
00BC0036: POPAD
00BC0037: POP EBP ; 000A1C2E
00BC0038: ADD EAX,ESI
00BC003A: JMP EAX

Again, another decryption routine, in this case by substitution. After jumping to EAX we get to the code below:

00BCD003: PUSH EBP ; kernel32.7C800000
00BCD004: MOV EBP,ESP
00BCD006: CALL 00BC6352
00BCD00B: TEST EAX,EAX
00BCD00D: JNZ SHORT 00BCD014
00BCD00F: OR EAX,FFFFFFFF
00BCD012: JMP SHORT 00BCD062
00BCD014: PUSH 2
00BCD016: CALL DWORD PTR DS:[BC2E00]
00BCD01C: CALL DWORD PTR DS:[BC2DFC]
00BCD022: MOV DWORD PTR DS:[BCF49C],EAX
00BCD027: PUSH 0
00BCD029: PUSH 0
00BCD02B: PUSH 0
00BCD02D: PUSH 0BCCDE0
00BCD032: PUSH 0
00BCD034: PUSH 0
00BCD036: CALL DWORD PTR DS:[BC2D08]
00BCD03C: PUSH 0
00BCD03E: PUSH 0
00BCD040: PUSH 0
00BCD042: PUSH 0BCCD16
00BCD047: PUSH 0
00BCD049: PUSH 0
00BCD04B: CALL DWORD PTR DS:[BC2D08]
00BCD051: CALL 00BCD1EC
00BCD056: CALL 00BCCDAA
00BCD05B: CALL 00BC6470
00BCD060: XOR EAX,EAX
00BCD062: POP EBP ; kernel32.7C80B713
00BCD063: RETN

If you notice, imports are redirected, of course it’s a simple redirection and you can easily find those APIs by hitting F7 for 5-6 times. In the second part we will analyze the main behavior of McRat and its network activity.

Best Regards hepL3r