def target(self, queue): files = common.java_files global parser, tree, filepath parser = plyj.Parser() tree = '' res = [] count = 0 for f in files: count += 1 pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(files))) filepath = str(f) try: # Parse the java file to an AST tree = parser.parse_file(f) except Exception as e: common.logger.exception("Unable to parse the file and generate as AST. Error: " + str(e)) continue try: for import_decl in tree.import_declarations: # Check if DexClassLoader is called in the import statement; example import dalvik.system.DexClassLoader if self.DEX_CLASS_LOADER in import_decl.name.value: for type_decl in tree.type_declarations: # Check class declaration within the java source code if type(type_decl) is m.ClassDeclaration: # Traverse through every field declared in the class for fields in type_decl.body: try: self.recursive_classloader_function(fields, f, res) except Exception as e: common.logger.error("Unable to run class loader plugin " + str(e)) except Exception as e: common.logger.debug("Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue try: for type_decl in tree.type_declarations: # Check class declaration within the java source code if type(type_decl) is m.ClassDeclaration: # Traverse through every field declared in the class for fields in type_decl.body: try: self.recursive_register_receiver_function(fields, f, res) except Exception as e: common.logger.error("Unable to run register receiver function plugin " + str(e)) except Exception as e: common.logger.debug("Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue # Arrange the Broadcast Receivers created Dynamically in column format and store it in the variable -> Broadcast_Receiver br_list = "\n".join(receivers_list) if receivers_list: # Report the issue in the file and display it on the terminal PluginUtil.reportWarning(filepath, broadcast_receiver(br_list), res) queue.put(res)
def testReportIssue1(): res = [] PluginUtil.reportWarning('fileName', 'details', res) assert len(res) == 2 assert res[0].getCategory() == ExploitType.PLUGIN assert res[0].getSeverity() == Severity.WARNING assert res[0].getFile() == 'fileName' assert res[0].getDetails() == 'details' assert res[1].getLevel() == Severity.WARNING assert res[1].getData() == 'details'
def target(self, queue): f = str(common.manifest) res = [] count = 0 ordered_broadcast = [] path_variable_list =[] launch_mode_list =[] global fileName # full path to app manifest fileName = qarkMain.find_manifest_in_source() receivers = self.UserCreatedReceivers() for receiver in receivers: if "exported" and "true" in str(receiver): if not any(re.findall(self.PRIORITY_REGEX, str(receiver))): ordered_broadcast.append(str(receiver)) # Arrange exported broadcast receiver without priority set in column format list_orderedBR = " \n".join(ordered_broadcast) if ordered_broadcast: PluginUtil.reportWarning(fileName, self.OrderedBroadcastIssueDetails(list_orderedBR), res) for line in f.splitlines(): count += 1 # update progress bar pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(f.splitlines()))) if any(re.findall(self.PATH_USAGE, line)): path_variable_list.append(line) if any(re.findall(self.LAUNCH_MODE, line)): launch_mode_list.append(line) if any(re.findall(self.TASK_REPARENTING, line)): PluginUtil.reportInfo(fileName, self.TaskReparentingIssue(fileName), res) # Arrange identified path variable and launch mode usage in column format path_variable = " \n".join(path_variable_list) launch_mode_variable = "\n".join(launch_mode_list) if path_variable_list: PluginUtil.reportWarning(fileName, self.PathUsageIssue(path_variable), res) if launch_mode_list: PluginUtil.reportInfo(fileName, self.LaunchModeIssue(launch_mode_variable), res) # Check for google safebrowsing API if "WebView" in f.splitlines(): if "EnableSafeBrowsing" and "true" not in f.splitlines(): PluginUtil.reportInfo(fileName, self.SafebrowsingIssueDetails(fileName), res) # send all results back to main thread queue.put(res)
def target(self, queue): files = common.java_files global parser, tree, fileName parser = plyj.Parser() tree = '' res = [] #List of Broadcast Receiver list_BR = [] count = 0 for f in files: count += 1 pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(files))) fileName = str(f) try: tree = parser.parse_file(f) except Exception: continue try: for import_decl in tree.import_declarations: if self.DEX_CLASS_LOADER in import_decl.name.value: if self.CLASS_LOADER in str(tree): PluginUtil.reportInfo( fileName, self.DexClassLoaderIssueDetails(fileName), res) # This will check if app register's a broadcast receiver dynamically if self.DYNAMIC_BROADCAST_RECEIVER in str(tree): list_BR.append(fileName) except Exception: continue # Arrange the Broadcast Receivers created Dynamically in column format and store it in the variable -> Broadcast_Receiver Broadcast_Receiver = "\n".join(list_BR) if list_BR: PluginUtil.reportWarning( fileName, self.BroadcastReceiverIssueDetails(Broadcast_Receiver), res) queue.put(res)
def target(self, queue): files = common.java_files parser = plyj.Parser() global filepath, tree tree = '' res = [] issues_list = [] count = 0 for f in files: count += 1 pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(files))) filepath = str(f) try: tree = parser.parse_file(f) except Exception as e: common.logger.exception( "Unable to parse the file and generate as AST. Error: " + str(e)) continue try: global url url = [] for import_decl in tree.import_declarations: # Check import statements with value declared as WebView and WebSettings for the potential use of web views if 'WebView' in import_decl.name.value or 'WebSettings' in import_decl.name.value: with open(filepath, 'r') as r: data = r.read() if PluginUtil.contains(self.JAVASCRIPT_ENABLED, data): if PluginUtil.contains(self.MIXED_CONTENT, data): PluginUtil.reportWarning( filepath, mixed_content(filepath), res) if "setAllowFileAccess(false)" or "setAllowContentAccess(false)" not in data: if filepath not in issues_list: issues_list.append(filepath) if PluginUtil.contains(self.LOAD_URL_HTTP, data): PluginUtil.reportWarning(filepath, load_http_urls(filepath), res) break except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue try: for import_decl in tree.import_declarations: if 'WebView' in import_decl.name.value or 'WebSettings' in import_decl.name.value: for type_decl in tree.type_declarations: # Check for class declaration in java source code and traverse further down the AST to find method names if type(type_decl) is m.ClassDeclaration: for fields in type_decl.body: if type(fields) is m.MethodDeclaration: if 'shouldOverrideUrlLoading' in fields.name: if 'true' not in str(fields.body): PluginUtil.reportWarning( filepath, url_override(filepath), res) break else: continue if 'shouldInterceptRequest' in fields.name: if 'null' in str(fields.body): PluginUtil.reportWarning( filepath, intercept_request( filepath), res) break else: continue break except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue if issues_list: issue_name = " \n".join(issues_list) PluginUtil.reportInfo(filepath, secure_content(issue_name), res) queue.put(res)
def target(self, queue): raw_file = str(common.manifest) # Split the raw file content into each individual line split_line = raw_file.splitlines() count = 0 # Create a list for each object ordered_broadcast, path_variable_list, launch_mode_list, api_key_list, res = ([] for _ in xrange(5)) global file_name # full path to app manifest file_name = qarkMain.find_manifest_in_source() receivers = self.UserCreatedReceivers() for receiver in receivers: if "exported" in str(receiver) and "true" in str(receiver): if not re.search(self.PRIORITY_REGEX, str(receiver)): ordered_broadcast.append(str(receiver)) # Arrange exported broadcast receiver without priority set in column format list_orderedBR = " \n".join(ordered_broadcast) if ordered_broadcast: PluginUtil.reportWarning(file_name, list_orderedBR, res) for line in split_line: count += 1 # update progress bar pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(split_line))) if re.search(self.PATH_USAGE, line): path_variable_list.append(line) if re.search(self.LAUNCH_MODE, line): launch_mode_list.append(line) if re.search(self.TASK_REPARENTING, line): PluginUtil.reportInfo(file_name, task_reparenting(file_name), res) if re.match(self.API_KEY_REGEX, line): # Check if special character is present in the line. If "Yes, then ignore. if not re.match(self.SPECIAL_CHAR_REGEX, line) and line not in api_key_list: api_key_list.append(line) # Additional check for hardcoded api keys which matches the syntax most commonly used with google API_KEY if re.search(self.HARDCODED_API_KEY, line) and line not in api_key_list: api_key_list.append(line) # Arrange identified path variable and launch mode usage in column format path_variable = " \n".join(path_variable_list) launch_mode_variable = "\n".join(launch_mode_list) api_key_variable = "\n".join(api_key_list) if path_variable_list: PluginUtil.reportWarning(file_name, path_usage(path_variable), res) if launch_mode_list: PluginUtil.reportInfo(file_name, task_launch_mode(launch_mode_variable), res) if api_key_list: PluginUtil.reportInfo(file_name, hardcoded_api_key(api_key_variable), res) # Check for google safe browsing API if "WebView" in split_line: if "EnableSafeBrowsing" not in split_line and "true" not in split_line: PluginUtil.reportInfo(file_name, google_safe_browsing(file_name), res) # send all results back to main thread queue.put(res)
def target(self, queue): files = common.java_files parser = plyj.Parser() global filepath, tree tree = '' res = [] issues_list = [] count = 0 for f in files: count += 1 pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(files))) filepath = str(f) try: tree = parser.parse_file(f) except Exception as e: common.logger.exception( "Unable to parse the file and generate as AST. Error: " + str(e)) continue try: global url url = [] for import_decl in tree.import_declarations: # Check import statements with value declared as WebView and WebSettings for the potential use of web views if 'WebView' in import_decl.name.value or 'WebSettings' in import_decl.name.value: with open(filepath, 'r') as r: data = r.read() if PluginUtil.contains(self.JAVASCRIPT_ENABLED, data): if PluginUtil.contains(self.MIXED_CONTENT, data): PluginUtil.reportWarning(filepath, mixed_content(filepath), res) if "setAllowFileAccess(false)" or "setAllowContentAccess(false)" not in data: if filepath not in issues_list: issues_list.append(filepath) if PluginUtil.contains(self.LOAD_URL_HTTP, data): PluginUtil.reportWarning(filepath, load_http_urls(filepath), res) break except Exception as e: common.logger.debug("Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue try: for import_decl in tree.import_declarations: if 'WebView' in import_decl.name.value or 'WebSettings' in import_decl.name.value: for type_decl in tree.type_declarations: # Check for class declaration in java source code and traverse further down the AST to find method names if type(type_decl) is m.ClassDeclaration: for fields in type_decl.body: if type(fields) is m.MethodDeclaration: if 'shouldOverrideUrlLoading' in fields.name: if 'true' not in str(fields.body): PluginUtil.reportWarning(filepath, url_override(filepath), res) break else: continue if 'shouldInterceptRequest' in fields.name: if 'null' in str(fields.body): PluginUtil.reportWarning(filepath, intercept_request(filepath), res) break else: continue break except Exception as e: common.logger.debug("Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue if issues_list: issue_name = " \n".join(issues_list) PluginUtil.reportInfo(filepath, secure_content(issue_name), res) queue.put(res)
def target(self, queue): f = str(common.manifest) res = [] count = 0 ordered_broadcast = [] path_variable_list = [] launch_mode_list = [] global fileName # full path to app manifest fileName = qarkMain.find_manifest_in_source() receivers = self.UserCreatedReceivers() for receiver in receivers: if "exported" and "true" in str(receiver): if not any(re.findall(self.PRIORITY_REGEX, str(receiver))): ordered_broadcast.append(str(receiver)) # Arrange exported broadcast receiver without priority set in column format list_orderedBR = " \n".join(ordered_broadcast) if ordered_broadcast: PluginUtil.reportWarning( fileName, self.OrderedBroadcastIssueDetails(list_orderedBR), res) for line in f.splitlines(): count += 1 # update progress bar pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(f.splitlines()))) if any(re.findall(self.PATH_USAGE, line)): path_variable_list.append(line) if any(re.findall(self.LAUNCH_MODE, line)): launch_mode_list.append(line) if any(re.findall(self.TASK_REPARENTING, line)): PluginUtil.reportInfo(fileName, self.TaskReparentingIssue(fileName), res) # Arrange identified path variable and launch mode usage in column format path_variable = " \n".join(path_variable_list) launch_mode_variable = "\n".join(launch_mode_list) if path_variable_list: PluginUtil.reportWarning(fileName, self.PathUsageIssue(path_variable), res) if launch_mode_list: PluginUtil.reportInfo(fileName, self.LaunchModeIssue(launch_mode_variable), res) # Check for google safebrowsing API if "WebView" in f.splitlines(): if "EnableSafeBrowsing" and "true" not in f.splitlines(): PluginUtil.reportInfo(fileName, self.SafebrowsingIssueDetails(fileName), res) # send all results back to main thread queue.put(res)
def target(self, queue): global filepath, tree files = common.java_files parser = plyj.Parser() tree = '' external_pub_dir, external_media, external_storage, res = ( [] for _ in xrange(4)) count = 0 for f in files: count += 1 pub.sendMessage('progress', bar=self.name, percent=round(count * 100 / len(files))) filepath = str(f) try: tree = parser.parse_file(f) except Exception as e: common.logger.exception( "Unable to parse the file and generate as AST. Error: " + str(e)) continue try: for import_decl in tree.import_declarations: if 'File' in import_decl.name.value: with open(filepath, 'r') as fr: file_body = fr.read() if PluginUtil.contains(self.CHECK_EXTERNAL_STORAGE, file_body): external_storage.append(filepath) break if PluginUtil.contains(self.CHECK_EXTERNAL_MEDIA, file_body): external_media.append(filepath) break if PluginUtil.contains(self.CHECK_PUBLIC_DIR, file_body): external_pub_dir.append(filepath) break except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue # Store the content obtained above in a column format storage = "\n".join(external_storage) media = "\n".join(external_media) pub_dir = "\n".join(external_pub_dir) if external_storage: PluginUtil.reportWarning(filepath, check_external_storage(storage), res) if external_media: PluginUtil.reportWarning(filepath, check_media_directory(media), res) if external_pub_dir: PluginUtil.reportWarning(filepath, check_public_directory(pub_dir), res) queue.put(res)