AndroidDropper

Description

This app does nothing!

dropper.apk sha256sum: aaf49dcee761d13da52a95f86b7b92596e7b63c14d0a04bce5dd24c7927ecea9

Author: gchip

Link: http://misc.csaw.io:3003/ Downloads: dropper.apk

Analysis

Since it's troublesome to run the app let's try reversing it. Using dex2jar convert Apk -> JAR. Using Java-Decompiler open JAR to read the code.

└─$ dex2jar dropper.apk -o dropper.apk.jar
dex2jar dropper.apk -> dropper.apk.jar
package com.example.dropper;

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Base64;
import d.l;
import dalvik.system.DexClassLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;

public class MainActivity extends l {
  public final void onCreate(Bundle paramBundle) {
    super.onCreate(paramBundle);
    setContentView(2131427356);
    try {
      byte[] arrayOfByte = Base64.decode("ZGV4CjAzNQAWORryq3+hLJ+yXt9y3L5lCBAqyp3c8Q6UBwAAcAAAAHhWNBIAAAAAAAAAANAGAAAoAAAAcAAAABMAAAAQAQAACwAAAFwBAAABAAAA4AEAABAAAADoAQAAAQAAAGgCAAAMBQAAiAIAAPYDAAD4AwAAAAQAAA4EAAARBAAAFAQAABoEAAAeBAAAPQQAAFkEAABzBAAAigQAAKEEAAC+BAAA0AQAAOcEAAD7BAAADwUAAC0FAAA9BQAAVwUAAHMFAACHBQAAigUAAI4FAACSBQAAlgUAAJ8FAACnBQAAswUAAL8FAADIBQAA2AUAAPIFAAD+BQAAAwYAABMGAAAkBgAALgYAADUGAAADAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABgAAAAZAAAABAAAAAUAAAAAAAAABAAAAAoAAAAAAAAABQAAAAoAAADMAwAABAAAAA0AAAAAAAAABAAAAA4AAAAAAAAAFgAAABAAAAAAAAAAFwAAABAAAADYAwAAFwAAABAAAADgAwAAFwAAABAAAADoAwAAFwAAABAAAADwAwAABgAAABEAAADoAwAAAQARACEAAAABAAUAAQAAAAEAAQAeAAAAAQACACIAAAADAAcAAQAAAAMAAQAlAAAABgAGAAEAAAAIAAUAJAAAAAkABQABAAAACgAJAAEAAAALAAUAGgAAAAsABQAcAAAACwAAAB8AAAAMAAgAAQAAAAwAAwAjAAAADgAKABsAAAAPAAQAHQAAAAEAAAABAAAACQAAAAAAAAACAAAAuAYAAJYGAAAAAAAABAAAAAMAAgCoAwAASwAAAAAAIgAMABoBIABwIAwAEABuEA0AAAAMAB8ACwBuEAkAAAAiAQMAIgIGAG4QCwAAAAwDcCAFADIAcCADACEAbhAEAAEADAFuEAoAAAAoDA0BKB8NAW4QBgABAG4QCgAAABoBAABxAA8AAAAMAG4gDgAQAAwAaQAAABMAEwETATIBEwIqAHEwAgAQAgwAEQBuEAoAAAAnAQAADgAAABUAAQAqAAAAAwAFAAJ/CCknACcABwADAAIAAAC/AwAAGQAAALFFI1ASABIBNVEPAGICAACQAwQBSAICA7dijiJQAgAB2AEBASjyIgQKAHAgCAAEABEEAAABAAEAAQAAAKQDAAAEAAAAcBAHAAAADgAKAA4AEQAOHnhqPOFOPBwpHj08LqamAnkdPAAnAwAAAA48PKM+AAAAAwAAAAAAAAAAAAAAAQAAAAUAAAABAAAABwAAAAEAAAAKAAAAAQAAABIAAAAGPGluaXQ+AAxEcm9wcGVkLmphdmEAAUkAAUwABExJSUkAAkxMAB1MY29tL2V4YW1wbGUvZHJvcHBlZC9Ecm9wcGVkOwAaTGRhbHZpay9hbm5vdGF0aW9uL1Rocm93czsAGExqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwAVTGphdmEvaW8vSU9FeGNlcHRpb247ABVMamF2YS9pby9JbnB1dFN0cmVhbTsAG0xqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyOwAQTGphdmEvaW8vUmVhZGVyOwAVTGphdmEvbGFuZy9FeGNlcHRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAcTGphdmEvbmV0L0h0dHBVUkxDb25uZWN0aW9uOwAOTGphdmEvbmV0L1VSTDsAGExqYXZhL25ldC9VUkxDb25uZWN0aW9uOwAaTGphdmEvdXRpbC9CYXNlNjQkRGVjb2RlcjsAEkxqYXZhL3V0aWwvQmFzZTY0OwABVgACVkwAAltCAAJbQwAHY29ubmVjdAAGZGVjb2RlAApkaXNjb25uZWN0AApnZXREZWNvZGVyAAdnZXRGbGFnAA5nZXRJbnB1dFN0cmVhbQAYaHR0cDovL21pc2MuY3Nhdy5pbzozMDAzAApub3RUaGVGbGFnAANvYmYADm9wZW5Db25uZWN0aW9uAA9wcmludFN0YWNrVHJhY2UACHJlYWRMaW5lAAV2YWx1ZQBXfn5EOHsiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwiaGFzLWNoZWNrc3VtcyI6ZmFsc2UsIm1pbi1hcGkiOjEsInZlcnNpb24iOiIyLjEuNy1yMSJ9AAICASYcARgEAQADAAAIAIGABIwHAQmIBQEJyAYAAAAAAAABAAAAjgYAAKwGAAAAAAAAAQAAAAAAAAABAAAAsAYAABAAAAAAAAAAAQAAAAAAAAABAAAAKAAAAHAAAAACAAAAEwAAABABAAADAAAACwAAAFwBAAAEAAAAAQAAAOABAAAFAAAAEAAAAOgBAAAGAAAAAQAAAGgCAAABIAAAAwAAAIgCAAADIAAAAwAAAKQDAAABEAAABQAAAMwDAAACIAAAKAAAAPYDAAAEIAAAAQAAAI4GAAAAIAAAAQAAAJYGAAADEAAAAgAAAKwGAAAGIAAAAQAAALgGAAAAEAAAAQAAANAGAAA=", 0);
      FileOutputStream fileOutputStream = openFileOutput("dropped.dex", 0);
      fileOutputStream.write(arrayOfByte);
      fileOutputStream.flush();
      fileOutputStream.close();
    } catch (IOException iOException) {
      iOException.printStackTrace();
    } 
    StrictMode.setThreadPolicy((new StrictMode.ThreadPolicy.Builder()).permitAll().build());
    File file = new File(getFilesDir(), "dropped.dex");
    String str1 = file.getAbsolutePath();
    String str2 = getCacheDir().getAbsolutePath();
    ClassLoader classLoader = getClassLoader();
    NoSuchMethodException noSuchMethodException2 = null;
    DexClassLoader dexClassLoader = new DexClassLoader(str1, str2, null, classLoader);
    try {
      Class<?> clazz = dexClassLoader.loadClass("com.example.dropped.Dropped");
    } catch (ClassNotFoundException classNotFoundException) {
      classNotFoundException.printStackTrace();
      str2 = null;
    } 
    try {
      dexClassLoader = str2.newInstance();
    } catch (IllegalAccessException|InstantiationException illegalAccessException) {
      illegalAccessException.printStackTrace();
      illegalAccessException = null;
    } 
    try {
      Method method = str2.getMethod("getFlag", null);
    } catch (NoSuchMethodException noSuchMethodException1) {
      noSuchMethodException1.printStackTrace();
      noSuchMethodException1 = noSuchMethodException2;
    } 
    try {
      noSuchMethodException1.invoke(illegalAccessException, new Object[0]);
    } catch (IllegalAccessException|java.lang.reflect.InvocationTargetException illegalAccessException1) {
      illegalAccessException1.printStackTrace();
    } 
    file.delete();
    AlertDialog.Builder builder = new AlertDialog.Builder((Context)this);
    builder.setMessage("test");
    builder.show();
    finish();
    System.exit(0);
  }
}

From the looks of it program creates a dex file, calls getFlag and exits. The previous tool allows us to decompile dex files too.

└─$ echo -n '{BASE64BLOB}' | base64 -d > dropped.dex 

└─$ file dropped.dex 
dropped.dex: Dalvik dex file version 035

└─$ dex2jar dropped.dex -o dropped.dex.jar
dex2jar dropped.dex -> dropped.dex.jar                                    

dropped.dex.jar:

package com.example.dropped;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;

public class Dropped {
  static byte[] notTheFlag;
  
  public static String getFlag() throws IOException {
    Exception exception;
    HttpURLConnection httpURLConnection = (HttpURLConnection)(new URL("http://misc.csaw.io:3003")).openConnection();
    try {
      httpURLConnection.connect();
      BufferedReader bufferedReader = new BufferedReader();
      InputStreamReader inputStreamReader = new InputStreamReader();
      this(httpURLConnection.getInputStream());
      this(inputStreamReader);
      String str = bufferedReader.readLine();
      httpURLConnection.disconnect();
    } catch (Exception exception1) {
      exception1.printStackTrace();
      httpURLConnection.disconnect();
      String str = "";
    } finally {}
    notTheFlag = Base64.getDecoder().decode((String)exception);
    return obf(275, 306, 42);
  }
  
  public static String obf(int paramInt1, int paramInt2, int paramInt3) {
    int i = paramInt2 - paramInt1;
    char[] arrayOfChar = new char[i];
    for (paramInt2 = 0; paramInt2 < i; paramInt2++)
      arrayOfChar[paramInt2] = (char)(char)(notTheFlag[paramInt1 + paramInt2] ^ paramInt3); 
    return new String(arrayOfChar);
  }
}

Prettify:

public static String obf(int paramInt1, int index, int key) {
  int length = index - paramInt1; // Calculate Length
  char[] flag = new char[i]; // Allocate Buffer
  for (index = 0; index < length; index++) { // Loop
    flag[index] = (char)(char)(notTheFlag[paramInt1 + index] ^ key); // Do XOR On Each Character With `key` 
  }
  return new String(flag); // Array -> String
}

Solution

Take the base64 blob from website, paste it in CyberChef, From Base64, XOR -> 42 (Decimal)

Recipe

For instance, on the planet Earth, man had always assumed that he was more intelligent than dolphins because he had achieved so much - the wheel, New York, wars and so on - whilst all the dolphins had ever done was muck about in the water having a good time. But conversely, csawctf{dyn4m1c_lo4deRs_r_fuN!} the dolphins had always believed that they were far more intelligent than man - for precisely the same reasons.

Note

If you want to get deep into Android Application Reverse Engineering try Mobile Security Framework MobSF

DEF CON Safe Mode Demo Labs - Ajin Abraham - Mobile App Security Testing with MobSF

Last updated