A couple of weeks ago, Citizen Lab announced the discoveryof the mobile component to the previously discovered FinFisher Toolkit (Reference Here).In this reveal, they talk about the many mobile variants, and a number ofcomponents included in each. Surveillance, file exfiltration, locationtracking, and communication with the spyware's headquarters are but a few ofthe many pieces of functionality this spyware has. So as I'm reading theirwrite-up (great job again guys), I find myself looking at the section thattalks about how the Android variant's configuration is created.
The raw hex from their example above certainly shows a fewinteresting tidbits of information, such as phone numbers and domain names, butwhat does it really mean? How does the configuration get parsed andsubsequently read? Well, I finally got my hands on a FinSpy sample for Androida short while back, and decided to jump in and find the answers to myquestions.
Before I jump into parsing the configuration itself, it'sinteresting to know how it gets generated. So essentially the FinSpy sample hasall of these blank, embedded *.dat files inside of it. Two hundred empty filesinside of it to be precise. Most would probably think that these files wouldlater get populated upon execution of the malware, or at the very least, be used in some way. I know I certainly thought so originally.However, it's not the files themselves that end up getting used by FinSpy, butthe file headers that reside in the FinSpy APK sample. Specifically, themalware is using the internal file attributes, and the external file attributesfor every *.dat file present.
You might be confused right now. Don't worry; I'll do mybest to explain. So, if we look at the ZIP file format (All APKs are ZIPs), wecan see that each Central Directory Structure (CDS) entry begins with a 4-byteidentifier (Documentation Here)of '50 4B 01 02' (or 'PK\x01\x02'). Sure enough, if we look at the FinSpysample, we can see this towards the end of the ZIP file.
Based on the documentation, we can see that the 'Internalfile attributes' begin at offset 0x24, or 36 decimal. The Internal fileattribute is a word, or two bytes. We then see that the 'External fileattributes' begin at 0x26, or 38 decimal. This attribute is a dword, or doubleword, and has a size of four bytes. So in total there are six bytes of datawhen these attributes are combined. So, let's see what the malware has for eachfile's attributes:
Well, look what we have here. These certainly don't looklike any internal or external file attributes to me. So essentially, what ishappening is the malware authors have written over the original values withtheir own data. The malware, upon execution, looks at each file's internal andexternal attributes in the ZIP file, and concatenates them. This leaves youwith a string that looks something like this:
OK, so now the real fun begins—What does this data mean!?Well, if we start to inspect it, we can start to find some patterns. Let'sstart at the beginning. If we look at the first four bytes, we see a value of01 02 00 00. If we treat this as little-endian, it gives us a value of 00 00 0201, or 0x201. Converted to decimal, we get a value of 513. If we look at thetotal size of the configuration file, we see that is is 514 bytes long. Nottotally exact, but who knows, maybe it's not just a coincidence. As wecontinue, we start to see more and more DWORDs that may in fact be 'size'values. I've demonstrated this in the following gif animation:
So maybe those values are in fact sizes. The next questionis, what is the data inside of each section within the configuration file? Itappears as though each size DWORD is followed by another DWORD of some unknownvalue. If we convert the first two that we see (90 FB FE 00 and A0 33 84 00),and treat them as little endian values, we get 16669584 and 8663968respectively in decimal. So what are these numbers? Well, the answer to thisquestion lies in the FinSpy sample itself. If we decompile the underlying Javacode, we see a large lookup table that has a number and its associated name.
Using this information, we can lookup the numbers wepreviously identified and get "TlvTypeMobileEncryption" and "TlvTypeMobileTargetOfflineConfig"respectively. The only remaining question to answer is what is the datafollowing these parameters? Well, at this point we've stumbled on the data ofthe configuration itself. So at this point we've determined that theconfiguration file has the following structure:
Where DATA can potentially be another 'section' of theconfiguration file. A full breakdown of this configuration can be seen below:
At this point we can start painting a pretty decent pictureabout what the malware does, even without digging too greatly into the sampleitself. Values such as 'TlvTypeConfigTargetProxy' and 'TlvTypeConfigTargetPort'tell us that we will be connecting to some host on one of any number of portsspecified here. 'TlvTypeMobileTrackingConfig' allow us to see that this malwarehas capabilities to track the victim device's location.
Going a step further, we can take all of the knowledge we'vegained up to this point and completely parse the configuration of FinSpy, asshown below:
Since I'm such a nice guy, I decided to provide a few tools (somethat have been seen in this blog post) to make your life easier (if you happento be playing with an Android FinSpy sample). You can find the following threeruby scripts on SpiderLab's github page:
- extractConfig.rb – Tool to get the rawconfiguration from a FinSpy sample.
- parseConfig.rb – Tool to parse the previouslyextracted configuration file.
- writeConfig.rb – Write a new configuration to aFinSpy sample.
All files can be found in the following location: https://github.com/SpiderLabs/Malware_Analysis/tree/master/Ruby
So, let's wrap this up. What did we find and what did wesee? Well, overall I think you'll agree that by parsing out the configuration(as opposed to just viewing it in a hex editor), it provides a much greaterdegree of insight into both the information present, as well as the decisionsmade by the authors. In truth, a very similar technique is used to format datagoing across the wire via TCP communications, but that's a post for anothertime perhaps. Additionally, the 'types' that were discovered in the Androidbinary shed quite a bit of light as to the overall functionality of theSpyware. In summation, I hope you were able to get some insight about reversingthis configuration file along with the Android FinSpy family in general.