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 global filepath, tree 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: 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 'Service' in import_decl.name.value: with open(filepath, 'r') as r: data = r.read() if PluginUtil.contains(self.CHECK_PERMISSION, data): PluginUtil.reportInfo(filepath, check_permission(filepath), res) break if PluginUtil.contains(self.ENFORCE_PERMISSION, data): PluginUtil.reportInfo(filepath, enforce_permission(filepath), res) break except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue queue.put(res)
def target(self, queue): files = common.java_files global filepath, tree 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: 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 Intent is called in the import statement if 'Intent' in import_decl.name.value: with open(filepath, 'r') as r: file_body = r.read() if PluginUtil.contains(self.NEW_TASK, file_body): PluginUtil.reportInfo(filepath, new_task(filepath), res) break if PluginUtil.contains(self.MULTIPLE_TASK_TASK, file_body): PluginUtil.reportInfo(filepath, multiple_task(filepath), res) break except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue queue.put(res)
def target(self, queue): files = common.java_files global parser parser = plyj.Parser() global tree global fileName tree = '' res = [] 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: global url url = [] for import_decl in tree.import_declarations: if 'HttpURLConnection' in import_decl.name.value or 'URL' in import_decl.name.value: textfile = str(open(fileName, 'r').read()) search = "http://" http_result = re.findall('\\b' + search + '\\b', textfile) if http_result: url = re.findall(self.http_url_regex, textfile) http_url_list = " \n".join(url) PluginUtil.reportInfo( fileName, self.HardcodedHTTPUrlsIssueDetails( (fileName, http_url_list)), res) break else: continue except Exception: continue queue.put(res)
def target(self, queue): files = common.java_files global parser, tree, filepath parser = plyj.Parser() tree = '' global res 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: 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 type_decl in tree.type_declarations: if type(type_decl) is m.ClassDeclaration: for fields in type_decl.body: try: self.recursive_insecure_call_function( fields, f, res) except Exception as e: common.logger.exception( "Unable to run insecure function plugin " + str(e)) except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue 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)
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.''' import lib.plyj.parser as plyj from modules import common, report from modules import filters import lib.plyj.model as m import re, sys import logging from report import ReportIssue from modules.common import Severity, ReportIssue from createExploit import ExploitType from lib.pubsub import pub from common import terminalPrint parser = plyj.Parser() tree = '' def main(queue): global parser global tree results = [] count = 0 if common.minSdkVersion < 19: weak_rng_warning(results) find_key_files(results) for j in common.java_files: count = count + 1 pub.sendMessage('progress',
def target(self, queue): files = common.java_files global filepath, tree parser = plyj.Parser() total_debug_logs, total_verbose_logs, debug_logs, verbose_logs, verbose_logs_list, res, \ debug_logs_list, discovered_debug_logs, discovered_verbose_logs = ([] for _ in xrange(9)) tree = '' 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 # Traverse down the tree to find out verbose or debug logs try: for type_decl in tree.type_declarations: if type(type_decl) is m.ClassDeclaration: for fields in type_decl.body: if type(fields) is m.MethodDeclaration: # Check if the app is send verbose logging message if str(fields.name) == 'v': verbose_logs.append(str(fields.name)) if filepath not in discovered_verbose_logs: discovered_verbose_logs.append( filepath) # Check if the app is send debug logging message elif str(fields.name) == 'd': debug_logs.append(str(fields.name)) if filepath not in discovered_debug_logs: discovered_debug_logs.append(filepath) except Exception as e: common.logger.debug( "Plyj parser failed while parsing the file: " + filepath + "\nError" + str(e)) continue # Join all the filename and path containing debug and verbose logging debug_logs_path = " \n".join(discovered_debug_logs) verbose_logs_path = " \n".join(discovered_verbose_logs) queue.put(res) # Display the file paths of all discovered logs if discovered_debug_logs: x = len(debug_logs) PluginUtil.reportInfo(filepath, debug_log_issues(debug_logs_path, x), res) if discovered_verbose_logs: y = len(verbose_logs) PluginUtil.reportInfo(filepath, verbose_log_issues(verbose_logs_path, y), res) # Sometimes Log functions may be called from a constructor and hence maybe skipped by tree # if len(debug_logs) == 0 and len(verbose_logs) == 0: for f in files: with open(f, 'r') as fi: filename = fi.read() filepath = str(f) find_debug_logs = re.findall(self.debug_regex, filename) find_verbose_logs = re.findall(self.verbose_regex, filename) if find_debug_logs: total_debug_logs.append(str(find_debug_logs)) if filepath not in debug_logs_list: debug_logs_list.append(filepath) if find_verbose_logs: total_verbose_logs.append(str(find_verbose_logs)) if filepath not in verbose_logs_list: verbose_logs_list.append(filepath) debug_path = " \n".join(debug_logs_list) verbose_path = " \n".join(verbose_logs_list) if total_debug_logs: x = len(total_debug_logs) PluginUtil.reportInfo(filepath, debug_log_issues(debug_path, x), res) if total_verbose_logs: y = len(total_verbose_logs) PluginUtil.reportInfo(filepath, verbose_log_issues(verbose_path, y), res)
def target(self, queue): files = common.java_files global parser, tree, fileName, verbose, debug, debug_logs_path, verbose_logs_path parser = plyj.Parser() debug_logs = [] verbose_logs = [] discovered_debug_logs = [] discovered_verbose_logs = [] res = [] tree = '' 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 as e: continue # Traverse down the tree to find out verbose or debug logs try: for type_decl in tree.type_declarations: if type(type_decl) is m.ClassDeclaration: for t in type_decl.body: if type(t) is m.MethodDeclaration: if str(t.name) == 'v': verbose_logs.append(str(t.name)) discovered_verbose_logs.append(fileName) elif str(t.name) == 'd': debug_logs.append(str(t.name)) discovered_debug_logs.append(fileName) except Exception: continue # Join all the filename and path containing debug and verbose logging debug_logs_path = " \n".join(discovered_debug_logs) verbose_logs_path = " \n".join(discovered_verbose_logs) queue.put(res) if discovered_debug_logs: PluginUtil.reportInfo(fileName, self.DebugLogsIssueDetails(debug_logs_path), res) if discovered_verbose_logs: PluginUtil.reportInfo( fileName, self.VerboseLogsIssueDetails(verbose_logs_path), res) # Provide the count of verbose/debug logs. # Written separately so that issue description is mentioned once and not repeated for each warning. if debug_logs or verbose_logs: x = str(len(debug_logs)) y = str(len(verbose_logs)) PluginUtil.reportInfo(fileName, self.LogIssueDetails((x, y)), res) global reg, reg1, filename len_reg = [] len_reg1 = [] # Sometimes Log functions may be called from a constructor and hence maybe skipped by tree if len(debug_logs) == 0 and len(verbose_logs) == 0: for f in files: with open(f, 'r') as fi: filename = fi.read() file_name = str(f) reg = re.findall(self.debug_regex, filename) reg1 = re.findall(self.verbose_regex, filename) if reg: len_reg.append(str(reg)) PluginUtil.reportInfo( filename, self.DebugLogsIssueDetails(file_name), res) if reg1: len_reg1.append(str(reg1)) PluginUtil.reportInfo( filename, self.VerboseLogsIssueDetails(file_name), res) if len_reg or len_reg1: x = str(len(len_reg)) y = str(len(len_reg1)) PluginUtil.reportInfo(filename, self.LogIssueDetails((x, y)), 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)