FinFisher Malware Dropper Analysis

  • Posted on: 19 September 2014
  • By: siteadm

Hey, 

As you may have heard, recently Finfisher malware sample leaked online. As I got a little free time today, I decided to take a look at it. Sample I'm going to analyze in this article is finfisher1.exe.bin:

MD5: 074919F13D07CD6CE92BB0738971AFC7 

SHA: 9F9A18E81E9B39BD2F047004B8E3B4CB0FB505C9

So, at first glance, I noticed it's written in C++ and compiled using Visual Studio 2005. No packer/crypter/obfuscator has been used. So far, FinFisher's performance is disappointing.

Anyway, when you check program's entry point at 0x4029B9, after initializations, it calls WinMain function which is located at 0x00401648. In this function, there is several calls, which some of them are quite interesting. Anyway, first function being called here is the 0x00402369 function. 

This function, does something that I've never seen in any other malware sample I've analyzed, possibly it has been used by other malwares too, but to me, it's first time. This function, simply calls GetModuleHandleW with NULL as parameter to get handle to current module. Then it locates IAT (Import Address Table) of it's own file. From here it searches for user32.dll entries in it's own IAT. When it finds user32.dll IAT entries, it loops through imported functions from User32.dll. It loops through this table until it locates two function addresses: a) RegisterClassExW b) CreateWindowExW

When it resolves address of these two imported APIs, it calls VirtualProtect and makes address variable (DWORD) location writable:

VirtualProtect(CreateWindowIATEntryAddress, 0x04, PAGE_EXECUTE_READWRITE, &pOld);

FinFisher does this for both CreateWindowExW and RegisterClassExW API address locations in IAT of it's own file. Then subsequently it modifies value of both API addresses to 2 new addresses:

RegisterClassExW address will be set to => 0x4019EF

CreateWindowExW address will be set to => 0x00402228

Now, Ollydbg and IDA Pro, both can't handle this and both of them during entire analysis, when there is a call to CreateWindowExW, will think it's actually a call to CreateWindowExW, but in fact it isn't. It's a call to 0x402228. Fun part is, FinFisher malware simulates exactly ALL required functions to call CreateWindowEx, so Ollydbg successfully parses parameters and it looks totally legit (other than setting window's X parameter to 0x80000000).

It does exactly same for CreateWindowExW:

Function 0x402369 does all these modifications, later FinFisher calls function 0x004015CB, here at first glance it looks totally innocent, you'll notice calls to LoadCursor, LoadIcon, and then RegisterClassExW, so it should be innocent, shouldn't it?

But no, it's not! As you can see Ollydbg still thinks it's a call to RegisterClassExW, I also removed analysis from file, but still Ollydbg thinks it's a call to RegisterClassExW, same with IDA Pro, but in fact, devil is in details:

If you look closer, you'll see that real address that will be called is 0x004019EF, not RegisterClassExW !

OK! We continue to debug by going to 0x4019EF function, here FinFisher, simply gets %TEMP% folder path, then generates a random name, creates a new folder in %TEMP% like: %TEMP%\TMPXXXXXXXX, then it copies current file as it is with same name into this folder and returns, nothing important here.

As next step, function 0x0040145 will be called. This one also looks totally innocent and looks like it does have legit call to CreateWindowExW and that's it. But it's not. Again, Olly reconstructs call parameters to CreateWindowExW and it looks totally legit, again devil is in details, look at address of real function being called here, it is 0x402228, not CreateWindowExW!

When we follow application and move to 0x402228, we notice that it creates a new process, using file copied to TEMP folder as ModuleFileName, important point is, it creates this process in suspended mode using CREATE_SUSPENDED flag. This way, process will be created, but it will not run until ResumeThread being called. Now second interesting this about FinFisher malware is here. 

FinFisher here calls GetThreadContext to receive information about suspended process. Then it locates EIP of suspended process and changes it to 0x00401E1F. This simply modifies program's flow, so later, when ResumeThread called, program will not run the same as original file, even thought it's same code. Instead, because of change in EIP, it will simply jump to 0x00401E1F as EP (Entry Point). This is second interesting trick.

Later it calls WriteProcessMemory two times and each call have a special purpose. First call, writes current running EXE path exactly to location of a TCHAR variable in suspended child process, so when suspended thread resumes it's operation, it will see it's parent's EXE file path in one of it's variables. See:

Then it calls GetCurrentProcessID, subsequently calls OpenProcess to open it's own process. Finally it calls DuplicateHandle with DUPLICATE_SAME_ACCESS flag and current process handle as hSource parameter. Then it writes result of duplicate handle into suspended process memory, into same location using WriteProcessMemory and finally calls ResumeThread and terminates itself.

From here, we continue debugging in child process which it's EIP is now 0x00401E1F.

As first step, child process, reads duplicated handle (caller process handle) and waits for it to terminate, then it closes duplicated handle and deletes the original file:

Now, after some initializations and calling Virtualprotect on 0x004198BC with PAGE_EXECUTE_READWRITE flag, it jumps to 0x00402662, which is where it decodes and writes main malware file.

Here is decryption loop:

It's simply XORing 4 byte to it's next 4 byte until end of the data.

Data before decryption:

Data after decryption:

Then, again it calls same decryption function, but this time it will decrypt the embedded JPEG file in it.

Before JPEG decryption:

After JPEG decryption:

Finally it writes the JPEG or any embedded file in location of original main file but without .EXE extension, instead it uses real extension of embedded file, here is switch code to find out required extension for embedded file:

So if your original file was in C:\Test\Test.exe, now you'll get C:\Test\Test.jpeg, seems legit, isn't it?

Finally it writes decrypted main payload of malware into TEMP folder with original filename (if your app was Test.exe, it will create %TEMP%\Test.exe) and execute it using ShellExecuteW API. It also opens JPEG file using ShellExecuteW API.

This is it! I finished analyzing FinFisher dropper and extracted main payload. Next time I get free time, I'll analyze main code. So far, FinFisher disappointed me... C'mon FinFisher, "50M EURO! company's trojan" should be better.

Comments

I like your articles, keep up the good work! I love screenshots you invlude too

Excellent article indeed!

This method is called self IAT hooking, it's old and known method. Anyway, nice post!

Did you observe the rootkit? The Finfisher exe drops one.

Yes, as I said in this article it's dropper part analysis only and yes I got decrypted main module out of dropper. Next time I get some free time I will analyze main module and I will write a new article here.

Really obsolete finfisher just for kids. Really a waste of money for government jajaaa

U go to need too much time, all finfisher is into a vm. Luck

I described that way of spawning a process from memory buffer over at SO nearly 6 years ago (http://stackoverflow.com/questions/305203/createprocess-from-memory-buff...). The reference is dead but the technique still works.
Take a look at the Godel payload, basic implementation of the Advanced Software Protection Now by Diego Bendersky et al. (http://corelabs.coresecurity.com/index.php?module=Wiki&action=view&type=...).
The bottom line probably is that the *cough* good guys *cough* seem to be at least 8+ years behind the academic state-of-the-art, not to mention what can be bought for a huge pile of money?

great work!

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.