Android Titan SMS Trojan Analysis | Part One | VerSprite Android Titan SMS Trojan Analysis | Part One | VerSprite

Android Titan SMS Trojan Analysis | Part One

Written By: Versprite

Analysis

As the title states, the Android Titan SMS Trojan utilizes Trojan functionality in order to steal SMS and exfiltrate them off of the target user’s device. It attempts to mask itself as a “SmartCard Service” on installed on the device, but is hardly such. The bulk of Titan is code, using natively, which have method declarations within the Android components:

In [8]: show_NativeMethods(dx)
 
Lcom/Titanium/Accipite/pipeline; nativepipeline (Landroid/content/Context; Landroid/content/Intent; Ljava/lang/Object;)V
 
Lcom/Titanium/Magister/acsursum; nativeacsursumCall ()V
 
Lcom/Titanium/Magister/posursum; nativeposursumCall ()V
 
Lcom/Titanium/Magister/sursum; nativesursumCall (Landroid/content/Context;)V
 
Lcom/Titanium/Magister/sursumApp; nativesursumAppCall (Landroid/content/Context;)V
 
Lcom/Titanium/Synchronous/Protegendum; nativeProtegendum (Landroid/content/Context; Landroid/content/Intent;)V
 
Lcom/Titanium/Synchronous/adipiscing; nativeadipiscing (Landroid/content/Context; Landroid/content/Intent;)V
 
Lcom/Titanium/Synchronous/desine; nativedesine (Landroid/content/Context; Landroid/content/Intent;)V
 
Lcom/Titanium/Synchronous/factum; nativefactum (Landroid/content/Context; Landroid/content/Intent; Ljava/lang/Object;)Ljava/lang/Object;
 
Lcom/Titanium/Synchronous/praesunt; nativepraesunt (Landroid/content/Context;)I

If we use apktool to disassemble the APK, we will find the shared object we really want to inspect -> libTitaniumCore.so. Titan is quite verbose in nature, so we want to focus on how the Trojan steals and exfiltrates SMS data from the phone.

Broadcast Receivers

Here is what we find when enumerating Titan’s Broadcast Receivers:

In [2]: a.get_receivers()
 
Out[2]:
 
['com.Titanium.Accipite.pipeline',
 
'com.Titanium.Accipite.exinani',
 
'com.Titanium.Accipite.competentia']
<receiver android:name="com.Titanium.Accipite.pipeline" android:permission="android.permission.BROADCAST_SMS">
 
            <intent-filter android:priority="1000">
 
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
 
                <category android:name="android.intent.category.LAUNCHER"/>
 
                <action android:name="android.provider.Telephony.SMS_DELIVER"/>
 
            </intent-filter>
 
        </receiver>
 
        <receiver android:name="com.Titanium.Accipite.exinani" android:permission="android.permission.BROADCAST_WAP_PUSH">
 
            <intent-filter>
 
                <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER"/>
 
                <data android:mimeType="application/vnd.wap.mms-message"/>
 
            </intent-filter>
 
        </receiver>
 
        <receiver android:label="@string/app_name" android:name="com.Titanium.Accipite.competentia" android:permission="android.permission.BIND_DEVICE_ADMIN">
 
            <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin"/>
 
            <intent-filter android:priority="2147483647">
 
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
 
            </intent-filter>
 
        </receiver>

Right away there are some interesting things to note about com.Titanium.Accipite.pipeline. The android.permission.BROADCAST_SMSpermission, allows Titan to broadcast the receipt of an SMS. It also has an Intent Filter meant to receive any Intent communication with the action android.provider.Telephony.SMS_DELIVER, which will give Titan the ability to capture any new inbound SMS data. The android:priority is also a way to make sure this Broadcast Receiver is first inline of the Broadcast Receivers for receiving communication. Investigating com.Titanium.Accipite.pipline we can use the native method declarations:

In [25]: d.CLASS_Lcom_Titanium_Accipite_pipeline.METHOD_nativepipeline.pretty_show()
 
########## Method Information
 
Lcom/Titanium/Accipite/pipeline;->nativepipeline(Landroid/content/Context; Landroid/content/Intent; Ljava/lang/Object;)V [access_flags=private native]
 
 
 
In [24]: d.CLASS_Lcom_Titanium_Accipite_pipeline.METHOD_onReceive.pretty_show()
 
########## Method Information
 
Lcom/Titanium/Accipite/pipeline;->onReceive(Landroid/content/Context; Landroid/content/Intent;)V [access_flags=public]
 
########## Params
 
- local registers: v0...v1
 
- v2: android.content.Context
 
- v3: android.content.Intent
 
- return: void
 
####################
 
***************************************************************************
 
[email protected] :
 
    0  (00000000) iget-object         v0, v1, Lcom/Titanium/Accipite/pipeline;->m_context Lcom/Titanium/Accipite/pipeline;
 
    1  (00000004) invoke-direct       v1, v2, v3, v0, Lcom/Titanium/Accipite/pipeline;->nativepipeline(Landroid/content/Context; Landroid/content/Intent; Ljava/lang/Object;)V
 
    2  (0000000a) return-void

JNI

It appears that nativepipeline() is being called with the Intent object passed to the onReceive() method. If we load up the shared object into the library and do a search for JNI, we can find the method definitions:

titan_01

The Intent Object is passed to a subroutine, which we will call 'operate_on_intent', and then passed to another subroutine. Here getAction() is called on the Intent Object, in order to retrieve the Intent Action, to make some determinations about the communication.

titan_02

Now Titan goes through a series of checks against the returned action, and decides what branch to take if the action matches. We are going to analyze the jump taken if the action is android.provider.Telephony.SMS_RECEIVED. After performing some basic validation of the data, and calling getExtras() on the Intent object, Titan branches to a subroutine we will call 'get_pdu'. In 'get_pdu' Titan calls get() in order to retrieve the raw bundle data, and this is what it will subsequently use to create a PDU in a new subroutine.

titan_03

Now that Titan has the hot ‘n fresh PDU, it will go through the process of adding this data to a new Intent Object, and start the service com.Titanium.Synchronous.adipiscing with said data.

titan_04

Conclusion

In Part Two, we will look into how the com.Titanium.Synchronous.adipiscing takes are PDU and exfiltrates it off the target device.

Protect Your Assets from Various Threat Actors

VerSprite's Research and Development division (a.k.a VS-Labs) is comprised of individuals who are passionate about diving into the internals of various technologies.

Our clients rely on VerSprite's unique offerings of zero-day vulnerability research and exploit development to protect their assets from various threat actors.

From advanced technical security training to our research for hire B.O.S.S offering, we help organizations solve their most complex technical challenges. Learn more about Research as a Service →

Receive Security News





View our security advisories detailing vulnerabilities found in major products for MacOs, Windows, Android, and iOS.

We are an international squad of professionals working as one.

logos