Last week the Carberp source code has been leaked, and we got it. This was the occasion to analyse a nice piece of malware.
One of the multiple modules of Carberp is called anti_rapport, this is a module able to (in theory) inject itself in Internet Explorer”s memory to remove Trusteer rapport protection by unhooking API calls and suspend rapport”s threads. I will also forbid any thread related to rapport dll to get a handle on any module of the process.
Here”s the global flow of the source code:
The module is divided in 2 parts. The dropper (exe file) and the DLL. Both parts belong to the same file, but they are related to different parts in the flow.
The dropper is responsible for copying itself to a temp file, then modify that copy to turns its characteristic flag into DLL. That way, it can be injected as module into processes. Once the DLL is ready, it reads iexplore.exe memory (Mapping) and copies a shellcode right after the Section headers of its loaded ntdll.dll module.
The Shellcode is basically only a LoadLibrary, which will trigger the Main routine of the injected DLL into the process”s context.
mov eax,0x11111111//pShellData->bLock (stored in process) in EAX
xorcl,cl//clear CL flag
cmp byteptr[eax],cl//if bLock = 0 => Exit
mov byteptr[eax],cl//Set bLock = cl = 0
inc eax//move EAX ptr on pShellData->chDllName
push eax//pShellData->chDllName on stack
mov eax,0x22222222//LoadLibraryA addr in EAX
call eax//Call LoadLibrary
mov eax,0x33333333//pShellData->ucOldBytes (stored in process) in EAX
jmp eax//Jump to stolen bytes (old address of splicing)
Once the shellcode copied into loaded module, the dropper will rewrite the first few bytes of ZwClose (in ntdll) to jump to the shellcode (Splice). So at any attempt to ZwClose (which occurs quite often) from iexplore.exe, the DLL will be loaded in memory and trigger the main routine (in process”s context).
Dll injected into iexplore.exe:
The DLL is responsible (once injected) for removing every hook made by a protection DLL, stop any thread from “rapport” DLL, and forbid “rapport” DLL to call GetModuleHandleW in kernel32.dll
To remove protection made by a security product into Internet Explorer, the anti_rapport will look for hooks in specific modules (ntdll.dll, kernel32.dll, mswsock.dll, ws2_32.dll, wsock32.dll, wininet.dll, user32.dll and gdi32.dll), and remove them.
To perform hook removal, the DLL will simply reload the DLL into another memory space, parse Export tables (one for the new loaded DLL and one for the existing one) and compare addresses. If some of them mismatches, it will restore to initial value.
To stop rapport threads, the module only enumerate process”s threads, then call NtQueryInformationThread with ThreadQuerySetWin32StartAddress value to get the threads”s entry point address, then it calls GetMappedFileName to get the module name related to the thread”s entry point.
That way it”s able to retrieve the module where a thread is based. To finish, it filters that name and calls ResumeThread only on those who are authorized to run (It has previously suspended the whole process with NtSuspendProcess)
To avoid Security products to access any part of the process, and be able to check for malicious hooks, the anti_rapport will detour GetModuleHandle API and filter any attempt to access a loaded module.
The hook is made with classic splicing, which consists to insert a JUMP at the beginning of the function (in memory). It”s way better than IAT hook (which replace the address of the function in IAT table) because not visible except if we scan lot of the process”s memory.
Here, the hook is not seen in TaskSTRun (But I know it’s here 🙂 ):
By loading the infected process into a debugger, and looking at the address (0x7C80E4DD) of the function (in ntdll), we can see the detour code:
That jump leads to the detour function, which looks like this:
It”s just getting the caller of the function and the caller of that caller (with RtlGetCallersAddress), and checks if one of them is coming from any “rapport” DLL. If this is the case, the function will return NULL (and thus will forbid that caller to get the needed handle), otherwise it returns the original function.
By doing this, a security product that needs to get a handle on a module to scan it (for signatures, or to check the IAT table) will be rejected and will not be able to scan it.
Do not forget that module is part of a huge malware, Carberp. This malware is able to steal bank informations by watching the web browser. One major problem for them was to go stealth and remain into that web browser, even with security products guarding it.
That module has clearly being developed to kill Trusteer rapport product, and keep their product functional and undetected.
Trusteer claims their product has resisted to this, so that”s a good point 🙂 . However, even if the anti_rapport code contains hard-coded name about the rapport module of Trusteer, it”s quite generic and can be adapted for any security product that use wide DLL injection to guard web browsers.
I’ve tested the module against Rapport, and it seems to be bypassed. I don’t know if it really protects or not, but every feature of the anti-rapport module has been loaded and is functional. I was able to inject the DLL into iexplore.exe (with rapport loaded), to hook GetModuleHandleW, and to filter DLL calls. Trusteer has been contacted, I hope they will either give me more information or fix this. This is severe issue, as this malware is in the wild for years, and now because the source code has been leaked and will be used in many new malwares. See screenshots below.
Anti rapport module is injected into iexplore.exe (rapport is loaded)
Rapport DLL calls are filtered out by the anti-rapport module and cannot access to process’ modules handles
Trusteer, after a fast reply told me they had fixed it. So I updated their software, and retried start the anti-rapport binary.
Now, the module is able to inject itself in Internet Explorer, and splice the API, but it seems unable to resume some useful threads, related to core application. As a consequence, Internet Explorer behaves like it was hanging, and does not responds anymore. This is really better, for several reasons.
The user is alerted that something is going wrong, and can maybe query some help on support forums.
The user is unable to start banking sessions, and thus the malware cannot grab its informations.
I would like to thanks Trusteer for their quick answer and fix, and for their valuable support guys.