Example #1
0
class Run(SurgicalCmd):
    def __init__(self, vm, vmx):
        SurgicalCmd.__init__(self)
        self.logger = Logger()
        self.t = Terminal()
        self.u = Util()
        self.vm = vm
        self.vmx = vmx
        self.methods = self.vm.get_methods()
        self.intent = IntentModule()
        self.zip = ZipModule()
        self.socket = SocketModule()
        self.system = SystemModule()
        self.modules = [
            m for m in self.zip, self.intent, self.socket, self.system
        ]
        self.target_module = None
        self.methods_api_usage = list()

    def do_modules(self, args):
        """
        List and select target API modules.

        := modules list
        := modules select
        """

        # Locals
        selection = None

        try:
            if args.split()[0] == "list":
                if self.modules:
                    print("\n")
                    for m in self.modules:
                        if m:
                            print(self.t.cyan("\t--> {}".format(m.name)))
                    print("\n")
            if args.split()[0] == "select":
                if self.modules:
                    selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select module : ")
                    for m in self.modules:
                        if m:
                            if selection == m.name:
                                self.target_module = m
                                self.logger.surgical_log(
                                    "info",
                                    "{} module selected (!)".format(m.name))
        except Exception as e:
            SurgicalError(e.message)

    def do_api(self, args):
        """
        List and select methods from a given loaded API module

        := api list
        := api select
        := api analyzed list
        := api analyzed select
        """

        # Locals
        class_selection = None
        method_selection = None
        surgical_lib = None

        try:
            # List the available API methods from the target module
            if args.split()[0] == "list":
                if self.target_module:
                    print("\n")
                    for k, v in self.target_module.model.values.items():
                        print("\n")
                        for m in v:
                            print(
                                self.t.cyan("\t--> {} : {} : {}".format(
                                    self.target_module.name,
                                    k.split(".")[-1], m)))
                    print("\n")
                else:
                    self.logger.surgical_log(
                        "info", "Target module has not been loaded (!)")
            # Select an API method from the target module
            elif args.split()[0] == "select":
                if self.target_module:
                    # TODO Consider building a wrapper around raw_input()
                    class_selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select class : ")
                    method_selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select method : ")
                    for k, v in self.target_module.model.values.items():
                        # This is so we can support classes with identical
                        # method names --> Ex: java.util.zip.ZipFile
                        if class_selection == k.split(".")[-1]:
                            for m in v:
                                if m == method_selection:
                                    self.logger.surgical_log(
                                        "info", "Analyzing ...")
                                    from core.brains.surgical.lib.libsurgical import SurgicalLib
                                    # Begin processing and return the results
                                    # from the selected api
                                    surgical_lib = SurgicalLib(
                                        self.target_module, self.vmx, self.vm,
                                        k, method_selection, self.methods)
                                    # methods_api_usage will contain a list of
                                    # tuples
                                    self.methods_api_usage = surgical_lib.search(
                                    )
                                else:
                                    self.logger.surgical_log(
                                        "warn", "Method not found (!)")
            # Analyze the processed method list
            elif args.split()[0] == "analyzed":
                # List the methods that have been processed
                if args.split()[1] == "list":
                    if self.methods_api_usage:
                        print("\n")
                        for m in self.methods_api_usage:
                            print(
                                self.t.cyan("\t--> {} -> {} ".format(
                                    m[0].class_name, m[0].name)))
                        print("\n")
                    else:
                        SurgicalError("API usage not found (!)")
                # Select from the processed method list
                elif args.split()[1] == "select":
                    if self.methods_api_usage:
                        selection = raw_input(
                            self.t.yellow("[{}] ".format(datetime.now())) +
                            "Select method : ")
                        for m in self.methods_api_usage:
                            if selection == m[0].name:
                                print("\n")
                                print(
                                    self.t.cyan("\t--> Class : {}".format(
                                        m[0].class_name)))
                                print(
                                    self.t.cyan("\t\t--> Method : {}".format(
                                        m[0].name)))
                                print(
                                    self.t.cyan(
                                        "\t\t\t --> XREFS ###########"))
                                self.u.print_xref("T",
                                                  m[1].method.XREFto.items)
                                self.u.print_xref("F",
                                                  m[1].method.XREFfrom.items)
                                print("\n")
                                print(
                                    highlight(m[2], JavaLexer(),
                                              TerminalFormatter()))
                    else:
                        SurgicalError("API usage not found (!)")
        except Exception as e:
            SurgicalError(e.message)
Example #2
0
class Run(SurgicalCmd):
    def __init__(self, vm, vmx):
        SurgicalCmd.__init__(self)
        self.logger = Logger()
        self.t = Terminal()
        self.u = Util()
        self.vm = vm
        self.vmx = vmx
        self.methods = self.vm.get_methods()
        self.web = None
        self.intent = IntentModule()
        self.modules = [m for m in self.web, self.intent]
        self.target_module = None
        self.methods_api_usage = list()

    def do_modules(self, args):
        """
        List and select target API modules.

        := modules list
        := modules select
        """
        try:
            if args.split()[0] == "list":
                if self.modules:
                    print("\n")
                    for m in self.modules:
                        if m:
                            print(self.t.cyan("\t--> {}".format(m.name)))
                    print("\n")
            if args.split()[0] == "select":
                if self.modules:
                    selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select module : ")
                    for m in self.modules:
                        if m:
                            if selection == m.name:
                                self.target_module = m
                                self.logger.surgical_log(
                                    "info",
                                    "{} module selected (!)".format(m.name))
        except Exception as e:
            SurgicalError(e.message)

    def do_api(self, args):
        """
        List and select methods from a given loaded API module

        := api list
        := api select
        := api analyzed list
        := api analyzed select
        """
        try:
            # List the available API methods from the target module
            if args.split()[0] == "list":
                if self.target_module:
                    print("\n")
                    for k, v in self.target_module.model.values.items():
                        for m in v:
                            print(
                                self.t.cyan("\t--> {} : {}".format(
                                    self.target_module.name, m)))
                    print("\n")
                else:
                    self.logger.surgical_log(
                        "info", "Target module has not been loaded (!)")
            # Select an API method from the target module
            elif args.split()[0] == "select":
                if self.target_module:
                    selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select method : ")
                    for k, v in self.target_module.model.values.items():
                        for m in v:
                            if m == selection:
                                self.logger.surgical_log(
                                    "info", "Searching ...")
                                from core.brains.surgical.lib.libsurgical import SurgicalLib
                                # Begin processing and return the results fomr the selected method
                                surgical_lib = SurgicalLib(
                                    self.target_module, self.vmx, self.vm, k,
                                    selection, self.methods)
                                # methods_api_usage will contain a list of tuples
                                self.methods_api_usage = surgical_lib.search()
                            else:
                                self.logger.surgical_log(
                                    "warn", "Method not found (!)")
            # Analyze the processed method list
            elif args.split()[0] == "analyzed":
                # List the methods that have been processed
                if args.split()[1] == "list":
                    if self.methods_api_usage:
                        print("\n")
                        for m in self.methods_api_usage:
                            print(
                                self.t.cyan("\t--> {} -> {} ".format(
                                    m[0].class_name, m[0].name)))
                        print("\n")
                    else:
                        SurgicalError("API usage not found (!)")
                        SurgicalError("Try running --> 'api select' again (!)")
                # Select from the processed method list
                elif args.split()[1] == "select":
                    if self.methods_api_usage:
                        selection = raw_input(
                            self.t.yellow("[{}] ".format(datetime.now())) +
                            "Select method : ")
                        for m in self.methods_api_usage:
                            if selection == m[0].name:
                                print("\n")
                                print(
                                    self.t.cyan("\t--> Class : {}".format(
                                        m[0].class_name)))
                                print(
                                    self.t.cyan("\t\t--> Method : {}".format(
                                        m[0].name)))
                                print(
                                    self.t.cyan(
                                        "\t\t\t --> XREFS ###########"))
                                self.u.print_xref("T",
                                                  m[1].method.XREFto.items)
                                self.u.print_xref("F",
                                                  m[1].method.XREFfrom.items)
                                print("\n")
                                print(
                                    highlight(m[2], JavaLexer(),
                                              TerminalFormatter()))
                    else:
                        SurgicalError("API usage not found (!)")
                        SurgicalError("Try running --> 'api select' again (!)")
        except Exception as e:
            SurgicalError(e.message)
Example #3
0
class Run(SurgicalCmd):
    def __init__(self, vm, vmx):
        SurgicalCmd.__init__(self)
        self.logger = Logger()
        self.t = Terminal()
        self.u = Util()
        self.vm = vm
        self.vmx = vmx
        self.methods = self.vm.get_methods()
        self.intent = IntentModule()
        self.zip = ZipModule()
        self.socket = SocketModule()
        self.system = SystemModule()
        self.crypto = CryptoModule()
        self.modules = [
            m for m in self.zip, self.intent, self.socket, self.system,
            self.crypto
        ]
        self.target_module = None
        self.methods_api_usage = list()

    def _cmd_completer(self, name, text, line, begidx, endidx):
        fn = getattr(self, 'do_' + name)
        if not hasattr(fn.im_func, "_expected_args"):
            return []
        a = [arg for arg in fn.im_func._expected_args if arg.startswith(text)]
        return a

    def complete_modules(self, *args):
        return self._cmd_completer("modules", *args)

    @cmd_arguments(["list", "select"])
    def do_modules(self, *args):
        """
        List and select target API modules.

        := modules list
        := modules select
        """
        # Locals
        arg0 = args[0]
        selection = None

        try:
            if arg0 == "list":
                if self.modules:
                    print("\n")
                    for i, m in enumerate(self.modules):
                        print(self.t.cyan("\t--> [{}] {}".format(i, m.name)))
                    print("\n")
            if arg0 == "select":
                if self.modules:
                    selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select module : ")
                    try:
                        index = int(selection)
                    except ValueError:
                        index = -1
                    for i, m in enumerate(self.modules):
                        if selection == m.name or i == index:
                            self.target_module = m
                            break
                    self.logger.surgical_log(
                        "info", "{} module selected (!)".format(
                            self.target_module.name))
        except Exception as e:
            SurgicalError(e.message)

    def complete_api(self, *args):
        return self._cmd_completer("api", *args)

    @cmd_arguments(["list", "select", "analyzed"])
    def do_api(self, *args):
        """
        List and select methods from a given loaded API module

        := api list
        := api select
        := api analyzed list
        := api analyzed select
        """
        # Locals
        arg0 = args[0].split(" ")[0]
        arg1 = None
        class_selection = None
        method_selection = None
        surgical_lib = None

        try:
            # List the available API methods from the target module
            if arg0 == "list":
                if self.target_module:
                    print("\n")
                    for k, v in self.target_module.model.values.items():
                        print("\n")
                        for m in v:
                            print(
                                self.t.cyan("\t--> {} : {} : {}".format(
                                    self.target_module.name,
                                    k.split(".")[-1], m)))
                    print("\n")
                else:
                    self.logger.surgical_log(
                        "info", "Target module has not been loaded (!)")
            # Select an API method from the target module
            elif arg0 == "select":
                if self.target_module:
                    # TODO Consider building a wrapper around raw_input()
                    class_selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select class : ")
                    method_selection = raw_input(
                        self.t.yellow("[{}] ".format(datetime.now())) +
                        "Select method : ")
                    for k, v in self.target_module.model.values.items():
                        # This is so we can support classes with identical
                        # method names --> Ex: java.util.zip.ZipFile
                        if class_selection == k.split(".")[-1]:
                            for m in v:
                                if m == method_selection:
                                    self.logger.surgical_log(
                                        "info", "Analyzing ...")
                                    from core.brains.surgical.lib.libsurgical import SurgicalLib
                                    # Begin processing and return the results
                                    # from the selected api
                                    surgical_lib = SurgicalLib(
                                        self.target_module, self.vmx, self.vm,
                                        k, method_selection, self.methods)
                                    # methods_api_usage will contain a list of
                                    # tuples
                                    self.methods_api_usage = surgical_lib.search(
                                    )
                                else:
                                    self.logger.surgical_log(
                                        "warn", "Method not found (!)")
            # Analyze the processed method list
            elif arg0 == "analyzed":
                if args[0].split(" ")[1]:
                    arg1 = args[0].split(" ")[1]
                    # List the methods that have been processed
                    if arg1 == "list":
                        if self.methods_api_usage:
                            print("\n")
                            for i, m in enumerate(self.methods_api_usage):
                                print(
                                    self.t.cyan("\t--> [{}] {} -> {} ".format(
                                        i, m[0].class_name, m[0].name)))
                            print("\n")
                        else:
                            SurgicalError("API usage not found (!)")
                # Select from the processed method list
                elif arg1 == "select":
                    if self.methods_api_usage:
                        selection = raw_input(
                            self.t.yellow("[{}] ".format(datetime.now())) +
                            "Select method : ")
                        try:
                            index = int(selection)
                        except ValueError:
                            index = -1
                        for i, m in enumerate(self.methods_api_usage):
                            if selection == m[0].name or i == index:
                                print("\n")
                                print(
                                    self.t.cyan("\t--> Class : {}".format(
                                        m[0].class_name)))
                                print(
                                    self.t.cyan("\t\t--> Method : {}".format(
                                        m[0].name)))
                                print(
                                    self.t.cyan(
                                        "\t\t\t --> XREFS ###########"))
                                self.u.print_xref("T",
                                                  m[1].method.XREFto.items)
                                self.u.print_xref("F",
                                                  m[1].method.XREFfrom.items)
                                print("\n")
                                print(
                                    highlight(m[2], JavaLexer(),
                                              TerminalFormatter()))
                    else:
                        SurgicalError("API usage not found (!)")
        except Exception as e:
            SurgicalError(e.message)
class SurgicalLibError(Exception):
    def __init__(self, message):
        self.logger = Logger()
        self.message = message
        self.logger.surgical_log("critical", "SurgicalLib : {}".format(self.message))
class SurgicalLib(object):
    def __init__(self, target_module, vmx, vm, k, selection, methods):
        self.logger = Logger()
        self.target_module = target_module
        self.vmx = vmx
        self.vm = vm
        self.clazz = k
        self.selection = selection
        self.methods = methods

    def process_methods(self, found_methods):
        """
        Process and return a unique and analyzed list of methods based on usage
        findings.

        Args:
            param1: Discovered methods

        Returns:
            return: Processed methods
        """

        # Locals
        seen = set()
        unique = list()
        processed = list()

        try:
            for m in found_methods:
                if m.get_class_name() not in seen:
                    unique.append(m)
                    seen.add(m.get_class_name())
            for u in unique:
                if u.get_code():
                    analyzed = self.vmx.get_method(u)
                    src = decompile.DvMethod(analyzed)
                    src.process()
                    processed.append((u, analyzed, src.get_source()))
                else:
                    analyzed = self.vmx.get_method(u)
                    processed.append((u, analyzed, None))
            return processed
        except Exception as e:
            SurgicalLibError("process_methods : {}".format(e))
            if "Instruction31c" in e.message:
                pass

    def search(self):
        """
        Search for API usage within the target module

        Args:
            None

        Returns:
            return: Method
        """

        # Locals
        paths = None
        method = None
        found_methods = list()

        try:
            paths = self.vmx.get_tainted_packages().search_methods(self.clazz, self.selection, ".")
            if paths:
                for p in paths:
                    for method in self.methods:
                        if method.get_name() == p.get_src(self.vm.get_class_manager())[1]:
                            if method.get_class_name() == p.get_src(self.vm.get_class_manager())[0]:
                                found_methods.append(method)
            if found_methods:
                self.logger.surgical_log("info", "Results found (!)")
                process_methods = self.process_methods(found_methods)
                if process_methods:
                    return process_methods
            else:
                self.logger.surgical_log("info", "No results found (!)")
        except Exception as e:
            SurgicalLibError(e.message)
Example #6
0
class SurgicalLibError(Exception):
    def __init__(self, message):
        self.logger = Logger()
        self.message = message
        self.logger.surgical_log("critical", "SurgicalLib : {}"
                                 .format(self.message))
Example #7
0
class SurgicalLib(object):
    def __init__(self, target_module, vmx, vm, k, selection, methods):
        self.logger = Logger()
        self.target_module = target_module
        self.vmx = vmx
        self.vm = vm
        self.clazz = k
        self.selection = selection
        self.methods = methods

    def process_methods(self, found_methods):
        """
        Process and return a unique and analyzed list of methods based on usage
        findings.

        Args:
            param1: Discovered methods

        Returns:
            return: Processed methods
        """

        # Locals
        seen = set()
        unique = list()
        processed = list()

        for m in found_methods:
            if m.get_class_name() not in seen:
                unique.append(m)
                seen.add(m.get_class_name())
        for u in unique:
            if u.get_code():
                analyzed = self.vmx.get_method(u)
                src = decompile.DvMethod(analyzed)
                src.process()
                processed.append((u, analyzed, src.get_source()))
            else:
                analyzed = self.vmx.get_method(u)
                processed.append((u, analyzed, None))
        return processed

    def search(self):
        """
        Search for API usage within the target module

        Args:
            None

        Returns:
            return: Method
        """

        # Locals
        paths = None
        method = None
        found_methods = list()

        try:
            paths = self.vmx.get_tainted_packages().search_methods(self.clazz, self.selection, ".")
            if paths:
                for p in paths:
                    for method in self.methods:
                        if method.get_name() == p.get_src(self.vm.get_class_manager())[1]:
                            if method.get_class_name() == p.get_src(self.vm.get_class_manager())[0]:
                                found_methods.append(method)
            if found_methods:
                self.logger.surgical_log("info", "Results found (!)")
                process_methods = self.process_methods(found_methods)
                if process_methods:
                    return process_methods
        except Exception as e:
            SurgicalLibError(e.message)