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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #6
0
    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)
Exemple #7
0
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',
Exemple #8
0
    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)
Exemple #9
0
    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)
Exemple #10
0
    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)