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)
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)
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)
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() 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)