The growing number of Android-based devices, the simplified development process of Android applications and their widespread usage is attracting potential attackers that are after financial gain. By analyzing the area of security issues addressing Android applications (APK’s ), we found out that there is no such thing as a good tool to help with runtime analysis and we are too lazy to debug all the time. Therefore we developed a tool called Vaccine. Vaccine is used for dynamically analyzing APK’s. For a detailed explanation continue reading. If you just want to use Vaccine visit the link https://github.com/viris/android/tree/master/vaccine. Readme contains some additional information about how to use Vaccine.
Going Deeper
The Vaccine consists of a Testing component and a Controlling component. An environment where the Vaccine can be applied to analyze APK’s is shown below.
The environment is divided into two parts. On the left, there is the Android application with injected Vaccine Service and Beanshell, which is a Java source Interpreter [1]. Beanshell is based on Java Relection and makes it possible to execute Java source on the Android device without the need for compiling. The structure of Vaccine is shown on the right side of the picture with the tools it depends on. Communication between these two parts is established and maintained with adb which is part of the ADT bundle. We can reach the Testing component of Vaccine to start analyzing the application in two different ways. The first way is by modifying the Android application and the second is by injecting necessary components in a runtime.
Modifying the Android Application
The Vaccine Controlling component controls the preparation, modification, and installation of the Android application. At the end, it also connects to the application and shows the user interface. The whole process can be stated as:
- unzipping the APK,
- baksmaling classes.dex,
- injecting Vaccine Service and Beanshell library,
- smaling source to classes.dex,
- modifying AndoidManifest.xml,
- replacing classes.dex and AndroidManifest.xml in the APK,
- removing the signature,
- signing the application,
- installing the application,
- running the injected service,
- connecting and running the UI.
The above-described process leads to the dynamical analysis by following command:
./vaccine –i apk_file –p port_number
The first approach doesn’t require a rooted Android device, but can’t be applied if the application performs an integrity check at startup. Lack of permissions isn’t a problem, because the Vaccine changes permissions according to the permissions file included in the package.
Runtime Injection
This approach reaches the Testing component with help of ADBI [2] and DDI [3] toolkits. If the toolkits are setup correctly we need to transfer some additional libraries to the Android device into a temporary directory (/data/local/tmp) where program hijack from ADBI toolkit is already in place. The additional libraries are libvaccine.so, which is used to replace OnStart method of main Activity and vaclasses.dex which is used by libvaccine.so and represents the compiled Vaccine Service code in Java. After transferring libraries, we need to run hijack on the target like:
./hijack -d -p PID -z -l /data/local/tmp/libvaccine.so -s full.package.name
Command PID is the process ID of zygote process and full.packege.name is the name of the Android application we are targeting. So we are hijacking the zygote process and hooking the OnStart main Activity function of the target Android application. The hook imports required libraries, starts the injected service and after that runs the original OnStart function. This hook is executed only once. Now, we only need to run Vaccine as shown below :
./vaccine –r
After executing the above command we can begin with dynamical analysis.
Dynamical Analysis
Whether we are injecting the Vaccine Service and other needed libraries by repackaging APK’s or at runtime we always end up with the Testing component of Vaccine. The front end of the Testing component (the UI) is divided into three parts. The first part in the left upper corner is a tree structure of objects that the application uses in a runtime. The root object named Application was created artificially and represents the analyzing application. One level below there are activities and the application context of the modified application. Activities are added to the root object automatically according to the Activity Lifecycle management in Android [4]. In the right upper corner of the Vaccine UI are two Views. A Status View, where are basic information about an object selected in the objects tree is shown and a Watch View, where values of chosen objects are displayed in regular time intervals. The third part of the Vaccine UI is a scripting area (below part one and two) where it is possible to write Beanshell scripts and Java source code. Scripts will be executed in a runtime under the name of the running application.
The tree object structure in the Vaccine UI responses to the four actions: double click, left click, right-click, and the combination CRL-left click. With the left mouse click, we can select the object and some information is displayed in the Status View. With the right mouse click on the object, we can expand the object. This means that the Vaccine returns all fields and methods of an object whether they are private or public and attaches them to the clicked object. By making the combination CRL-left click we can add objects to the Watch View where object values are displayed in regular time intervals. When double-clicking an object a name of this object is inserted into the scripting part of the Vaccine UI. This name is a variable that can be used in scripts.
Possibilities
The Vaccine possibilities are limited to the device and permissions of an APK on that device. On a smartphone with a custom ROM like CynogenMod that is rooted by default and with access to a system certificate it is possible to access the running Phone instance. We accomplished this by creating a new application, signing it with the system certificate, and setting in the AndroidManifest.xml the attribute sharedUserid (in the manifest element) to android.uid.system and the attribute process (in the application element) to com.android.phone. Section of code shown below presents how to get the running phone instance with the Vaccine:
import com.android.internal.telephony.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.telephony.SmsMessage;
import android.app.PendingIntent;
Phone phone=null;
__beanshellNameOfActivity.runOnUiThread (new Thread(
new Runnable() {
public void run() {
phone = PhoneFactory.getDefaultPhone();
}}));
By adding the code shown below (original code [5]) it is possible to send SMS messages with class 0:
IccSmsInterfaceManager ismsm = phone.getIccSmsInterfaceManager();
Field f = IccSmsInterfaceManager.class.getDeclaredField("mDispatcher");
f.setAccessible(true);
SMSDispatcher sms_disp =(SMSDispatcher)f.get(ismsm);
byte[] b = new byte[0];
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(null, "Phone number", "Zero SMS”, false);
size = (int)pdus.encodedMessage[2];
size = (size/2) + (size%2);
pdus.encodedMessage[size+5] = (byte)0xF0;
sms_disp.sendRawPdu(pdus.encodedScAddress,pdus.encodedMessage,null,null,"Phone number");
When injecting the Vaccine Service into useful APK’s such as Mms.apk in CynogenMode the modified application can be used as a framework. For example, it is possible to send SMS with a Beanshell script.
References
[1] http://www.beanshell.org/intro.html
[2] https://github.com/crmulliner/adbi
[3] https://github.com/crmulliner/ddi
[4] http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
[5] https://github.com/virtualabs/ZeroSMS/blob/master/project/src/com/android/zerosms/ZeroSMS.java