├── 20200806_finspy_android_analysis_public_release.pdf ├── README.md ├── python ├── analyze_samples.py ├── config_parser.py ├── extract_apk_config.py ├── java_parser.py ├── requirements.txt ├── string_decoder.py ├── strings.py ├── strings_db.tpl └── yara │ └── FinSpy.yar ├── samples ├── 9c8bf89d043ba3ed802d6d4f9b290747d12822402d61065adfbcb48a740a47b8.apk └── WIFI.apk └── tables.ods /20200806_finspy_android_analysis_public_release.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveLabAgency/FinSpy-for-Android/78158322169922c72f833402e6485abc7ff7a33a/20200806_finspy_android_analysis_public_release.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FinSpy for Android tools - 2020 2 | This repository contains the tools we developed while investigating on **a new FinSpy implant for Android** as explained in [the AmnestyTech report](https://www.amnesty.org/en/latest/research/2020/09/german-made-finspy-spyware-found-in-egypt-and-mac-and-linux-versions-revealed/) and [our analysis report](https://defensive-lab.agency/2020/09/finspy-android/). 3 | 4 | These tools are meant to: 5 | * extract and decode obfuscated strings; 6 | * extract and parse configuration whether it is stored into the APK or into the DEX. 7 | 8 | ## FinSpy variants detection 9 | We provide Yara rules (located at `python/yara`) detecting 4 variations of FinSpy for Android: 10 | * `FinSpy_ConfigInAPK`: FinSpy configuration stored into the APK 11 | * `FinSpy_DexDen`: FinSpy configuration stored into the DEX 12 | * `FinSpy_TippyTime`: use of a timestamp to generate local socket address 13 | * `FinSpy_TippyPad`: use of basic pad to obfuscate strings 14 | 15 | ## Tools overview 16 | * `java_parser.py` extracts `FinSpy_TippyPad` obfuscated strings from Java source code 17 | * `string_decoder.py` decodes obfuscated strings 18 | * `analyze_samples.py` detects, extracts and parses FinSpy configuration of all samples stored in a given directory 19 | 20 | NB: `analyze_samples.py` extracts and parses configuration whether it is stored into the APK or into the DEX. 21 | 22 | ## Installation 23 | * clone this repository: `git clone https://github.com/DefensiveLabAgency/FinSpy-for-Android.git` 24 | * enter into the cloned directory: `cd FinSpy-for-Android.git` 25 | * create a Python 3 virtual env.: `virtualenv -p python3 venv` 26 | * activate the venv: `source venv/bin/activate` 27 | * then: `cd python` 28 | * install dependencies: `pip install -r requirements.txt` 29 | * play! 30 | 31 | ## Configuration parsing 32 | The scripts we provide parse what we were able to reverse so few configuration fields are not parsed. Anyway, if you run `python analyze_samples.py ../samples yara/FinSpy.yar output`, the script will generate the following directory structure: 33 | * `output/` 34 | * `summary.txt` an analysis summary report 35 | * `/` 36 | * `config.dat` raw extracted configuration 37 | * `config.hex` hexdump of the extracted configuration 38 | * `config.json` JSON representation of the parsed configuration 39 | * `config.txt` text representation of the parsed configuration 40 | 41 | ## Examples 42 | Example of summary: 43 | ``` 44 | ../samples/WIFI.apk 45 | Matching Yara rules: [FinSpy_DexDen, FinSpy_TippyTime, FinSpy_TippyPad] 46 | FinSpy configuration: found and extracted 47 | 48 | ../samples/9c8bf89d043ba3ed802d6d4f9b290747d12822402d61065adfbcb48a740a47b8.apk 49 | Matching Yara rules: [FinSpy_DexDen, FinSpy_TippyTime, FinSpy_TippyPad] 50 | FinSpy configuration: found and extracted 51 | ``` 52 | 53 | Example of parsed configuration: 54 | ``` 55 | [...] 56 | [8402800][803770] TlvTypeConfigTargetProxy = 185.[redacted] 57 | [8402800][803770] TlvTypeConfigTargetProxy = 103.[redacted] 58 | [8403008][803840] TlvTypeConfigTargetPort = 443 59 | [8676208][846370] TlvTypeConfigSMSPhoneNumber = +04[redacted] 60 | [8676976][846670] TlvTypeMobileTrojanID = 12[redacted] 61 | [8676672][846540] TlvTypeMobileTrojanUID = 22[redacted] 62 | [16654656][fe2140] TlvTypeUserID = 1000 63 | [8392000][800d40] TlvTypeTrojanMaxInfections = 9 64 | [8677440][846840] TlvTypeConfigMobileAutoRemovalDateTime = 0 65 | [8403776][803b40] TlvTypeConfigAutoRemovalIfNoProxy = 168 66 | [8675472][846090] TlvTypeMobileTargetHeartbeatEvents = 67 | - SIM changed: True 68 | - Cell location changed: False 69 | - Network changed: True 70 | - Call: False 71 | - Wifi connected: True 72 | - Data link available: True 73 | - Network activated: False 74 | - Data available: True 75 | [8681872][847990] TlvTypeInstalledModules = 76 | - Spy calls: False 77 | - Intercept calls: False 78 | - SMS: True 79 | - Address book: True 80 | - Logging: False 81 | - Location: True 82 | - Call log: True 83 | - Calendar: True 84 | - Spy chats: True 85 | [...] 86 | ``` 87 | 88 | ## Credits 89 | * Esther Onfroy 90 | * Etienne Maynier -------------------------------------------------------------------------------- /python/analyze_samples.py: -------------------------------------------------------------------------------- 1 | # Android FinFisher samples bisection 2 | # Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b) 3 | # 4 | # Analyzes samples (APK or DEX files) and gives hints about the FinSpy variant. 5 | # Automatically analyze DEX file contained into APK and extract FinSpy configuration (DexDen only). 6 | import shutil 7 | import zipfile 8 | from tempfile import NamedTemporaryFile 9 | 10 | from objutils import Section 11 | 12 | import yara 13 | import glob 14 | import json 15 | import sys 16 | import os 17 | 18 | from config_parser import parse_dex_configuration, parse_configuration_entries, find_config_entry 19 | from extract_apk_config import extract_apk_config 20 | 21 | 22 | class FinSpyAnalyzer: 23 | def __init__(self, sample, output_dir, yara_file): 24 | self.sample = sample 25 | self.main_output_dir = output_dir 26 | self.dump_dir = None 27 | self.raw_config = None 28 | self.parsed_config = None 29 | self.config_addr = 0 30 | self.matches = [] 31 | self.yara_rules = yara.compile(yara_file) 32 | # self.apply_rules() 33 | 34 | def summary(self): 35 | line = self.sample + '\n' 36 | line += f'Matching Yara rules: {self.matches}\n' 37 | line += 'FinSpy configuration: ' 38 | if self.raw_config and self.parsed_config: 39 | line += 'found and extracted\n' 40 | else: 41 | line += 'not found\n' 42 | return line + '\n' 43 | 44 | def _prepare_output(self): 45 | output_path = os.path.realpath(self.main_output_dir) 46 | if not os.path.exists(output_path): 47 | os.mkdir(output_path) 48 | origin_file_name_path = os.path.join(output_path, os.path.basename(self.sample)) 49 | if not os.path.exists(origin_file_name_path): 50 | os.mkdir(origin_file_name_path) 51 | 52 | self.dump_dir = origin_file_name_path 53 | 54 | def dump(self): 55 | if self.raw_config and self.parsed_config: 56 | self._prepare_output() 57 | with open(os.path.join(self.dump_dir, 'config.json'), 'w') as out: 58 | json.dump(self.parsed_config, out, indent=2, sort_keys=True) 59 | with open(os.path.join(self.dump_dir, 'config.dat'), 'wb') as out: 60 | out.write(self.raw_config) 61 | with open(os.path.join(self.dump_dir, 'config.hex'), 'w') as out: 62 | section = Section(self.config_addr, self.raw_config) 63 | section.hexdump(out) 64 | with open(os.path.join(self.dump_dir, 'config.txt'), 'w') as out: 65 | for i in self.parsed_config: 66 | elt = i 67 | line = '['+str(elt.get('tlv_int'))+']' 68 | line += '['+elt.get('tlv_hex')+']' 69 | line += ' '+elt.get('tlv_name')+' = ' 70 | if elt['attrs']: 71 | for a in elt['attrs']: 72 | line += '\n - ' + a['name'] + ': ' + str(a['active']) 73 | line += '\n' 74 | elif elt['is_printable_value']: 75 | line += str(elt.get('value')) 76 | else: 77 | line += '\n'+elt.get('value') 78 | out.write(line+'\n') 79 | 80 | @staticmethod 81 | def print_detections(matches, detected_file): 82 | if len(matches) > 0: 83 | print(f'{matches}:{detected_file}') 84 | 85 | def apply_rules(self): 86 | self.matches = self.yara_rules.match(self.sample) 87 | 88 | def detect(self, bin_file, parent_file=None): 89 | self.matches += self.yara_rules.match(bin_file) 90 | detected_file = bin_file 91 | 92 | if parent_file: 93 | detected_file = parent_file 94 | 95 | if bin_file.endswith('.apk'): 96 | # self.print_detections(matches, detected_file) 97 | if 'FinSpy_ConfigInAPK' in [m.rule for m in self.matches]: 98 | with open(bin_file, 'rb') as apk_file: 99 | config = extract_apk_config(apk_file.read()) 100 | if config: 101 | self.raw_config = config 102 | self.config_addr = 12 103 | self.parsed_config = parse_configuration_entries(config, 12, len(config)) 104 | try: 105 | with zipfile.ZipFile(bin_file) as apk: 106 | with apk.open('classes.dex') as dex: 107 | with NamedTemporaryFile(suffix='.dex') as dex_file: 108 | dex_file.write(dex.read()) 109 | dex_file.seek(0) 110 | self.detect(dex_file.name, bin_file) 111 | except zipfile.BadZipFile: 112 | pass 113 | elif bin_file.endswith('.dex'): 114 | if parent_file: 115 | detected_file += '/classes.dex' 116 | # self.print_detections(matches, detected_file) 117 | if 'FinSpy_DexDen' in [m.rule for m in self.matches]: 118 | try: 119 | with open(bin_file, 'rb') as dex_file: 120 | dex_data = dex_file.read() 121 | offset, length = find_config_entry(dex_data) 122 | self.raw_config = dex_data[offset:offset+length] 123 | self.config_addr = offset 124 | self.parsed_config = parse_dex_configuration(bin_file) 125 | except: 126 | pass 127 | 128 | @staticmethod 129 | def list_apk_files(dir): 130 | apk_files = glob.glob(f'{dir}/**/*.apk', recursive=True) 131 | for apk_file in apk_files: 132 | yield apk_file 133 | 134 | @staticmethod 135 | def list_dex_files(dir): 136 | dex_files = glob.glob(f'{dir}/**/*.dex', recursive=True) 137 | for dex_file in dex_files: 138 | yield dex_file 139 | 140 | 141 | if __name__ == '__main__': 142 | if len(sys.argv) != 4: 143 | print(f'Usage: python {sys.argv[0]} ') 144 | sys.exit(1) 145 | 146 | directory = str(sys.argv[1]) 147 | yara_file = str(sys.argv[2]) 148 | output_dir = str(sys.argv[3]) 149 | 150 | if os.path.exists(output_dir): 151 | shutil.rmtree(output_dir) 152 | os.mkdir(output_dir) 153 | 154 | def _do(dex, output_dir, yara_file): 155 | analyzer = FinSpyAnalyzer(dex, output_dir, yara_file) 156 | analyzer.detect(dex) 157 | analyzer.dump() 158 | # print(analyzer.summary()) 159 | with open(os.path.join(output_dir, 'summary.txt'), 'a') as s: 160 | s.write(analyzer.summary()) 161 | 162 | for dex in FinSpyAnalyzer.list_dex_files(directory): 163 | _do(dex, output_dir, yara_file) 164 | 165 | for apk in FinSpyAnalyzer.list_apk_files(directory): 166 | _do(apk, output_dir, yara_file) 167 | -------------------------------------------------------------------------------- /python/config_parser.py: -------------------------------------------------------------------------------- 1 | # Android FinFisher DexDen configuration parser 2 | # Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b) 3 | # 4 | # Automatically extract FinSpy configuration stored in DEX (DexDen only). 5 | 6 | import binascii 7 | import string 8 | import struct 9 | from io import StringIO 10 | 11 | from objutils import Section 12 | 13 | tlv_types = { 14 | 4522400: "TlvTypeMobileTrackingStartRequest", 15 | 4522656: "TlvTypeMobileTrackingStopRequest", 16 | 4523376: "TlvTypeMobileTrackingDataV10", 17 | 4535200: "TlvTypeMobileTrackingConfig", 18 | 4535440: "TlvTypeMobileTrackingConfigRaw", 19 | 4538432: "TlvTypeMobileTrackingTimeInterval", 20 | 4538688: "TlvTypeMobileTrackingDistance", 21 | 4538928: "TlvTypeMobileTrackingSendOnAnyChannel", 22 | 6291872: "TlvTypeMobileLoggingMetaInfo", 23 | 6292096: "TlvTypeMobileLoggingData", 24 | 4456864: "TlvTypeMobileBlackberryMessengerMetaInfo", 25 | 4457088: "TlvTypeMobileBlackberryMessengerData", 26 | 4457328: "TlvTypeMobileBlackberryMsChatID", 27 | 4457600: "TlvTypeMobileBlackberryMsConversationPartners", 28 | 4587936: "TlvTypeMobilePhoneCallLogsMetaInfo", 29 | 4588192: "TlvTypeMobilePhoneCallLogsData", 30 | 4588400: "TlvTypeMobilePhoneCallLogsType", 31 | 4588672: "TlvTypeMobilePhoneCallAdditionalInformation", 32 | 4588912: "TlvTypeMobilePhoneCallLogsCallerNumber", 33 | 4589168: "TlvTypeMobilePhoneCallLogsCalleeNumber", 34 | 4589440: "TlvTypeMobilePhoneCallLogsCallerName", 35 | 4589696: "TlvTypeMobilePhoneCallLogsCalleeName", 36 | 4591680: "TlvTypeMobilePhoneCallLogLastEntryEndtime", 37 | 4325792: "TlvTypeMobileSMSMetaInfo", 38 | 4326016: "TlvTypeMobileSMSData", 39 | 4326256: "TlvTypeSMSSenderNumber", 40 | 4326512: "TlvTypeSMSRecipientNumber", 41 | 4326768: "TlvTypeSMSDirection", 42 | 4326528: "TlvTypeSMSInformation", 43 | 4391328: "TlvTypeMobileAddressBookMetaInfo", 44 | 4391552: "TlvTypeMobileAddressBookData", 45 | 4407360: "TlvTypeMobileAddressBookChecksum", 46 | 8978752: "TlvTypeMobileProxyMasterCommSig", 47 | 8979104: "TlvTypeMobileProxyMasterComm", 48 | 8979360: "TlvTypeMobileMasterProxyComm", 49 | 8979616: "TlvTypeProxyMasterMobileHeartBeatAnswer", 50 | 8979872: "TlvTypeMobileMasterProxyCommNotification", 51 | 8782176: "TlvTypeProxyMobileTargetCommSig", 52 | 8782496: "TlvTypeProxyMobileTargetComm", 53 | 8782752: "TlvTypeProxyMasterMobileTargetComm", 54 | 1507744: "TlvTypeAccessedFileMetaInfo", 55 | 1507968: "TlvTypeAccessedFileAccessTime", 56 | 1508224: "TlvTypeAccessedFileAccessEvent", 57 | 1508496: "TlvTypeAccessedFileRecording", 58 | 1508736: "TlvTypeAccessedApplicationName", 59 | 1508912: "TlvTypeConfigRecordImagesFromExplorer", 60 | 1519776: "TlvTypeGetAccessedConfigRequest", 61 | 1520032: "TlvTypeAccessedConfigReply", 62 | 1520288: "TlvTypeSetAccessedConfigRequest", 63 | 1520448: "TlvTypeConfigAccessedEvents", 64 | 2240672: "TlvTypeGetMouseClicksConfigRequest", 65 | 2240928: "TlvTypeMouseClicksConfigReply", 66 | 2241184: "TlvTypeSetMouseClicksConfigRequest", 67 | 2228640: "TlvTypeMouseClicksMetaInfo", 68 | 2228896: "TlvTypeMouseClicksFrame", 69 | 2232448: "TlvTypeMouseClicksEncodingType", 70 | 2232896: "TlvTypeConfigMouseClicksRectangle", 71 | 2233152: "TlvTypeConfigMouseClicksSensitivity", 72 | 2233408: "TlvTypeConfigMouseClicksType", 73 | 2175136: "TlvTypeGetVoIPConfigRequest", 74 | 2175392: "TlvTypeVoIPConfigReply", 75 | 2175648: "TlvTypeSetVoIPConfigRequest", 76 | 2163104: "TlvTypeVoIPMetaInfo", 77 | 2166912: "TlvTypeVoIPEncodingType", 78 | 2167168: "TlvTypeVoIPSessionType", 79 | 2167424: "TlvTypeVoIPApplicationName", 80 | 2167696: "TlvTypeVoIPAppScreenshot", 81 | 2167952: "TlvTypeVoIPAudioRecording", 82 | 2168112: "TlvTypeConfigVoIPScreenshotEnabled", 83 | 2109600: "TlvTypeGetForensicsConfigRequest", 84 | 2109856: "TlvTypeForensicsConfigReply", 85 | 2110112: "TlvTypeSetForensicsConfigRequest", 86 | 2097568: "TlvTypeUploadForensicsApplicationRequest", 87 | 2097824: "TlvTypeUploadForensicsApplicationReply", 88 | 2098080: "TlvTypeUploadForensicsApplicationChunk", 89 | 2098336: "TlvTypeUploadForensicsApplicationDoneRequest", 90 | 2098592: "TlvTypeUploadForensicsApplicationDoneReply", 91 | 2101664: "TlvTypeRemoveForensicsApplicationRequest", 92 | 2101920: "TlvTypeRemoveForensicsApplicationReply", 93 | 2105760: "TlvTypeForensicsAppExecuteRequest", 94 | 2106016: "TlvTypeForensicsAppExecuteReply", 95 | 2106272: "TlvTypeForensicsAppExecuteResult", 96 | 2106528: "TlvTypeForensicsAppExecuteResultChunk", 97 | 2106784: "TlvTypeForensicsAppExecuteResultDone", 98 | 2107040: "TlvTypeForensicsCancelAppExecuteRequest", 99 | 2107296: "TlvTypeForensicsCancelAppExecuteReply", 100 | 2113680: "TlvTypeConfigForensicsApplicationInfoGeneric", 101 | 2113952: "TlvTypeConfigForensicsApplicationInfo", 102 | 2117760: "TlvTypeConfigForensicsApplicationName", 103 | 2117952: "TlvTypeConfigForensicsApplicationSize", 104 | 2118208: "TlvTypeConfigForensicsApplicationID", 105 | 2118528: "TlvTypeConfigForensicsApplicationCmdline", 106 | 2118784: "TlvTypeConfigForensicsApplicationOutput", 107 | 2118976: "TlvTypeConfigForensicsApplicationTimeout", 108 | 2119232: "TlvTypeConfigForensicsApplicationVersion", 109 | 2119552: "TlvTypeForensicsFriendlyName", 110 | 2119808: "TlvTypeConfigForensicsApplicationOutputPrepend", 111 | 2120064: "TlvTypeConfigForensicsApplicationOutputContentType", 112 | 1638816: "TlvTypeDeletedFileMetaInfo", 113 | 1639296: "TlvTypeDeletedFileDeletionTime", 114 | 1639552: "TlvTypeDeletedFileRecycleBin", 115 | 1639808: "TlvTypeDeletedMethod", 116 | 1640064: "TlvTypeDeletedApplicationName", 117 | 1640336: "TlvTypeDeletedFileRecording", 118 | 1650848: "TlvTypeGetDeletedConfigRequest", 119 | 1651104: "TlvTypeDeletedConfigReply", 120 | 1651360: "TlvTypeSetDeletedConfigRequest", 121 | 1573280: "TlvTypePrintFileMetaInfo", 122 | 1573520: "TlvTypePrintFrame", 123 | 1581184: "TlvTypePrintApplicationName", 124 | 1581440: "TlvTypePrintFilename", 125 | 1581696: "TlvTypePrintEncodingType", 126 | 1585312: "TlvTypeGetPrintConfigRequest", 127 | 1585568: "TlvTypePrintConfigReply", 128 | 1585824: "TlvTypeSetPrintConfigRequest", 129 | 1442208: "TlvTypeChangedFileMetaInfo", 130 | 1442432: "TlvTypeChangedFileChangeTime", 131 | 1442688: "TlvTypeChangedFileChangeEvent", 132 | 1442960: "TlvTypeChangedFileRecording", 133 | 1454240: "TlvTypeGetChangedConfigRequest", 134 | 1454496: "TlvTypeChangedConfigReply", 135 | 1454752: "TlvTypeSetChangedConfigRequest", 136 | 1454912: "TlvTypeConfigChangedEvents", 137 | 1311136: "TlvTypeSkypeAudioMetaInfo", 138 | 1311376: "TlvTypeSkypeAudioRecording", 139 | 1311648: "TlvTypeSkypeTextRecording", 140 | 1311904: "TlvTypeSkypeFileMetaInfo", 141 | 1312144: "TlvTypeSkypeFileRecording", 142 | 1312416: "TlvTypeSkypeContactsRecording", 143 | 1312640: "TlvTypeSkypeContactsUserData", 144 | 1323168: "TlvTypeGetSkypeConfigRequest", 145 | 1323424: "TlvTypeSkypeConfigReply", 146 | 1323680: "TlvTypeSetSkypeConfigRequest", 147 | 1324336: "TlvTypeConfigSkypeAudioEnable", 148 | 1324592: "TlvTypeConfigSkypeTextEnable", 149 | 1324848: "TlvTypeConfigSkypeFileEnable", 150 | 1325104: "TlvTypeConfigSkypeContactsListEnable", 151 | 1327232: "TlvTypeSkypeAudioEncodingType", 152 | 1327488: "TlvTypeSkypeLoggedInUserAccountName", 153 | 1327744: "TlvTypeSkypeConversationPartnerAccountName", 154 | 1328000: "TlvTypeSkypeConversationPartnerDisplayName", 155 | 1328256: "TlvTypeSkypeChatMembers", 156 | 1328512: "TlvTypeSkypeTextMessage", 157 | 1328768: "TlvTypeSkypeChatID", 158 | 1329024: "TlvTypeSkypeSenderAccountName", 159 | 1329280: "TlvTypeSkypeSenderDisplayName", 160 | 1329536: "TlvTypeSkypeIncoming", 161 | 1329792: "TlvTypeSkypeSessionType", 162 | 1192096: "TlvTypeGetKeyloggerConfigRequest", 163 | 1192352: "TlvTypeKeyloggerConfigReply", 164 | 1192608: "TlvTypeSetKeyloggerConfigRequest", 165 | 1180064: "TlvTypeStartKeyLoggingRequest", 166 | 1180320: "TlvTypeStartKeyLoggingReply", 167 | 1180576: "TlvTypeKeyLoggingFrame", 168 | 1180832: "TlvTypeStopKeyLoggingRequest", 169 | 1181088: "TlvTypeKeyLoggingStoppedReply", 170 | 1196416: "TlvTypeKLFrameData", 171 | 1126560: "TlvTypeGetVideoConfigRequest", 172 | 1126816: "TlvTypeVideoConfigReply", 173 | 1127072: "TlvTypeSetVideoConfigRequest", 174 | 1114528: "TlvTypeStartScreenRequest", 175 | 1114784: "TlvTypeStartScreenReply", 176 | 1115040: "TlvTypeScreenFrame", 177 | 1115296: "TlvTypeStopScreenRequest", 178 | 1115552: "TlvTypeScreenStoppedReply", 179 | 1115808: "TlvTypeStartScreenRecording", 180 | 1122720: "TlvTypeStartWebCamRequest", 181 | 1122976: "TlvTypeStartWebCamReply", 182 | 1123232: "TlvTypeWebCamFrame", 183 | 1123488: "TlvTypeStopWebCamRequest", 184 | 1123744: "TlvTypeWebCamStoppedReply", 185 | 1124000: "TlvTypeStartWebCamRecording", 186 | 1130560: "TlvTypeVDFrameID", 187 | 1130896: "TlvTypeVDFrameData", 188 | 1131136: "TlvTypeOriginalVideoResolution", 189 | 1131392: "TlvTypeVideoResolution", 190 | 1066112: "TlvTypeVideoSessionType", 191 | 1066368: "TlvTypeVideoEncodingType", 192 | 1132160: "TlvTypeAutomaticRecordingUID", 193 | 1061024: "TlvTypeGetAudioConfigRequest", 194 | 1061280: "TlvTypeAudioConfigReply", 195 | 1061536: "TlvTypeSetAudioConfigRequest", 196 | 1048992: "TlvTypeStartMicrophoneRequest", 197 | 1049248: "TlvTypeStartMicrophoneReply", 198 | 1049504: "TlvTypeMicrophoneFrame", 199 | 1049760: "TlvTypeStopMicrophoneRequest", 200 | 1050016: "TlvTypeMicrophoneStoppedReply", 201 | 1050272: "TlvTypeStartMicrophoneRecording", 202 | 1052736: "TlvTypeMICFrameID", 203 | 1053072: "TlvTypeMICFrameData", 204 | 1053312: "TlvTypeAudioSessionType", 205 | 1053568: "TlvTypeAudioEncodingType", 206 | 328096: "TlvTypeGetSchedulerConfigRequest", 207 | 328352: "TlvTypeSchedulerConfigReply", 208 | 328608: "TlvTypeSetSchedulerConfigRequest", 209 | 331920: "TlvTypeSchedulerTask", 210 | 332192: "TlvTypeSchedulerTaskRecordByTime", 211 | 332448: "TlvTypeSchedulerTaskRecordScreenWhenAppRuns", 212 | 332704: "TlvTypeSchedulerTaskRecordMicWhenAppUsesIt", 213 | 332960: "TlvTypeSchedulerTaskRecordWebCamWhenAppUsesIt", 214 | 360592: "TlvTypeSCHTaskConfiguration", 215 | 360752: "TlvTypeSCHTaskEnabled", 216 | 361344: "TlvTypeSCHTaskStartDateTime", 217 | 361600: "TlvTypeSCHTaskStopDateTime", 218 | 362112: "TlvTypeSCHApplicationName", 219 | 362288: "TlvTypeSCHApplicationWindowOnly", 220 | 299168: "TlvTypeGetCmdLineConfigRequest", 221 | 299424: "TlvTypeCmdLineConfigReply", 222 | 299680: "TlvTypeSetCmdLineConfigRequest", 223 | 262560: "TlvTypeStartCmdLineSessionRequest", 224 | 262816: "TlvTypeStartCmdLineSessionReply", 225 | 263072: "TlvTypeStopCmdLineSessionRequest", 226 | 263328: "TlvTypeCmdLineSessionStoppedReply", 227 | 263584: "TlvTypeCmdLineExecute", 228 | 263840: "TlvTypeCmdLineExecutionResult", 229 | 266352: "TlvTypeCmdLineExecuteCommand", 230 | 266560: "TlvTypeCmdLineExecuteAnswerID", 231 | 266864: "TlvTypeCmdLineExecuteAnswerData", 232 | 168096: "TlvTypeGetFileSystemConfigRequest", 233 | 168352: "TlvTypeFileSystemConfigReply", 234 | 168608: "TlvTypeSetFileSystemConfigRequest", 235 | 131488: "TlvTypeGetAllDrivesRequest", 236 | 131744: "TlvTypeGetAllDrivesReply", 237 | 135328: "TlvTypeGetFolderContentsRequest", 238 | 135584: "TlvTypeGetFolderContentsReply", 239 | 135840: "TlvTypeGetFolderContentsNext", 240 | 136096: "TlvTypeGetFolderContentsEnd", 241 | 139424: "TlvTypeDownloadFileRequest", 242 | 139680: "TlvTypeCancelDownloadFileRequest", 243 | 139936: "TlvTypeDownloadFileReply", 244 | 140192: "TlvTypeDownloadFileNext", 245 | 140448: "TlvTypeDownloadFileEnd", 246 | 140704: "TlvTypeCancelDownloadFileReply", 247 | 143520: "TlvTypeUploadFileRequest", 248 | 143776: "TlvTypeCancelUploadFileRequest", 249 | 144032: "TlvTypeUploadFileReply", 250 | 144288: "TlvTypeUploadFileNext", 251 | 144544: "TlvTypeUploadFileEnd", 252 | 144800: "TlvTypeUploadFileCompleted", 253 | 145056: "TlvTypeCancelUploadFileReply", 254 | 147616: "TlvTypeDeleteFileRequest", 255 | 147872: "TlvTypeDeleteFileReply", 256 | 151968: "TlvTypeSearchFileRequest", 257 | 152224: "TlvTypeSearchFileReply", 258 | 152480: "TlvTypeSearchFileNext", 259 | 152736: "TlvTypeSearchFileEnd", 260 | 152992: "TlvTypeCancelSearchFileRequest", 261 | 153248: "TlvTypeCancelSearchFileReply", 262 | 159888: "TlvTypeFSFileDataChunk", 263 | 160128: "TlvTypeFSDiskDrive", 264 | 160384: "TlvTypeFSFullPath", 265 | 160640: "TlvTypeFSFilename", 266 | 160896: "TlvTypeFSFileExtension", 267 | 161088: "TlvTypeFSDiskDriveType", 268 | 161408: "TlvTypeFSFileSize", 269 | 161584: "TlvTypeFSIsFolder", 270 | 161840: "TlvTypeFSReadOnly", 271 | 162096: "TlvTypeFSHidden", 272 | 162352: "TlvTypeFSSystem", 273 | 162688: "TlvTypeFSFileCreationTime", 274 | 162944: "TlvTypeFSFileLastAccessTime", 275 | 163200: "TlvTypeFSFileLastWriteTime", 276 | 163472: "TlvTypeFSFullPathM", 277 | 8978848: "TlvTypeMasterMobileTargetConn", 278 | 7471520: "TlvTypeMasterTargetConn", 279 | 7405984: "TlvTypeMasterAgentLogin", 280 | 7406240: "TlvTypeMasterAgentLoginAnswer", 281 | 7406752: "TlvTypeMasterAgentTargetList", 282 | 7407008: "TlvTypeMasterAgentTargetOnlineList", 283 | 7407264: "TlvTypeMasterAgentTargetInfoReply", 284 | 7407520: "TlvTypeMasterAgentUserList", 285 | 7407776: "TlvTypeMasterAgentUserListReply", 286 | 7408032: "TlvTypeMasterAgentTargetArchivedList", 287 | 7408288: "TlvTypeMasterAgentTargetListEx", 288 | 7408544: "TlvTypeMasterAgentTargetOnlineListEx", 289 | 7408800: "TlvTypeMasterAgentMobileTargetArchivedList", 290 | 7409056: "TlvTypeMasterAgentMobileTargetList", 291 | 7409312: "TlvTypeMasterAgentMobileTargetOnlineList", 292 | 7409824: "TlvTypeMasterAgentQueryFirst", 293 | 7410080: "TlvTypeMasterAgentQueryNext", 294 | 7410336: "TlvTypeMasterAgentQueryLast", 295 | 7410592: "TlvTypeMasterAgentQueryAnswer", 296 | 7410848: "TlvTypeMasterAgentRemoveRecord", 297 | 7411104: "TlvTypeMasterAgentTargetInfoExReply", 298 | 7411344: "TlvTypeTargetInfoExProperty", 299 | 7411616: "TlvTypeTargetInfoExPropertyValue", 300 | 7411840: "TlvTypeTargetInfoExPropertyValueName", 301 | 7411968: "TlvTypeTargetInfoExPropertyValueData", 302 | 7412384: "TlvTypeMasterAgentAlarm", 303 | 7413920: "TlvTypeMasterAgentRetrieveData", 304 | 7414176: "TlvTypeMasterAgentRetrieveDataAnswer", 305 | 7414432: "TlvTypeMasterAgentRemoveUser", 306 | 7414688: "TlvTypeMasterAgentRemoveTarget", 307 | 7414944: "TlvTypeMasterAgentRetrieveDataComments", 308 | 7415200: "TlvTypeMasterAgentUpdateDataComments", 309 | 7415712: "TlvTypeMasterAgentRetrieveActivityLogging", 310 | 7415968: "TlvTypeMasterAgentRetrieveMasterLogging", 311 | 7416224: "TlvTypeMasterAgentRetrieveAgentActivityLogging", 312 | 7417248: "TlvTypeMasterAgentSendUserGUIConfig", 313 | 7417504: "TlvTypeMasterAgentGetUserGUIConfigRequest", 314 | 7417760: "TlvTypeMasterAgentGetUserGUIConfigReply", 315 | 7418016: "TlvTypeMasterAgentProxyList", 316 | 7418272: "TlvTypeMasterAgentProxyInfoReply", 317 | 7419040: "TlvTypeMasterAgentNameValuePacket", 318 | 7419248: "TlvTypeMasterAgentValueName", 319 | 7419392: "TlvTypeMasterAgentValueData", 320 | 7419808: "TlvTypeMasterAgentRetrieveTargetHistory", 321 | 7421088: "TlvTypeMasterAgentInstallMasterLicense", 322 | 7421344: "TlvTypeMasterAgentInstallSoftwareUpdate", 323 | 7421600: "TlvTypeMasterAgentInstallSoftwareUpdateChunk", 324 | 7421856: "TlvTypeMasterAgentInstallSoftwareUpdateDone", 325 | 7422112: "TlvTypeMasterAgentSoftwareUpdateInfo", 326 | 7422368: "TlvTypeMasterAgentSoftwareUpdateInfoReply", 327 | 7422624: "TlvTypeMasterAgentSoftwareUpdate", 328 | 7422880: "TlvTypeMasterAgentSoftwareUpdateReply", 329 | 7423136: "TlvTypeMasterAgentSoftwareUpdateNext", 330 | 7423392: "TlvTypeMasterAgentAddTimeSchedule", 331 | 7423648: "TlvTypeMasterAgentAddScreenSchedule", 332 | 7423904: "TlvTypeMasterAgentAddLockedSchedule", 333 | 7424160: "TlvTypeMasterAgentRemoveSchedule", 334 | 7424416: "TlvTypeMasterAgentGetSchedulerList", 335 | 7424672: "TlvTypeMasterAgentSchedulerTimeAction", 336 | 7424928: "TlvTypeMasterAgentSchedulerScreenAction", 337 | 7425184: "TlvTypeMasterAgentSchedulerLockedAction", 338 | 7425440: "TlvTypeMasterAgentProjectSoftwareUpdateInfo", 339 | 7425696: "TlvTypeMasterAgentProjectSoftwareUpdateInfoReply", 340 | 7425952: "TlvTypeMasterAgentProjectSoftwareUpdate", 341 | 7426112: "TlvTypeMasterAgentSchedulerID", 342 | 7426368: "TlvTypeMasterAgentSchedulerStartTime", 343 | 7426624: "TlvTypeMasterAgentSchedulerStopTime", 344 | 7427488: "TlvTypeMasterAgentAddRecordedDataAvailableSchedule", 345 | 7427744: "TlvTypeMasterAgentSchedulerRecordedDataAvailableAction", 346 | 7428256: "TlvTypeMasterAgentRetrieveRemoteMasterData", 347 | 7428512: "TlvTypeMasterAgentRetrieveRemoteMasterDataReply", 348 | 7428768: "TlvTypeMasterAgentDeleteRemoteMasterData", 349 | 7429024: "TlvTypeMasterAgentRetrieveOfflineMasterData", 350 | 7429280: "TlvTypeMasterAgentRetrieveOfflineMasterDataReply", 351 | 7429536: "TlvTypeMasterAgentDeleteOfflineMasterData", 352 | 7430304: "TlvTypeMasterAgentQueryFirstEx", 353 | 7430560: "TlvTypeMasterAgentQueryNextEx", 354 | 7430816: "TlvTypeMasterAgentQueryLastEx", 355 | 7431072: "TlvTypeMasterAgentQueryAnswerEx", 356 | 7431328: "TlvTypeMasterAgentSendUserPreferences", 357 | 7431584: "TlvTypeMasterAgentGetUserPreferencesRequest", 358 | 7431840: "TlvTypeMasterAgentGetUserPreferencesReply", 359 | 7432096: "TlvTypeMasterAgentListMCFilesRequest", 360 | 8415392: "TlvTypeMasterAgentListMCFilesReply", 361 | 7432608: "TlvTypeMasterAgentDeleteMCFiles", 362 | 7432864: "TlvTypeMasterAgentSendMCFiles", 363 | 7433120: "TlvTypeMasterAgentMCStatisticsRequest", 364 | 7433376: "TlvTypeMasterAgentMCStatisticsReply", 365 | 7433616: "TlvTypeMasterAgentMCStatisticsValues", 366 | 7434400: "TlvTypeMasterAgentTrojanKeyRequest", 367 | 7434656: "TlvTypeMasterAgentTrojanKeyReply", 368 | 7434912: "TlvTypeMasterAgentEvProtectionX509Request", 369 | 7435168: "TlvTypeMasterAgentEvProtectionX509Reply", 370 | 7435424: "TlvTypeMasterAgentEvProtectionImportCert", 371 | 7435680: "TlvTypeMasterAgentEvProtectionImportCertCompleted", 372 | 7435936: "TlvTypeMasterAgentConfigurationRequest", 373 | 7436192: "TlvTypeMasterAgentConfigurationReply", 374 | 7436448: "TlvTypeMasterAgentConfigurationUpdateRequest", 375 | 7436704: "TlvTypeMasterAgentConfigurationUpdateRequestCompleted", 376 | 7436944: "TlvTypeMasterAgentConfiguration", 377 | 7437216: "TlvTypeMasterAgentConfigurationValue", 378 | 7437424: "TlvTypeMasterAgentConfigurationValueName", 379 | 7437568: "TlvTypeMasterAgentConfigurationValueData", 380 | 7437984: "TlvTypeMasterAgentConfigurationTransferDone", 381 | 7438496: "TlvTypeMasterAgentRetrieveTargetFile", 382 | 7438752: "TlvTypeMasterAgentRetrieveTargetFileAnswer", 383 | 7438912: "TlvTypeMasterAgentAlarmEntryID", 384 | 7439168: "TlvTypeMasterAgentAlarmEntryVersion", 385 | 7439424: "TlvTypeMasterAgentAlarmTriggerFlags", 386 | 7439776: "TlvTypeMasterAgentGetAlarmList", 387 | 7440032: "TlvTypeMasterAgentAddAlarmEntry", 388 | 7440288: "TlvTypeMasterAgentRemoveAlarmEntry", 389 | 7440544: "TlvTypeMasterAgentAlarmEntry", 390 | 7440800: "TlvTypeMasterAgentSystemStatus", 391 | 7441056: "TlvTypeMasterAgentSystemStatusRequest", 392 | 7441312: "TlvTypeMasterAgentSystemStatusReply", 393 | 7441552: "TlvTypeMasterAgentLicenseValues", 394 | 7441824: "TlvTypeMasterAgentLicenseValuesRequest", 395 | 7442080: "TlvTypeMasterAgentLicenseValuesReply", 396 | 7442592: "TlvTypeMasterAgentGetNetworkConfigurationRequest", 397 | 7442848: "TlvTypeMasterAgentSetNetworkConfigurationRequest", 398 | 7443104: "TlvTypeMasterAgentSetNetworkConfigurationReply", 399 | 7443360: "TlvTypeMasterAgentRetrieveAllowedModulesList", 400 | 7443616: "TlvTypeMasterAgentRetrieveAllowedModulesListAnswer", 401 | 7446688: "TlvTypeMasterAgentRemoveAllTargetData", 402 | 7446944: "TlvTypeMasterAgentForceDownloadRecordedData", 403 | 7447200: "TlvTypeMasterAgentTargetCreateNotification", 404 | 7447456: "TlvTypeMasterAgentMobileTargetInfoReply", 405 | 7447696: "TlvTypeMasterAgentMobileTargetInfoValues", 406 | 7450784: "TlvTypeMasterAgentAlert", 407 | 7454880: "TlvTypeMasterAgentAddUser", 408 | 7455392: "TlvTypeMasterAgentAddUserReply", 409 | 7455648: "TlvTypeMasterAgentModifyUser", 410 | 7455904: "TlvTypeMasterAgentSetUserPermission", 411 | 7456160: "TlvTypeMasterAgentSetTargetPermission", 412 | 7456400: "TlvTypeMasterAgentUserPermission", 413 | 7456656: "TlvTypeMasterAgentTargetPermission", 414 | 7456928: "TlvTypeMasterAgentUserPermissionValuePacket", 415 | 7457184: "TlvTypeMasterAgentTargetPermissionValuePacket", 416 | 7457344: "TlvTypeMasterAgentUserPermissionValueName", 417 | 7457600: "TlvTypeMasterAgentTargetPermissionValueName", 418 | 7457856: "TlvTypeMasterAgentUserPermissionValueData", 419 | 7458112: "TlvTypeMasterAgentTargetPermissionValueData", 420 | 7458464: "TlvTypeMasterAgentModifyPassword", 421 | 7458656: "TlvTypeMasterAgentMobileTargetPermissionValueName", 422 | 7458976: "TlvTypeMasterAgentUploadFile", 423 | 7459232: "TlvTypeMasterAgentUploadFileChunk", 424 | 7459488: "TlvTypeMasterAgentUploadFileDone", 425 | 7459744: "TlvTypeMasterAgentUploadFilesTransferDone", 426 | 7460000: "TlvTypeMasterAgentGetTargetModuleConfigRequest", 427 | 7460256: "TlvTypeMasterAgentRemoveFile", 428 | 7460512: "TlvTypeMasterAgentMobileProxyList", 429 | 7460768: "TlvTypeMasterAgentSMSProxyList", 430 | 7461024: "TlvTypeMasterAgentSMSProxyInfoReply", 431 | 7461280: "TlvTypeMasterAgentCallPhoneNumberList", 432 | 7461536: "TlvTypeMasterAgentCallPhoneNumberInfoReply", 433 | 7461792: "TlvTypeMasterAgentGetMobileTargetModuleConfigRequest", 434 | 7462048: "TlvTypeMasterAgentSendSMS", 435 | 7469984: "TlvTypeMasterAgentEncryptionRequired", 436 | 7470752: "TlvTypeAgentMasterComm", 437 | 7470240: "TlvTypeMasterAgentFileCompleted", 438 | 7470496: "TlvTypeMasterAgentRequestCompleted", 439 | 7471008: "TlvTypeMasterAgentRequestStatus", 440 | 7733664: "TlvTypeRelayProxyComm", 441 | 8454800: "TlvTypeRelayData", 442 | 7734176: "TlvTypeRelayDummyHeartbeat", 443 | 7668128: "TlvTypeMasterTargetComm", 444 | 7668384: "TlvTypeTargetCloseAllLiveStreaming", 445 | 7471424: "TlvTypeProxyMasterCommSig", 446 | 7471776: "TlvTypeProxyMasterComm", 447 | 7472032: "TlvTypeMasterProxyComm", 448 | 7472288: "TlvTypeProxyMasterHeartBeatAnswer", 449 | 7472544: "TlvTypeProxyMasterDisconnect", 450 | 7472704: "TlvTypeProxyMasterNotification", 451 | 7473056: "TlvTypeProxyMasterRequest", 452 | 7473312: "TlvTypeMasterProxyCommNotification", 453 | 7473568: "TlvTypeMasterCheckTargetDisconnect", 454 | 7536960: "TlvTypeProxyTargetCommSig", 455 | 7537312: "TlvTypeProxyTargetComm", 456 | 7537568: "TlvTypeProxyMasterTargetComm", 457 | 7537728: "TlvTypeProxyTargetRequestCrypto", 458 | 7538064: "TlvTypeProxyTargetAnswerCrypto", 459 | 8454544: "TlvTypeProxyData", 460 | 8458400: "TlvTypeProxyTargetDisconnect", 461 | 8458656: "TlvTypeProxyMobileTargetDisconnect", 462 | 8458912: "TlvTypeProxyDummyHeartbeat", 463 | 8459168: "TlvTypeProxyMobileDummyHeartbeat", 464 | 8585616: "TlvTypeAgentData", 465 | 8585808: "TlvTypeAgentQueryID", 466 | 8586048: "TlvTypeAgentQueryModSubmodID", 467 | 8586304: "TlvTypeAgentQueryFromDate", 468 | 8586560: "TlvTypeAgentQueryToDate", 469 | 8586816: "TlvTypeAgentQuerySortOrder", 470 | 8587136: "TlvTypeAgentQueryValueFilter", 471 | 8587328: "TlvTypeAgentUID", 472 | 8520080: "TlvTypeMasterData", 473 | 8520768: "TlvTypeMasterMode", 474 | 8521024: "TlvTypeMasterToken", 475 | 8521344: "TlvTypeMasterQueryResult", 476 | 8522368: "TlvTypeMasterAlarmString", 477 | 8651152: "TlvTypeMobileTargetData", 478 | 8651376: "TlvTypeMobileTargetHeartBeatV10", 479 | 8651632: "TlvTypeMobileTargetExtendedHeartBeatV10", 480 | 8651888: "TlvTypeMobileHeartBeatReplyV10", 481 | 8653472: "TlvTypeMobileInstalledModulesReply", 482 | 8656032: "TlvTypeMobileTargetUploadModuleRequest", 483 | 8656288: "TlvTypeMobileTargetUploadModuleReply", 484 | 8656544: "TlvTypeMobileTargetUploadModuleChunk", 485 | 8656800: "TlvTypeMobileTargetUploadModuleDoneRequest", 486 | 8657056: "TlvTypeMobileTargetUploadModuleDoneReply", 487 | 8657312: "TlvTypeMobileTargetRemoveModuleRequest", 488 | 8657568: "TlvTypeMobileTargetRemoveModuleReply", 489 | 8655008: "TlvTypeMobileTargetOfflineUploadModuleRequest", 490 | 8657824: "TlvTypeMobileTargetOfflineUploadModuleReply", 491 | 8658080: "TlvTypeMobileTargetOfflineUploadModuleChunk", 492 | 8658336: "TlvTypeMobileTargetOfflineUploadModuleDoneRequest", 493 | 8658592: "TlvTypeMobileTargetOfflineUploadModuleDoneReply", 494 | 8658848: "TlvTypeMobileTargetOfflineError", 495 | 8659104: "TlvTypeMobileTargetError", 496 | 8659360: "TlvTypeMobileTargetGetRecordedFilesRequest", 497 | 8659616: "TlvTypeMobileTargetRecordedFilesReply", 498 | 8659872: "TlvTypeMobileTargetRecordedFileDownloadRequest", 499 | 8660128: "TlvTypeMobileTargetRecordedFileDownloadReply", 500 | 8660384: "TlvTypeMobileTargetRecordedFileDownloadChunk", 501 | 8660640: "TlvTypeMobileTargetRecordedFileDownloadCompleted", 502 | 8660896: "TlvTypeMobileTargetRecordedFileDeleteRequest", 503 | 8661152: "TlvTypeMobileTargetRecordedFileDeleteReply", 504 | 8663968: "TlvTypeMobileTargetOfflineConfig", 505 | 8664224: "TlvTypeMobileTargetEmergencyConfigAsTLV", 506 | 8664432: "TlvTypeMobileTargetEmergencyConfig", 507 | 8671392: "TlvTypeMobileTargetLoadModuleRequest", 508 | 8671648: "TlvTypeMobileTargetLoadModuleReply", 509 | 8671904: "TlvTypeMobileTargetUnLoadModuleRequest", 510 | 8672160: "TlvTypeMobileTargetUnLoadModuleReply", 511 | 8675472: "TlvTypeMobileTargetHeartbeatEvents", 512 | 8675648: "TlvTypeMobileTargetHeartbeatInterval", 513 | 8675984: "TlvTypeMobileTargetHeartbeatRestrictions", 514 | 8676208: "TlvTypeConfigSMSPhoneNumber", 515 | 8676496: "TlvTypeMobileTargetPositioning", 516 | 8676672: "TlvTypeMobileTrojanUID", 517 | 8676976: "TlvTypeMobileTrojanID", 518 | 8677296: "TlvTypeMobileTargetLocationChangedRange", 519 | 8677440: "TlvTypeConfigMobileAutoRemovalDateTime", 520 | 8677808: "TlvTypeConfigOverwriteProxyAndPhones", 521 | 8678000: "TlvTypeConfigCallPhoneNumber", 522 | 8679488: "TlvTypeLocationAreaCode", 523 | 8679744: "TlvTypeCellID", 524 | 8680048: "TlvTypeMobileCountryCode", 525 | 8680304: "TlvTypeMobileNetworkCode", 526 | 8680560: "TlvTypeIMSI", 527 | 8680816: "TlvTypeIMEI", 528 | 8681072: "TlvTypeGPSLatitude", 529 | 8681328: "TlvTypeGPSLongitude", 530 | 8681520: "TlvTypeFirstHeartbeat", 531 | 8681872: "TlvTypeInstalledModules", 532 | 8683568: "TlvTypeValidGPSValues", 533 | 8389008: "TlvTypeTargetData", 534 | 8389280: "TlvTypeTargetHeartBeat", 535 | 8389680: "TlvTypeTargetKeepSessionAlive", 536 | 8390000: "TlvTypeTargetLocalIP", 537 | 8390256: "TlvTypeTargetGlobalIP", 538 | 8390448: "TlvTypeTargetState", 539 | 8390784: "TlvTypeTargetID", 540 | 8391072: "TlvTypeGetInstalledModulesRequest", 541 | 8391328: "TlvTypeInstalledModulesReply", 542 | 8391488: "TlvTypeTrojanUID", 543 | 8391808: "TlvTypeTrojanID", 544 | 8392000: "TlvTypeTrojanMaxInfections", 545 | 8392240: "TlvTypeScreenSaverOn", 546 | 8392496: "TlvTypeScreenLocked", 547 | 8392752: "TlvTypeRecordedDataAvailable", 548 | 8393024: "TlvTypeDownloadedRecordedDataTimeStamp", 549 | 8393280: "TlvTypeInstallationMode", 550 | 8393552: "TlvTypeTargetRemoveNotification", 551 | 8393792: "TlvTypeTargetPlatformBits", 552 | 8394032: "TlvTypeRemoveItselfMaxInfectionReached", 553 | 8394288: "TlvTypeRemoveItselfAtMasterRequest", 554 | 8394544: "TlvTypeRemoveItselfAtAgentRequest", 555 | 8394912: "TlvTypeRemoveItselfAtAgentReqRequest", 556 | 8395072: "TlvTypeRecordedFilesDownloadTotal", 557 | 8395328: "TlvTypeRecordedFilesDownloadProgress", 558 | 8395632: "TlvTypeTargetLicenseInfo", 559 | 8395840: "TlvTypeRemoveTargetLicenseInfo", 560 | 8396176: "TlvTypeTargetAllConfigurations", 561 | 8396960: "TlvTypeTargetError", 562 | 8401056: "TlvTypeGetTargetConfigRequest", 563 | 8401312: "TlvTypeTargetConfigReply", 564 | 8401568: "TlvTypeSetTargetConfigRequest", 565 | 8402304: "TlvTypeConfigTargetID", 566 | 8402496: "TlvTypeConfigTargetHeartbeatInterval", 567 | 8402800: "TlvTypeConfigTargetProxy", 568 | 8403008: "TlvTypeConfigTargetPort", 569 | 8403584: "TlvTypeConfigAutoRemovalDateTime", 570 | 8403776: "TlvTypeConfigAutoRemovalIfNoProxy", 571 | 8404032: "TlvTypeInternalAutoRemovalElapsedTime", 572 | 8405040: "TlvTypeConfigActiveHiding", 573 | 8409248: "TlvTypeTargetLoadModuleRequest", 574 | 8409504: "TlvTypeTargetLoadModuleReply", 575 | 8409760: "TlvTypeTargetUnLoadModuleRequest", 576 | 8410016: "TlvTypeTargetUnLoadModuleReply", 577 | 8410272: "TlvTypeTargetUploadModuleRequest", 578 | 8410528: "TlvTypeTargetUploadModuleReply", 579 | 8410784: "TlvTypeTargetUploadModuleChunk", 580 | 8411040: "TlvTypeTargetUploadModuleDoneRequest", 581 | 8411296: "TlvTypeTargetUploadModuleDoneReply", 582 | 8411552: "TlvTypeTargetRemoveModuleRequest", 583 | 8411808: "TlvTypeTargetRemoveModuleReply", 584 | 8412064: "TlvTypeTargetOfflineUploadModuleRequest", 585 | 8412320: "TlvTypeTargetOfflineUploadModuleReply", 586 | 8412576: "TlvTypeTargetOfflineUploadModuleChunk", 587 | 8412832: "TlvTypeTargetOfflineUploadModuleDoneRequest", 588 | 8413088: "TlvTypeTargetOfflineUploadModuleDoneReply", 589 | 8413344: "TlvTypeTargetOfflineError", 590 | 8413600: "TlvTypeTargetUploadError", 591 | 8417440: "TlvTypeTargetGetRecordedFilesRequest", 592 | 8417696: "TlvTypeTargetRecordedFilesReply", 593 | 8417952: "TlvTypeTargetRecordedFileDownloadRequest", 594 | 8418208: "TlvTypeTargetRecordedFileDownloadReply", 595 | 8418464: "TlvTypeTargetRecordedFileDownloadChunk", 596 | 8418720: "TlvTypeTargetRecordedFileDownloadCompleted", 597 | 8418976: "TlvTypeTargetRecordedFileDeleteRequest", 598 | 8419232: "TlvTypeTargetRecordedFileDeleteReply", 599 | 8419488: "TlvTypeTargetGetRecordedFilesRequestEx", 600 | 8419744: "TlvTypeTargetRecordedFilesReplyEx", 601 | 8420000: "TlvTypeTargetRecordedFileDeleteRequestEx", 602 | 8420256: "TlvTypeTargetRecordedFilesDownloadRequestEx", 603 | 16744768: "TlvTypeProxyConnectionBroken", 604 | 16712000: "TlvTypeTargetConnectionBroken", 605 | 16712256: "TlvTypeAgentConnectionBroken", 606 | 16712512: "TlvTypeTargetOffline", 607 | 16646544: "TlvTypePlaintext", 608 | 16646800: "TlvTypeCompression", 609 | 16647056: "TlvTypeEncryption", 610 | 16647232: "TlvTypeTargetUID", 611 | 16647536: "TlvTypeIPAddress", 612 | 16647808: "TlvTypeUserName", 613 | 16648064: "TlvTypeComputerName", 614 | 16648304: "TlvTypeLoginName", 615 | 16648560: "TlvTypePassphrase", 616 | 16648832: "TlvTypeRecordID", 617 | 16649088: "TlvTypeOwner", 618 | 16649344: "TlvTypeMetaData", 619 | 16649536: "TlvTypeModuleID", 620 | 16649856: "TlvTypeOSName", 621 | 16650048: "TlvTypeModuleSubID", 622 | 16650320: "TlvTypeErrorCode", 623 | 16650560: "TlvTypeOffset", 624 | 16650816: "TlvTypeLength", 625 | 16651088: "TlvTypeRequestID", 626 | 16651328: "TlvTypeRequestType", 627 | 16651584: "TlvTypeVersion", 628 | 16651840: "TlvTypeMachineID", 629 | 16652096: "TlvTypeMajorNumber", 630 | 16652352: "TlvTypeMinorNumber", 631 | 16652656: "TlvTypeGlobalIPAddress", 632 | 16652912: "TlvTypeASCII_Filename", 633 | 16653120: "TlvTypeFilesize", 634 | 16653392: "TlvTypeFilecount", 635 | 16653712: "TlvTypeFiledata", 636 | 16653968: "TlvTypeMD5Sum", 637 | 16654144: "TlvTypeProxyPort", 638 | 16654400: "TlvTypeStatus", 639 | 16654656: "TlvTypeUserID", 640 | 16654912: "TlvTypeGroupID", 641 | 16655168: "TlvTypePermissions", 642 | 16655424: "TlvTypeRequestCode", 643 | 16655680: "TlvTypeDataSize", 644 | 16655936: "TlvTypeKeyType", 645 | 16656240: "TlvTypeEmail", 646 | 16656432: "TlvTypeEnabled", 647 | 16656688: "TlvTypeLicensed", 648 | 16656960: "TlvTypeAudioFrequency", 649 | 16657216: "TlvTypeAudioBitsPerSample", 650 | 16657472: "TlvTypeAudioChannels", 651 | 16657728: "TlvTypeStartTime", 652 | 16657984: "TlvTypeStopTime", 653 | 16658240: "TlvTypeBitMask", 654 | 16658560: "TlvTypeTimeZone", 655 | 16658816: "TlvTypeDateTime", 656 | 16659072: "TlvTypeStartSessionDateTime", 657 | 16659328: "TlvTypeStopSessionDateTime", 658 | 16659520: "TlvTypeDateTimeRef", 659 | 16659776: "TlvTypeScheduleRepeat", 660 | 16660032: "TlvTypeUnixMasterDateTime", 661 | 16660288: "TlvTypeUnixUTCDateTime", 662 | 16660544: "TlvTypeDurationInSeconds", 663 | 16660864: "TlvTypeMasterRefTime", 664 | 16661120: "TlvTypeMasterRefTimeStart", 665 | 16661376: "TlvTypeMasterRefTimeEnd", 666 | 16661568: "TlvTypeCounter", 667 | 16661888: "TlvTypeWhiteListEntry", 668 | 16662144: "TlvTypeBlackListEntry", 669 | 16662336: "TlvTypeBlackWhiteListingMode", 670 | 16662576: "TlvTypeConfigEnabled", 671 | 16662848: "TlvTypeConfigMaxRecordingSize", 672 | 16663104: "TlvTypeConfigAudioQuality", 673 | 16663344: "TlvTypeConfigVideoBlackAndWhite", 674 | 16663616: "TlvTypeConfigVideoResolution", 675 | 16663872: "TlvTypeConfigCaptureFrequency", 676 | 16664128: "TlvTypeConfigVideoQuality", 677 | 16664384: "TlvTypeConfigFilesStandardFilter", 678 | 16664704: "TlvTypeConfigFilesCustomFilter", 679 | 16664896: "TlvTypeConfigStandardLocation", 680 | 16665216: "TlvTypeConfigCustomLocation", 681 | 16665408: "TlvTypeConfigFileChunkSize", 682 | 16665664: "TlvTypeConfigFileTransferSpeed", 683 | 16665904: "TlvTypeConfigUploadFileOverwrite", 684 | 16666160: "TlvTypeConfigDeleteOverReboot", 685 | 16666496: "TlvTypeConfigCustomLocationException", 686 | 16666752: "TlvTypeExtraData", 687 | 16667008: "TlvTypeSignature", 688 | 16667264: "TlvTypeComments", 689 | 16667520: "TlvTypeDescription", 690 | 16667776: "TlvTypeFilenameExtension", 691 | 16668032: "TlvTypeSessionType", 692 | 16668224: "TlvTypePeriod", 693 | 16668512: "TlvTypeMobileTargetUID", 694 | 16668784: "TlvTypeMobileTargetID", 695 | 16669072: "TlvTypeMobilePlaintext", 696 | 16669328: "TlvTypeMobileCompression", 697 | 16669584: "TlvTypeMobileEncryption", 698 | 16669824: "TlvTypeEncodingType", 699 | 16670576: "TlvTypePhoneNumber", 700 | 16670784: "TlvTypeConfigCustomLocationMode", 701 | 16674928: "TlvTypeNetworkInterface", 702 | 16675136: "TlvTypeNetworkInterfaceMode", 703 | 16675440: "TlvTypeNetworkInterfaceAddress", 704 | 16675696: "TlvTypeNetworkInterfaceNetmask", 705 | 16675952: "TlvTypeNetworkInterfaceGateway", 706 | 16676208: "TlvTypeNetworkInterfaceDNS_1", 707 | 16676464: "TlvTypeNetworkInterfaceDNS_2", 708 | 16677440: "TlvTypeLoginTime", 709 | 16677696: "TlvTypeLogoffTime", 710 | 16678720: "TlvTypeGeneric_Type", 711 | 16678976: "TlvTypeChecksum", 712 | 16679280: "TlvTypeCity", 713 | 16679536: "TlvTypeCountry", 714 | 16679792: "TlvTypeCountryCode", 715 | 16683072: "TlvTypeTargetType", 716 | 16683392: "TlvTypeDurationString", 717 | 8257792: "TlvTypeTestMetaTypeInvalid", 718 | 8258608: "TlvTypeTestMetaTypeBool", 719 | 8258880: "TlvTypeTestMetaTypeUInt", 720 | 8259152: "TlvTypeTestMetaTypeInt", 721 | 8259440: "TlvTypeTestMetaTypeString", 722 | 8259712: "TlvTypeTestMetaTypeUnicode", 723 | 8259984: "TlvTypeTestMetaTypeRaw", 724 | 8260256: "TlvTypeTestMetaTypeGroup", 725 | 8260416: "TlvTypeTestMemberIdentifier", 726 | 8260736: "TlvTypeTestMemberName" 727 | } 728 | 729 | 730 | def bitwise_and_bytes(a, b): 731 | result_int = int.from_bytes(a, byteorder="little") & int.from_bytes(b, byteorder="little") 732 | return result_int.to_bytes(max(len(a), len(b)), byteorder="little") 733 | 734 | 735 | def bitwise_or_bytes(a, b): 736 | result_int = int.from_bytes(a, byteorder="little") | int.from_bytes(b, byteorder="little") 737 | return result_int.to_bytes(max(len(a), len(b)), byteorder="little") 738 | 739 | 740 | def bitwise_xor_bytes(a, b): 741 | result_int = int.from_bytes(a, byteorder="little") ^ int.from_bytes(b, byteorder="little") 742 | return result_int.to_bytes(max(len(a), len(b)), byteorder="little") 743 | 744 | 745 | def find_config_entry(dex): 746 | i = 0 747 | first_marker = 16669584 # TlvTypeMobileEncryption 748 | second_marker = 8663968 # TlvTypeMobileTargetOfflineConfig 749 | 750 | while i < len(dex) - 12: 751 | marker_1 = struct.unpack_from(' 0, 823 | 'description': '' 824 | }, 825 | { 826 | 'name': 'Cell location changed', 827 | 'active': (int.from_bytes(value, byteorder="little") & 0b01000000) > 0, 828 | 'description': '' 829 | }, 830 | { 831 | 'name': 'Network changed', 832 | 'active': (int.from_bytes(value, byteorder="little") & 0b00100000) > 0, 833 | 'description': '' 834 | }, 835 | { 836 | 'name': 'Call', 837 | 'active': (int.from_bytes(value, byteorder="little") & 0b00010000) > 0, 838 | 'description': '' 839 | }, 840 | { 841 | 'name': 'Wifi connected', 842 | 'active': (int.from_bytes(value, byteorder="little") & 0b00001000) > 0, 843 | 'description': '' 844 | }, 845 | { 846 | 'name': 'Data link available', 847 | 'active': (int.from_bytes(value, byteorder="little") & 0b00000100) > 0, 848 | 'description': '' 849 | }, 850 | { 851 | 'name': 'Network activated', 852 | 'active': (int.from_bytes(value, byteorder="little") & 0b00000010) > 0, 853 | 'description': '' 854 | }, 855 | { 856 | 'name': 'Data available', 857 | 'active': (int.from_bytes(value, byteorder="little") & 0b00000001) > 0, 858 | 'description': '' 859 | } 860 | ] 861 | 862 | 863 | def parse_configuration_entries(dex, offset, length): 864 | config = [] 865 | i = offset 866 | marker = struct.unpack_from(' len(dex): 912 | return config 913 | length_to_parse_next = struct.unpack_from(' 0: 36 | try: 37 | hd = hidden_data.decode('utf-8').strip("\x00") 38 | if hd.isprintable(): 39 | b64 += hd 40 | except UnicodeDecodeError: 41 | pass 42 | 43 | if b64 == '': 44 | return None 45 | else: 46 | try: 47 | return base64.b64decode(b64) 48 | except Exception: 49 | return None 50 | -------------------------------------------------------------------------------- /python/java_parser.py: -------------------------------------------------------------------------------- 1 | # Android FinFisher 2019 obfuscated strings extraction from decompiled Java code using Procyon 2 | # Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b) 3 | # 4 | # Parse Java source files of FinSpy weaponized APK 5 | 6 | import javalang 7 | import pystache 8 | import glob 9 | import sys 10 | from javalang.tree import StatementExpression, MethodInvocation 11 | 12 | 13 | def extract_obfuscated_strings(method): 14 | obfuscated_strings = [] 15 | for statement in method.body: 16 | acc = [] 17 | if type(statement) is not StatementExpression: 18 | continue 19 | if type(statement.expression) is not MethodInvocation: 20 | continue 21 | if statement.expression.member == 'add' and statement.expression.qualifier == 'list': 22 | for child in statement.expression.arguments[0].initializer.children: 23 | for literal in child: 24 | acc.append(int(literal.value)) 25 | obfuscated_strings.append(acc) 26 | 27 | return obfuscated_strings 28 | 29 | 30 | def parse_source_code(source_dir, method_name='OOOoOoiIoIIiO0o01I1I00'): 31 | data = [] 32 | java_files = glob.glob(f'{source_dir}/**/*.java', recursive=True) 33 | for java_file in java_files: 34 | with open(java_file) as java: 35 | java_code = java.read() 36 | try: 37 | tree = javalang.parse.parse(java_code) 38 | for type in tree.types: 39 | if not type.methods: 40 | continue 41 | for method in type.methods: 42 | if method_name in method.name: 43 | # print(f'{tree.package.name}.{type.name}.{method.name}') 44 | data.append({ 45 | 'class_name': f'{tree.package.name}.{type.name}', 46 | 'strings': extract_obfuscated_strings(method) 47 | }) 48 | except Exception as e: 49 | print(java_file) 50 | print(e) 51 | return data 52 | 53 | 54 | def generate_python_db(data, output='encoded_strings.py'): 55 | with open('strings_db.tpl') as tpl_file: 56 | tpl = tpl_file.read() 57 | with open(output, mode='w') as output_file: 58 | output_file.write(pystache.render(tpl, {'data': data})) 59 | 60 | 61 | if __name__ == '__main__': 62 | if len(sys.argv) != 2: 63 | print(f'Usage: python {sys.argv[0]} ') 64 | sys.exit(1) 65 | 66 | source_dir = str(sys.argv[1]) 67 | data = parse_source_code(source_dir) 68 | generate_python_db(data) 69 | -------------------------------------------------------------------------------- /python/requirements.txt: -------------------------------------------------------------------------------- 1 | javalang 2 | pystache 3 | yara-python 4 | six==1.12.0 5 | git+https://github.com/U039b/smalisca.git 6 | objutils -------------------------------------------------------------------------------- /python/string_decoder.py: -------------------------------------------------------------------------------- 1 | # Decode Android FinFisher 2019 obfuscated strings 2 | # Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b) 3 | 4 | from strings import STRINGS 5 | 6 | 7 | def decode_array(encoded, index): 8 | mask = [102, 101, 100, 99, 98, 97, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48] 9 | if index % 2 == 0: 10 | mask = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102] 11 | 12 | decoded = [] 13 | counter = 0 14 | for e in encoded: 15 | decoded.append(chr(e ^ mask[counter % len(mask)])) 16 | counter += 1 17 | 18 | return ''.join(decoded) 19 | 20 | 21 | def decode_string(strings, class_name, index): 22 | if class_name not in strings: 23 | return '' 24 | 25 | encoded = strings[class_name][index] 26 | return decode_array(encoded, index) 27 | 28 | 29 | if __name__ == '__main__': 30 | a = [ 31 | [0x1F, 67, 0x5F, 68, 68, 27, 69, 0x5F], 32 | [73, 1, 5, 23, 3, 78, 85, 87, 84, 87, 89, 27, 71, 0x5F, 65, 0x1F, 21, 28, 74, 2, 18, 10], 33 | [81, 0x5F, 86, 65, 91, 92, 82, 25, 91, 86, 15, 22, 6, 10, 17, 72, 0x73, 94, 92, 71, 81, 77, 66], 34 | [1, 0, 16, 51, 3, 2, 82, 89, 80, 83, 120, 85, 93, 83, 86, 85, 20], 35 | [81, 0x5F, 86, 65, 91, 92, 82, 25, 91, 86, 15, 22, 6, 10, 17, 72, 0x40, 92, 28, 99, 85, 86, 93, 86, 0x5F, 92, 36 | 44, 3, 13, 5, 2, 3, 66], 37 | [1, 0, 16, 51, 3, 2, 82, 89, 80, 83, 0x7C, 90, 85, 93], 38 | [83, 94, 0x5F, 29, 93, 91, 69, 67, 89, 85, 13, 7, 17], 39 | [7, 11, 0, 17, 13, 8, 93, 22, 84, 89, 91, 0x40, 86, 92, 69, 30, 22, 8, 74, 51, 3, 2, 82, 89, 80, 83, 0x7C, 90, 40 | 85, 93], 41 | [81, 65, 66, 0x5F, 93, 86, 87, 67, 81, 86, 15, 43, 13, 2, 10], 42 | [7, 11, 0, 17, 13, 8, 93, 22, 84, 89, 91, 0x40, 86, 92, 69, 30, 22, 8, 74, 34, 18, 17, 85, 81, 84, 87, 65, 93, 43 | 92, 92, 120, 94, 0, 10], 44 | [67, 94, 71, 65, 87, 80, 0x72, 94, 74], 45 | [73, 23, 9, 20, 16, 0x4F, 74, 80], 46 | [83, 94, 0x5F, 29, 93, 91, 69, 67, 89, 85, 13, 7, 17], 47 | [9, 23, 3, 77, 26, 12, 85, 72, 66, 69, 93, 26, 69, 1], 48 | [0x1F, 67, 0x5F, 29, 71, 93], 49 | [73, 7, 5, 16, 7, 0x4F, 88, 72, 92], 50 | [0x1F, 66, 75, 0x40, 0x40, 80, 91, 24], 51 | ] 52 | for i in range(len(a)): 53 | print(decode_array(a[i], i)) 54 | # for class_name in STRINGS: 55 | # for i in range(len(STRINGS[class_name])): 56 | # decoded_string = decode_string(STRINGS, class_name, i).strip() 57 | # print(f'{class_name};{i};"{decoded_string}"') 58 | -------------------------------------------------------------------------------- /python/strings_db.tpl: -------------------------------------------------------------------------------- 1 | # Android FinFisher 2019 obfuscated strings extracted from decompiled Java code using Procyon 2 | # Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b) 3 | 4 | STRINGS = { 5 | {{#data}} 6 | '{{class_name}}': [ 7 | {{#strings}} 8 | {{{.}}}, 9 | {{/strings}} 10 | ], 11 | {{/data}} 12 | } 13 | -------------------------------------------------------------------------------- /python/yara/FinSpy.yar: -------------------------------------------------------------------------------- 1 | rule FinSpy_ConfigInAPK : android apkhideconfig finspy 2 | { 3 | meta: 4 | description = "Detect FinFisher FinSpy configuration in APK file. Probably the original FinSpy version." 5 | date = "2020/08/05" 6 | reference = "https://github.com/devio/FinSpy-Tools" 7 | author = "Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b)" 8 | 9 | strings: 10 | $re = /\x50\x4B\x01\x02[\x00-\xff]{32}[A-Za-z0-9+\/]{6}/ 11 | 12 | condition: 13 | uint32(0) == 0x04034b50 and $re and (#re > 50) 14 | } 15 | 16 | rule FinSpy_DexDen : android dexhideconfig finspy 17 | { 18 | meta: 19 | description = "Detect FinFisher FinSpy configuration in DEX file. Probably a newer FinSpy variant." 20 | date = "2020/08/05" 21 | author = "Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b)" 22 | 23 | strings: 24 | $config_1 = { 90 5b fe 00 } 25 | $config_2 = { 70 37 80 00 } 26 | $config_3 = { 40 38 80 00 } 27 | $config_4 = { a0 33 84 } 28 | $config_5 = { 90 79 84 00 } 29 | 30 | condition: 31 | uint16(0) == 0x6564 and 32 | #config_1 >= 2 and 33 | #config_2 >= 2 and 34 | #config_3 >= 2 and 35 | #config_4 >= 2 and 36 | #config_5 >= 2 37 | } 38 | 39 | rule FinSpy_TippyTime: finspyTT 40 | { 41 | meta: 42 | description = "Detect FinFisher FinSpy 'TippyTime' variant." 43 | date = "2020/08/05" 44 | author = "Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b)" 45 | strings: 46 | $config_1 = { 90 5b fe 00 } 47 | $config_2 = { 70 37 80 00 } 48 | $config_3 = { 40 38 80 00 } 49 | $config_4 = { a0 33 84 } 50 | $config_5 = { 90 79 84 00 } 51 | $timestamp = { 95 E9 D1 5B } 52 | 53 | condition: 54 | uint16(0) == 0x6564 and 55 | $timestamp and 56 | $config_1 and 57 | $config_2 and 58 | $config_3 and 59 | $config_4 and 60 | $config_5 61 | } 62 | 63 | rule FinSpy_TippyPad: finspyTP 64 | { 65 | meta: 66 | description = "Detect FinFisher FinSpy 'TippyPad' variant." 67 | date = "2020/08/05" 68 | author = "Esther Onfroy a.k.a U+039b - *@0x39b.fr (https://twitter.com/u039b)" 69 | strings: 70 | $pad_1 = "0123456789abcdef" 71 | $pad_2 = "fedcba9876543210" 72 | 73 | condition: 74 | uint16(0) == 0x6564 and 75 | #pad_1 > 50 and 76 | #pad_2 > 50 77 | } 78 | -------------------------------------------------------------------------------- /samples/9c8bf89d043ba3ed802d6d4f9b290747d12822402d61065adfbcb48a740a47b8.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveLabAgency/FinSpy-for-Android/78158322169922c72f833402e6485abc7ff7a33a/samples/9c8bf89d043ba3ed802d6d4f9b290747d12822402d61065adfbcb48a740a47b8.apk -------------------------------------------------------------------------------- /samples/WIFI.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveLabAgency/FinSpy-for-Android/78158322169922c72f833402e6485abc7ff7a33a/samples/WIFI.apk -------------------------------------------------------------------------------- /tables.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveLabAgency/FinSpy-for-Android/78158322169922c72f833402e6485abc7ff7a33a/tables.ods --------------------------------------------------------------------------------