Defeating mTANs for profit – part two


Axelle Apvrille

Fortinet, France

Kyle Yang

Fortinet, Canada
Editor: Helen Martin


Until recently, malware on mobile devices had not been used for organized crime involving large amounts of money. This changed when the infamous Zeus gang, known for targeting online banking, started to show a clear interest in infecting mobile phones and released a new version of their bot to propagate a trojan for mobile phones. Axelle Apvrille and Kyle Yang present an in-depth analysis of the Zitmo trojan.

Until recently, malware on mobile devices had not been used for organized crime involving large amounts of money. This changed when the infamous Zeus gang, known for targeting online banking, started to show a clear interest in infecting mobile devices and released a new version of their bot to propagate a trojan for mobile phones.

This two-part series (based on a paper presented at ShmooCon 2011) presents an in-depth analysis of the Zitmo trojan. Last month [1] we presented some background information on Zeus and mobile malware and looked at how the attack behind Zitmo works. In this article we will present our reverse engineering of Zitmo and attempt to draw lessons from the attack, as well as suggesting methods for circumventing it.

1. Zitmo for Symbian

The Zitmo package consists of a few resource files and an executable named NokiaUpdate.exe. The resource files are typical to Symbian applications – such as the resource in c:\private\101f875a\import, which is used to automatically restart an executable after the phone reboots – and are of little interest for the purpose of reverse engineering. NokiaUpdate.exe is more interesting, however. The .exe file centralizes all malicious functionalities in a single daemon, and this is what we analyse.

1.1 Initial tasks

The first time NokiaUpdate.exe is run after installation it sends an SMS to +44778148xxxx with the text ‘App installed ok’. Both the text and the phone number are hard coded, hence easily locatable in the malware’s strings. (As for most Symbian OS 9 executables, NokiaUpdate.exe must first be uncompressed before searching for strings.) To ensure that no SMS will be sent the next time the .exe file is run, the file c:\20022B8E\firststart.dat is created and used as a flag. The presence of the file indicates that the trojan has already been launched; if it is absent, an SMS should be sent.

During the first start-up, the trojan also creates an SQL database (c:\20022B8E\Numbers.db) containing three tables: tbl contact, tbl phone number and tbl history, as depicted in Table 1, Table 2 and Table 3. The contact table lists contacts to spy on. Only the first column, the index, is used by Zitmo. The other columns probably refer to the name descriptions of the contacts and their indexes in the phone’s address book (if listed there). The phone number table sets the relationship between contact indexes and their phone numbers. The contact id column corresponds to the index column of the contact table. Finally, the history table stores events related to those contacts such as incoming calls.

index 32-bit integername 16-bit Unicodedescr 16-bit Unicodepb _contact_id 32-bit int
1not usednot usednot used
2not usednot usednot used

Table 1. Example of contact table.

contact id 32-bit intphone number 16-bit Unicode

Table 2. Example of phone number table.

event id 8-bit intpn id 32-bit intdate typedescription 16-bit Unicodecontact info 16-bit Unicodecontact id 32-bit int
1 27-10-2010  2

Table 3. Example of history table.

1.2 Listening to incoming SMS messages

Once the initial set-up is complete, the trojan listens for incoming SMS messages. To do so, it uses the technique described in [2], i.e. it opens and binds a socket to the SMS channel. The Symbian APIs provide several ways to open SMS sockets, such as receiving anything (ESmsAddrRecvAny), receiving messages that start with a special prefix (ESmsAddrMatchText), or using a special port (ESmsAddrApplication8BitPort) to receive messages. Since opening an SMS socket to receive all messages is not possible because the phone’s built-in applications are already using this method, the trojan uses ESmsAddrMatchText but with a special trick (see Figure 1): it specifies that the incoming messages to receive must begin with nothing. This method works and actually receives all incoming SMSs. Note this trick has also been explained in [3].

Assembly code to intercept all incoming SMS messages.

Figure 1. Assembly code to intercept all incoming SMS messages.

In this article, ARM assembly listings are all taken from Zitmo. They use the following convention: functions beginning with ‘NokiaUpdate’ have been named and reverse engineered by us, functions beginning with ‘ZN’ have automatically been resolved by IDA Pro: they correspond to standard Symbian API calls. Other functions, starting with ‘sub’, are usually not very relevant and have not been reversed. Lines starting with a semicolon are comments.

Each time the mobile phone receives an SMS, the trojan’s socket intercepts it (before it reaches the phone’s inbox). It reads its content in the socket (RSmsSocketReadStream class in the API) and processes it.

An explanation of SMS processing is illustrated in Figure 2. The trojan checks who has sent the incoming SMS. There are three cases:

  1. Sender is monitored. If the SMS comes from a phone number the trojan is configured to monitor (i.e. if the phone number is specifically mentioned in the trojan’s phone number table, or if the trojan is configured to monitor all incoming numbers), the SMS is diverted to the administrator’s phone number (see Figure 3). The victim will never see this SMS in his inbox.

  2. Sender is administrator. In this case, the trojan parses the message body for a known command and processes it.

  3. Sender is neither monitored nor administrator. This happens when the victim receives an SMS from somebody the malicious gang does not care about (in which case the SMS is released to the victim’s inbox – the fact that the victim receives some SMS messages helps reduce suspicion) or, in other cases, when the administrator’s phone number changes. In this case, the administrator can send a SET ADMIN command from the new administrator phone. In fact, we believe this is a flaw in the trojan’s protocol and will explain later how we have abused it. Note that the SET ADMIN command is the only one a non-administrator can send.

How Zitmo processes incoming SMS messages.

Figure 2. How Zitmo processes incoming SMS messages.

SMS intercepted by Zitmo and forwarded to the administrator (lab test phone).

Figure 3. SMS intercepted by Zitmo and forwarded to the administrator (lab test phone).

1.3 Remote SMS commands

Zitmo implements 10 different commands: ON, OFF, SET ADMIN, ADD SENDER ALL, ADD SENDER xx, REM SENDER ALL, REM SENDER xx, SET SENDER xx, BLOCK ON, BLOCK OFF. All of these have been described either in [3], [4] or in our previous work [5]. What hasn’t been explained yet is how the trojan recognizes the commands in the SMS and processes them.

Basically, the trojan reads the SMS body, converts it to upper case and counts the number of spaces in order to work out the number of words in it. If there are no spaces, the only likely commands are ON or OFF. If there is one space, the only possible commands are BLOCK ON or BLOCK OFF etc. (see Figure 4). This is rather a strange way to recognize commands, and is perhaps copied from a more sophisticated library.

How Zitmo parses SMS commands.

Figure 4. How Zitmo parses SMS commands.

Once the trojan knows which command it is dealing with, it must react. Its immediate action always consists of updating its settings and/or updating the contact and phone number tables (ADD SENDER, REM SENDER and SET SENDER commands). Later, the effective behaviour of the trojan relies only on those two parameters.

The trojan’s settings are dumped in c:\20022B8E\settings2.dat. The format of the file is the following:

  1. The first byte represents the state of the trojan: 0 if it is off, 1 if it is on (enabled).

  2. The second byte represents the monitoring case: 0 to monitor phone numbers specified in the table, and 1 to monitor any numbers (in the case of ADD SENDER ALL).

  3. The third byte represents the blocking state: 0 if calls must not be blocked and 1 if they must be blocked (BLOCK ON/OFF).

  4. The remaining bytes correspond to the externalized 16-bit Unicode string object (TDesC16) for the administrator’s phone number.

For example, the settings of Figure 5 correspond to a disabled trojan (OFF), configured to steal any incoming SMS messages (ADD SENDER ALL) and let incoming calls go through (BLOCK OFF). The administrator’s phone number is +44778148xxxx.

Zitmo’s initial settings file.

Figure 5. Zitmo’s initial settings file.

For the ADD SENDER, REM SENDER and SET SENDER commands, the trojan also updates the contact and phone number tables with the phone numbers specified in the rest of the command. For example, ADD SENDER 1234567890 creates a new row in the contact table for index 2 (see Table 1). In the phone number table, a new row is added too, and index 2 is mapped to phone number 1234567890 (see Table 2). The other columns are not used in Zitmo.

1.4 SMS actions

In the end, there are only three different outcomes for an SMS received by the trojan: release the SMS to the victim’s inbox, divert it to the administrator’s phone number or just drop it. This is how the trojan does it:

  • Releasing the SMS actually consists of creating a new SMS message in the phone’s inbox. To do this, the trojan first switches to the inbox entry (SwitchCurrentEntryL specifying the inbox KMsvGlobalInboxIndex-EntryIdValue – see Figure 6).

    Code to switch to global inbox entry.

    Figure 6. Code to switch to global inbox entry.

    In Symbian, each entry (CMsvEntry object) consists of generic information (e.g. subject, date) held in a TMsvEntry object, and message-type specific data (e.g. headers, body) in a CMsvStore object [6]. So the trojan first copies the generic information to the entry and then marks the change (CMsvEntry::ChangeL).

    Then, it copies the SMS headers and body to the entry’s store. It must make sure the header is marked as an SMS to deliver (ESmsDeliver – see Figure 7) so that it appears as a message coming from the sender (and not to the sender).

    Setting SMS as ‘to deliver’.

    Figure 7. Setting SMS as ‘to deliver’.

    Finally, it commits the change (CommitL). Note also that if the message to release comes from a contact listed in the phone’s address book, the trojan opens the address book, searches for the contact whose phone number matches the sender of the SMS, retrieves the contact’s first and last name and writes this information in the inbox, instead of the phone number. This ensures, for instance, that the SMS appears to come from ‘Axelle Apvrille’ and not from ‘+336xxxxxx’.

  • Diverting the SMS to the administrator’s phone number is quite similar, except a new entry is created in the Drafts box. And, of course, the new SMS is created with the administrator as recipient, and the body is modified to include at the end the phone number of the original sender of the SMS (see the result in Figure 3: the original sender’s phone number is mentioned after ‘Fr:’). The trojan then marks this entry as changed (CMsvEntry::ChangeL – see Figure 8), sets the SMS service centre and finally sends it.

    Adding the sender’s phone number to the body of the SMS.

    Figure 8. Adding the sender’s phone number to the body of the SMS.

  • Dropping the SMS (i.e. not displaying the SMS at all) basically consists of doing nothing with the SMS once it has been read. More precisely, the trojan reads the SMS from the SMS socket, processes it and decides it must be dropped, does not commit any new entry on the phone’s message server, and makes sure it marks the socket message as successfully processed (as in the two other cases) – see Figure 9. It is important to mark the SMS PDU as successfully processed or it will reappear in the inbox on the next reboot.

    Call RSocket::Ioctl with KIoctlReadMessageSucceeded to indicate the message was processed correctly.

    Figure 9. Call RSocket::Ioctl with KIoctlReadMessageSucceeded to indicate the message was processed correctly.

1.5 Reverse engineering techniques

Symbian malware is typically reverse engineered using static code analysis. IDA Pro is particularly handy for Symbian because it supports ARM assembler and automatically resolves most Symbian API calls. Static code analysis represents a high percentage of our reverse engineering for Zitmo, but in addition, we have been able to use two other techniques:

  1. Spoofing the administrator. As mentioned previously, the trojan’s protocol to configure a new phone number for the administrator is flawed, because anybody can claim to be the new administrator, provided their phone number is not currently being monitored. So, for our experiments, we used two phones: one infected by the Zitmo malware, and the other one to act as the administrator (instead of the real Zeus gang). There are two ways to become the new administrator. The simplest way we found was to send a ‘set admin’ command (due to a bug in the trojan the command must be in lower case) with the phone number of our second phone. The more complicated way consisted of crafting a settings file with the new administrator’s phone number (for example, replacing the phone number at the end of the code in Figure 5). The settings file is located in a private, restricted directory though, so it is necessary first to install a hack on the phone [7] to access the directory.

    Once we had set up our phone as the new administrator, it was much easier to understand the code of the trojan: set up remote debugging of the device, send a command by SMS and step through the assembly line by line. For example, in Figure 10, we are debugging, step by step, the function that adds a new contact to the trojan’s database for monitoring.

    Screenshot of IDA Pro during a remote step debugging of the trojan. In this case, the function is adding a new row to the phone number table of the trojan.

    Figure 10. Screenshot of IDA Pro during a remote step debugging of the trojan. In this case, the function is adding a new row to the phone number table of the trojan.

  2. Unhiding the console window. Static analysis of the trojan reveals that it actually creates a text editor window and writes debug information to it. Under normal circumstances, this debug window is not shown because the malware authors have hidden it: basically, this consists of setting the window as hidden (CApaWindowGroupName::-SetHidden( ETrue )), and making sure the window stays in the background (RWindowTreeNode::Set-OrdinalPosition to ECoeWinPriorityNever AtFrom=-1000 or ECoeWinPriorityNormal=0). See [8] for more information. So, to show this debug window, we set breakpoints to the SetHidden and SetOrdinalPosition API calls, ran until we reached those breakpoints, and then each time we reached SetHidden, we modified ETrue (=1) to EFalse (=0) and each time we reached SetOrdinalPosition, we set the priorities to ECoeWinPriorityAlways-AtFront =1000 = 0x3e8. This caused the debug window to appear.

    Figure 11 shows the debug window after the trojan has read its settings. First, there is the administrator’s phone number (blurred – a test phone in our lab). Then we see the trojan is enabled, monitoring any incoming number, and incoming calls are not blocked. Finally, the last few phone numbers are those listed in the phone number table (partially blurred). We added those phone numbers to our test phone using the relevant ADD SENDER commands. They are ignored because the trojan is configured to monitor all incoming numbers.

    Zitmo’s debug window dynamically sent to the foreground.

    Figure 11. Zitmo’s debug window dynamically sent to the foreground.

2. Security considerations and solutions

Zitmo is quite worrying for two main reasons:

First, it is difficult to spot. Even security-aware users could fall into the trap and have their mobile phone infected. The only (weak) signs that something is amiss consist of 1. receiving an alleged certificate packaged as a Symbian package (.sis or .sisx) and not as a standard certificate (.p12 or .pfx), and 2. having an unknown application listed in the phone’s Application Manager. The rest of the social engineering is quite plausible. Moreover, the trojan is signed by Symbian, which gives end-users a false sense of security.

In reality, the fact that the trojan went through the Express Signed program does not mean the application was reviewed. Only some (randomly selected) applications are reviewed, and Zitmo was not one of those. Obviously, a more thorough analysis of the packages undergoing the Express Signed program (e.g. the Symbian security capabilities they require, in-house testing etc.) might block more malware, but this has a financial cost nobody seems to be willing to pay. The Apple Store and the Android Market get the money from applications sales – an interesting concept, although it does not make them technically immune to malware. (The Android Market has been known to distribute several pieces of spyware, which occasionally have been pulled out. The Apple Store has had fewer security issues so far, but it is often seen as so closed that it basically encourages end-users to jailbreak their devices and then download totally uncontrolled software.)

This issue is not simple to remedy with the current mobile framework. The most technically promising solutions we are aware of base malware detection on behaviour analysis [9], [10], on SMS sending profiles [11], or on matching rules combining security capabilities [12]. They should, however, be tested in real-life situations, and perhaps be combined with other approaches such as mobile anti-virus solutions or firewalls.

The second reason Zitmo gives us cause for concern is that it initiates on-demand two-factor authentication. In part one of this series [1], we explained that Zitmo gives cybercriminals the capability to authenticate whenever they want, using two different authentication factors.

Two-factor authentication is a good security measure, but only as long as the security of the systems in charge of each factor remains intact. In Zitmo’s case this does not happen: from a compromised PC in charge of the first authentication factor, it manages to compromise the mobile phone which handles the second authentication factor. The insecurity of the PC leads to the insecurity of the mobile phone.

Hardware authentication tokens, such as SecurID tokens, are not a solution to this issue. These were defeated by prior versions of Zeus, because the one-time password they generate is entered on a compromised host (the PC). However, in that case, cybercriminals cannot initiate authentication on demand and must wait for the victim to do it.

We would recommend the use of a smartcard-based authentication: a smartcard reader (with its own keypad) is attached to the PC. To authenticate, the end-user must insert his smartcard into the reader and enter a valid PIN on the smartcard reader. This unlocks a private key stored on the smartcard. This key is used to sign an authentication challenge sent by the bank. The signing process is done by the smartcard itself. The authentication challenge is randomly generated and only valid for a given time frame.

In this scenario, the PIN cannot be eavesdropped because it is entered on an uncompromised and secure device, the smartcard reader. The smartcard reader cannot be infected by a trojan such as Zitmo because it usually does not support installation of any additional software. The signed authentication challenge cannot be replayed because it is valid only for a short time frame. The cybercriminals cannot initiate the authentication because they need the victim to enter his PIN on the smartcard reader. The only vulnerability we foresee is race attacks, where the signed authentication challenge could be intercepted by the cybercriminals and sent to the bank by them before the victim. This protocol can probably be improved.

In the future, mobile phones could act as smartcard readers as long as their SIMs have the capability to store a keypair and the phone features a secure keyboard.

3. Conclusion

In this two-part series, we have shown how cybercriminals related to the Zeus gang have stolen online banking credentials, even in cases where the bank sends an mTAN to the end-user’s mobile phone.

We have provided an in-depth analysis of the malicious mobile component, Zitmo, which infects Symbian mobile phones. We have explained how the trojan intercepts all incoming SMS messages. Using a disassembler tool with a Symbian remote debugger and configuring a sane phone to act as the attacker, we have stepped through Zitmo’s malicious code and revealed the entire process of SMS interception and handling. This technique even succeeded in helping us display a debug window the malware authors had hidden.

We have also covered how the cybercriminals probably wrote Zitmo. During our research, we noticed a very similar piece of spyware and found that Zitmo was closely related to it, with a high percentage of identical routines and strings. So, the motivation, implementation and inspiration of Zitmo have all been explained. On a technical note, Zitmo’s reverse engineering is fully completed. Future work should probably keep an eye on SpyEye, which is seen as a rising successor to Zeus. Some other aspects would also be worth investigating more closely, such as countermeasures or cybercriminality.

Research into countermeasures would mean testing solutions based on malicious behaviour detection, firewalling or anti-virus capabilities in real-life environments. Research could also be conducted on reviewing challenge-based authentication protocols and proving them formally against Zeus/Zitmo attacks. As for cybercriminality, several points are still unknown (or undisclosed), such as how many online bank accounts were stolen, how much the cybercriminals traded the accounts for, and to whom, and of course, the identity of the gang.


We thank Guillaume Lovet (Fortinet) for his technical and in-depth review, and Ludovic Apvrille (Telecom ParisTech) for useful comments on the article structure. Finally, we thank David Barroso (s21sec) for kindly sharing information regarding Zeus and Zitmo.


[1] Apvrille, A.; Yang, K. Defeating mTANs for profit – part one. Virus Bulletin, March 2011, p.6.

[2] Payu, S. Silent Receiving of SMS Messages. October 2008.

[3] Barroso, D. ZeuS Mitmo: Man-in-the-mobile. September 2010.

[4] Tarasov, D. SMS Monitor User Manual.

[5] Apvrille, A. Zitmo Follow Up: From Spyware to Malware. September 2010.

[6] Campbell, I. Symbian OS Communications Programming. Symbian Press. John Wiley & Sons Ltd, 2nd edition, 2007.

[7] BiNPDA. SecMan Security Manager v1.1, 2008.

[8] Tarasov, D. Evil-coding Symbian. xakep magazine, 3, 2009. (in Russian).

[9] Bose, A.; Hu, X.; Shin, K. G.; Park, T. Behavioral Detection of Malware on Mobile Handsets. 6th International Conference on Mobile Systems, Applications, and Services (MobiSys’08). June 2008.

[10] Xie, L.; Zhang, X.; Seifert, J.-P.; Zhu, S. pBMDS: A Behavior-based Malware Detection System for Cellphone Devices. 3rd ACM Conference on Wireless Network Security (WiSec’10). March 2010.

[11] Yan, G.; Eidenbenz, S.; Galli, E. SMS-watchdog: Profiling social behaviors of SMS users for anomaly detection. RAID, volume 5758 of Lecture Notes in Computer Science, pp.202–223, 2009.

[12] Enck, W.; Ongtang, M.; McDaniel, P. On Lightweight Mobile Phone Application Certification. 16th ACM Conference on Computer and Communications Security (CCS’09). November 2009.



Latest articles:

Nexus Android banking botnet – compromising C&C panels and dissecting mobile AppInjects

Aditya Sood & Rohit Bansal provide details of a security vulnerability in the Nexus Android botnet C&C panel that was exploited to compromise the C&C panel in order to gather threat intelligence, and present a model of mobile AppInjects.

Cryptojacking on the fly: TeamTNT using NVIDIA drivers to mine cryptocurrency

TeamTNT is known for attacking insecure and vulnerable Kubernetes deployments in order to infiltrate organizations’ dedicated environments and transform them into attack launchpads. In this article Aditya Sood presents a new module introduced by…

Collector-stealer: a Russian origin credential and information extractor

Collector-stealer, a piece of malware of Russian origin, is heavily used on the Internet to exfiltrate sensitive data from end-user systems and store it in its C&C panels. In this article, researchers Aditya K Sood and Rohit Chaturvedi present a 360…

Fighting Fire with Fire

In 1989, Joe Wells encountered his first virus: Jerusalem. He disassembled the virus, and from that moment onward, was intrigued by the properties of these small pieces of self-replicating code. Joe Wells was an expert on computer viruses, was partly…

Run your malicious VBA macros anywhere!

Kurt Natvig wanted to understand whether it’s possible to recompile VBA macros to another language, which could then easily be ‘run’ on any gateway, thus revealing a sample’s true nature in a safe manner. In this article he explains how he recompiled…

Bulletin Archive

We have placed cookies on your device in order to improve the functionality of this site, as outlined in our cookies policy. However, you may delete and block all cookies from this site and your use of the site will be unaffected. By continuing to browse this site, you are agreeing to Virus Bulletin's use of data as outlined in our privacy policy.