Recently published blog posts:
Go to the blog archive and browse all previous blog posts
we have published so far.
Subscribe to the GovCERT.ch blog RSS feed to stay up to
date and get notified about new blog posts.
Recently published whitepapers:
Subscribe to the whitepapers RSS feed to stay up to date
and get notified about new whitepapers.
Report an incident:
The following email address can be considered as point of
contact for FIRST members and other
Alternative GovCERT.ch PGP Key (for older versions of PGP without Curve25519 support)
Published on September 11, 2015 08:00 UTC by GovCERT.ch (permalink)
Last updated on November 26, 2015 09:07 UTC
Some weeks ago we read an interesting blog by Malwarebytes about Fobber, a new e-banking focussed malware in the arena that seems to be a Tinba spinoff. We decided to have a closer look at it to find out whether Swiss critical infrastructures are targeted by it. We'd like to share our findings with you, because it contains some interesting advanced techniques that at the same time are implemented in a comparably simple way; we think this makes Fobber an ideal case study.
From a technical point of view, one of the more interesting features we'll look at in the paper is the technique used even after the initial unpacking stage. Around 70 functions are protected by this mechanism that keeps the content in encrypted form until it's actually called - with a granularity level of the function itself. It won't be decrypted before it's actually called, and as soon as the function returns, the code will be re-encrypted using a new, random key. Decryption and re-encryption are crafted in a transparent way that makes it simple to add it to already compiled code; the only precaution to be made in the original code is to leave some unused bytes at the start and a few bytes at the end. The re-encryption function even implements an emulation of a correct return instruction for the stdcall calling convention:
This mechanism ensures that the code is never visible in decrypted form as a whole at any given point in time. This makes most automated analysis method using memory snapshots ineffective and also ensures that the full memory content does not "look like" code if statistical heuristics for code detection are applied. Special data concerning the decryption are stored in a per-function header that also supplies a mutex protection to avoid parallel decryptions of the same function by different threads, as well as a a counter to keep track of the recursion level (so it is not decrypted twice when a function calls itself recursively). Said all that, the encryption algorithm itself is rather simple - not much more than a cyclic XOR that preserves the original function length; this makes it interesting as a scholarly example for demonstrating such a technique in action.
Another interesting, though not highly sophisticated feature is the fact that the code is completely position independent and does not require import tables or any additional data segment; in other words, it is fully self-contained - a typical feature of shellcode. It uses a special register (EBX) as a "global frame pointer" to keep an anchor to its own position in the address space. Additionally, when constant data (like strings) needs to be pushed on the stack as an argument for a function, a "fake" call to the next code interweaved with data in between is used. This is actually the same as pushing a pointer to the data onto the stack followed by a jmp. Such the code is position independent and additionally confuses disassemblers like IDA Pro quite effectively because such a call instruction has nothing to do with a function call. In the case of strings, this is most times combined with a string decryption function - once more, the strings will never all be visible in memory simultaneously.
For imports, fobber scans through loaded modules, finds function by calculating hash values over function names. From this, it builds its own IAT structure, which is different from a normal IAT structure known from the PE format.
The paper will also have a look at the encryption of the configuration file (embedded in the binary, or updated by a C2) and the domain name algorithm. Here some MD5s of fobber samples we examined - they all seem to be from the same campaign (we don't know if there even is more than one campaign) as they share the encryption key:
So far, we are not aware of any financial institutions in Switzerland being targeted by Fobber. However, we will continue to monitor this threat and will update our blog post if anything changes.
The whitepaper with our full Fobber analysis can be found in the whitepaper section:
Back to top