def do_copy_execute(line): '''Copy a file from host to guest, execute it, and pause VM on its EP - Custom command This command will first use the guest agent to copy a file to the guest and execute if afterwards. This file will be set as target, so that the script will start monitoring context changes and retrieve the module entry point as soon as it is available in memory. Then it will place a breakpoint on the entry point. ''' global pyrebox_print global target_procname from plugins.guest_agent import guest_agent pyrebox_print("Copying host file to guest, using agent...") # Copy the specified file to C:\\temp.exe in the guest guest_agent.copy_file(line.strip(), "C:\\temp.exe") # Execute the file guest_agent.execute_file("C:\\temp.exe") # stop_agent() does not only kill the agent, but it also # disables the agent plugin. Invalid opcodes # are not treated as agent commands any more, so this call # improves transparency. guest_agent.stop_agent() # Set target proc name: target_procname = "temp.exe" pyrebox_print("Waiting for process %s to start\n" % target_procname)
def do_copy_execute(line): '''Copy a file from host to guest, execute it, and pause VM on its EP - Custom command This command will first use the guest agent to copy a file to the guest and execute if afterwards. This file will be set as target, so that the script will start monitoring context changes and retrieve the module entry point as soon as it is available in memory. Then it will place a breakpoint on the entry point. ''' global pyrebox_print global target_procname from plugins.guest_agent import guest_agent pyrebox_print("Copying host file to guest, using agent...") # Copy the specified file to C:\\temp.exe in the guest guest_agent.copy_file(line.strip(), "C:\\temp.exe") # Execute the file guest_agent.execute_file("C:\\temp.exe") # stop_agent() does not only kill the agent, but it also # disables the agent plugin. Invalid opcodes # are not treated as agent commands any more, so this call # improves transparency. guest_agent.stop_agent() # Set target proc name: target_procname = "temp.exe" pyrebox_print("Waiting for process %s to start\n" % target_procname)
def initialize_callbacks(module_hdl, printer): ''' Initilize callbacks for this module. This function will be triggered whenever the script is loaded for the first time, either with the import_module command, or when loaded at startup. ''' # We keep a callback manager as a global var. # --> To access it from any function. # --> Necessary to call cm.clean() from clean() function global cm global pyrebox_print from plugins.guest_agent import guest_agent # Initialize printer function (global var), that we can use to print # text that is associated to our script pyrebox_print = printer pyrebox_print("[*] Initializing callbacks") # Initialize the callback manager, and register a couple of named # callbacks. cm = CallbackManager(module_hdl) cm.add_callback(CallbackManager.CREATEPROC_CB, new_proc, name="vmi_new_proc") cm.add_callback(CallbackManager.REMOVEPROC_CB, remove_proc, name="vmi_remove_proc") pyrebox_print("[*] Initialized callbacks") guest_agent.execute_file("C:\\Users\\Windows7\\Desktop\\test.exe")
def initialize_callbacks(module_hdl, printer): global cm global pyrebox_print from plugins.guest_agent import guest_agent pyrebox_print = printer cm = CallbackManager(module_hdl) guest_agent.copy_file("/home/marc/sdcard/zoo/gen/sample.exe", "C:\\ProgramData\\malo.exe") cm.add_callback(CallbackManager.CREATEPROC_CB, new_proc, name="vmi_new_proc") guest_agent.execute_file("C:\\ProgramData\\malo.exe")
def initialize_callbacks(module_hdl, printer): global cm global pyrebox_print global sample_to_upload global upload_path global sample_name from plugins.guest_agent import guest_agent pyrebox_print = printer cm = CallbackManager(module_hdl) # Push the sample from de host to de guest guest_agent.copy_file(sample_to_upload, upload_path + sample_name) # Create a Callback for every new process create to catch de sample when executed cm.add_callback(CallbackManager.CREATEPROC_CB, new_process_created, name="vmi_new_proc") # Run the sample uploaded to the VM guest_agent.execute_file(upload_path + sample_name)
def initialize_callbacks(module_hdl, printer): ''' Initialize callbacks for this module. This function will be triggered whenever import_module command is triggered. ''' from api import CallbackManager from plugins.guest_agent import guest_agent global cm global pyrebox_print global target_procname global autorun_module_handle autorun_module_handle = module_hdl pyrebox_print = printer pyrebox_print("[*] Reading configuration file") #Read AutoRun configuration file (json) f = open(os.environ["AUTORUN_CONF_PATH"], "r") conf = json.load(f) f.close() kws = [ "container_path", "main_executable_file", "extract_path", "temp_path", "preserve_filenames" ] for k in kws: if k not in conf: pyrebox_print( "The configuration file does not contain the necessary keywords" ) return # Initialize process creation callback pyrebox_print("[*] Initializing callbacks") cm = CallbackManager(module_hdl, new_style=True) cm.add_callback(CallbackManager.CREATEPROC_CB, new_proc, name="vmi_new_proc") pyrebox_print("[*] Initialized callbacks") # Copy target file to guest, and execute it pyrebox_print("Copying host file to guest, using agent...") temp_dnames = [] if "container_path" in conf and tarfile.is_tarfile(conf["container_path"]): # For each file in the tar file, extract to a temporary file, # and copy to the VM with the appropriate file name. extracted_files = {} tar = tarfile.open(conf["container_path"], "r:gz") # Get file names inside the tar file for tarinfo in tar: extracted_files[tarinfo.name] = None # Extract each file into a temporary file for fname in extracted_files.keys(): temp_dname = tempfile.mkdtemp(dir=conf["temp_path"]) temp_dnames.append(temp_dname) tar.extract(fname, path=temp_dname) extracted_files[fname] = os.path.join(temp_dname, fname) tar.close() # Copy files to the VM for fname, temp_fname in extracted_files.iteritems(): # Copy the specified file to C:\\temp.exe in the guest if conf["preserve_filenames"]: guest_agent.copy_file(temp_fname, conf["extract_path"] + fname) else: guest_agent.copy_file(temp_fname, conf["extract_path"] + "file.exe") conf["main_executable_file"] = "file.exe" # Execute the file. We set a callback to signal this script that # the files have already been copied and can be deleted f = functools.partial(files_copied_callback, temp_dnames) guest_agent.execute_file(conf["extract_path"] + conf["main_executable_file"], callback=f) # stop_agent() does not only kill the agent, but it also # disables the agent plugin. Invalid opcodes # are not treated as agent commands any more, so this call # improves transparency. guest_agent.stop_agent() # Set target proc name: target_procname = conf["main_executable_file"] pyrebox_print("Waiting for process %s to start\n" % target_procname) pyrebox_print("Module loaded: %d" % module_hdl)
def initialize_callbacks(module_hdl, printer): ''' Initilize callbacks for this module. This function will be triggered whenever import_module command is triggered. ''' from mw_monitor_classes import Process from mw_monitor_classes import mwmon import dumper import api from ipython_shell import add_command from plugins.guest_agent import guest_agent # Update printer mwmon.printer = printer # Read configuration mwmon.printer("Reading mw_monitor configuration...") # Config parser for main static configuration file config = ConfigParser.RawConfigParser() config.read('mw_monitor.conf') # Read run configuration from json file f = open("mw_monitor_run.json","r") config_run = json.load(f) f.close() # GENERAL CONFIGURATION if "files_path" not in config_run["general"] or \ "main_executable" not in config_run["general"] or \ "files_bundle" not in config_run["general"]: raise ValueError("File to run not properly specified") mwmon.output_bundle_name = config.get('general', 'output_bundle') mwmon.files_path = config_run['general']['files_path'] mwmon.main_executable = config_run['general']['main_executable'] mwmon.files_bundle = config_run['general']['files_bundle'] mwmon.api_database_path = config.get('general', 'api_database') # Set up process copy and execution mwmon.printer("Copying host file to guest, using agent...") #Extract files in a temporary directory extracted_files_path = tempfile.mkdtemp() mwmon.extracted_files_path = extracted_files_path zip_ref = zipfile.ZipFile(mwmon.files_bundle, 'r') zip_ref.extractall(extracted_files_path) zip_ref.close() onlyfiles = [f for f in os.listdir(extracted_files_path) if os.path.isfile(os.path.join(extracted_files_path, f))] #Copy the files to the guest for f in onlyfiles: guest_agent.copy_file(os.path.join(extracted_files_path,f),os.path.join(mwmon.files_path,f)) ex_path = str(ntpath.join(mwmon.files_path,mwmon.main_executable)) # Instruct file execution guest_agent.execute_file(ex_path) # Stop agent # guest_agent.stop_agent() # MODULE CONFIGURATION mwmon.api_tracer = config_run['modules']['api_tracer'] mwmon.interproc = config_run['modules']['interproc'] mwmon.coverage = config_run['modules']['coverage'] mwmon.dumper = config_run['modules']['dumper'] # API TRACER CONFIGURATION if mwmon.api_tracer and "api_tracer" in config_run: # Static config mwmon.api_tracer_text_log_name = config.get( 'api_tracer', 'text_log_name') mwmon.api_tracer_bin_log_name = config.get( 'api_tracer', 'bin_log_name') # Run config mwmon.api_tracer_light_mode = config_run['api_tracer']['light_mode'] mwmon.api_tracer_text_log = config_run['api_tracer']['text_log'] mwmon.api_tracer_bin_log = config_run['api_tracer']['bin_log'] if "include_apis" in config_run["api_tracer"]: mwmon.include_apis = [] mwmon.include_apis_addrs = [] for api_call in config_run["api_tracer"]["include_apis"]: try: mod, fun = api_call.split("!") mwmon.include_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.include_apis = None if "exclude_apis" in config_run["api_tracer"]: mwmon.exclude_apis = [] mwmon.exclude_apis_addrs = [] for api_call in config_run["api_tracer"]["exclude_apis"]: try: mod, fun = api_call.split("!") mwmon.exclude_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.excludeapis = None if "procs" in config_run["api_tracer"]: mwmon.api_tracer_procs = config_run["api_tracer"]["procs"] else: mwmon.api_tracer_procs = None if "exclude_modules" in config_run["api_tracer"]: mwmon.exclude_modules_addrs = [] mwmon.exclude_modules = [s.lower() for s in config_run["api_tracer"]["exclude_modules"]] else: mwmon.exclude_modules = None if "exclude_origin_modules" in config_run["api_tracer"]: mwmon.exclude_origin_modules_addrs = [] mwmon.exclude_origin_modules = [s.lower() for s in config_run["api_tracer"]["exclude_origin_modules"]] else: mwmon.exclude_origin_modules = None mwmon.exclude_origin_modules_addrs = None # interproc configuration if mwmon.interproc: # Static config mwmon.interproc_bin_log_name = config.get('interproc', 'bin_log_name') mwmon.interproc_text_log_name = config.get( 'interproc', 'text_log_name') mwmon.interproc_basic_stats_name = config.get( 'interproc', 'basic_stats_name') # Run config mwmon.interproc_bin_log = config_run['interproc']['bin_log'] mwmon.interproc_text_log = config_run['interproc']['text_log'] mwmon.interproc_basic_stats = config_run['interproc']['basic_stats'] if mwmon.interproc_text_log: mwmon.interproc_text_log_handle = open( mwmon.interproc_text_log_name, "w") if mwmon.coverage: # Static config mwmon.coverage_log_name = config.get('coverage', 'cov_log_name') mwmon.coverage_text_name = config.get('coverage', 'cov_text_name') # Run config if "procs" in config_run["coverage"]: mwmon.coverage_procs = config_run["coverage"]["procs"] else: mwmon.coverage_procs = None # Static config mwmon.dumper_path = config.get('dumper', 'path') # DUMPER CONFIGURATION if mwmon.dumper: if os.path.isdir(mwmon.dumper_path): shutil.rmtree(mwmon.dumper_path) os.makedirs(mwmon.dumper_path) # Run config mwmon.dumper_onexit = config_run['dumper']['dump_on_exit'] # Possible formats for dump_at: # 0x00400000 # user32.dll!CharNextW # user32.dll!CharNextW!0x00400000 if "dump_at" in config_run["dumper"]: mwmon.dumper_dumpat = config_run['dumper']['dump_at'] mwmon.printer("Initializing callbacks") mwmon.cm = CallbackManager(module_hdl, new_style = True) # Initialize first process proc_name = mwmon.main_executable mwmon.data.procs = [Process(proc_name)] procs = api.get_process_list() match_procs = [] for proc in procs: name = proc["name"] pid = proc["pid"] pgd = proc["pgd"] if proc_name is not None and (proc_name in name or name in proc_name): match_procs.append((pid, pgd, name)) if len(match_procs) == 0: mwmon.printer( "No process matching that process name, deferring process detection") mwmon.printer("Initializing process creation callback") # Monitor creation of new processes, to start tracing the first one. mwmon.cm.add_callback( CallbackManager.CREATEPROC_CB, new_process, name="vmi_new_proc") elif len(match_procs) == 1: mwmon.printer( "Process found with the name specified, monitoring process...") new_process({"pid": match_procs[0][0], "pgd": match_procs[0][1], "name": match_procs[0][2]}) else: mwmon.printer( "Too many procs matching that name, please narrow down!!") if mwmon.dumper: mwmon.printer("Adding dumper commands") # Create and activate new command (dump_mwmon) add_command("dump_mwmon", dumper.dump_command) # Add a callback on process remove, to know when # we dont have any monitored process left. mwmon.cm.add_callback( CallbackManager.REMOVEPROC_CB, remove_process, name="mwmon_vmi_remove_proc") mwmon.printer("Initialized callbacks")
def initialize_callbacks(module_hdl, printer): ''' Initilize callbacks for this module. This function will be triggered whenever import_module command is triggered. ''' from mw_monitor_classes import Process from mw_monitor_classes import mwmon import dumper import api from ipython_shell import add_command from plugins.guest_agent import guest_agent # Update printer mwmon.printer = printer # Read configuration mwmon.printer("Reading mw_monitor configuration...") # Config parser for main static configuration file config = ConfigParser.RawConfigParser() config.read('mw_monitor.conf') # Read run configuration from json file f = open("mw_monitor_run.json", "r") config_run = json.load(f) f.close() # GENERAL CONFIGURATION if "files_path" not in config_run["general"] or \ "main_executable" not in config_run["general"] or \ "files_bundle" not in config_run["general"]: raise ValueError("File to run not properly specified") mwmon.output_bundle_name = config.get('general', 'output_bundle') mwmon.files_path = config_run['general']['files_path'] mwmon.main_executable = config_run['general']['main_executable'] mwmon.files_bundle = config_run['general']['files_bundle'] mwmon.api_database_path = config.get('general', 'api_database') # Set up process copy and execution mwmon.printer("Copying host file to guest, using agent...") #Extract files in a temporary directory extracted_files_path = tempfile.mkdtemp() mwmon.extracted_files_path = extracted_files_path zip_ref = zipfile.ZipFile(mwmon.files_bundle, 'r') zip_ref.extractall(extracted_files_path) zip_ref.close() onlyfiles = [ f for f in os.listdir(extracted_files_path) if os.path.isfile(os.path.join(extracted_files_path, f)) ] #Copy the files to the guest for f in onlyfiles: guest_agent.copy_file(os.path.join(extracted_files_path, f), os.path.join(mwmon.files_path, f)) ex_path = str(ntpath.join(mwmon.files_path, mwmon.main_executable)) # Instruct file execution guest_agent.execute_file(ex_path) # Stop agent # guest_agent.stop_agent() # MODULE CONFIGURATION mwmon.api_tracer = config_run['modules']['api_tracer'] mwmon.interproc = config_run['modules']['interproc'] mwmon.coverage = config_run['modules']['coverage'] mwmon.dumper = config_run['modules']['dumper'] # API TRACER CONFIGURATION if mwmon.api_tracer and "api_tracer" in config_run: # Static config mwmon.api_tracer_text_log_name = config.get('api_tracer', 'text_log_name') mwmon.api_tracer_bin_log_name = config.get('api_tracer', 'bin_log_name') # Run config mwmon.api_tracer_light_mode = config_run['api_tracer']['light_mode'] mwmon.api_tracer_text_log = config_run['api_tracer']['text_log'] mwmon.api_tracer_bin_log = config_run['api_tracer']['bin_log'] if "include_apis" in config_run["api_tracer"]: mwmon.include_apis = [] mwmon.include_apis_addrs = [] for api_call in config_run["api_tracer"]["include_apis"]: try: mod, fun = api_call.split("!") mwmon.include_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.include_apis = None if "exclude_apis" in config_run["api_tracer"]: mwmon.exclude_apis = [] mwmon.exclude_apis_addrs = [] for api_call in config_run["api_tracer"]["exclude_apis"]: try: mod, fun = api_call.split("!") mwmon.exclude_apis.append((mod.lower(), fun.lower())) except Exception: # Just pass over the malformed api names pass else: mwmon.excludeapis = None if "procs" in config_run["api_tracer"]: mwmon.api_tracer_procs = config_run["api_tracer"]["procs"] else: mwmon.api_tracer_procs = None if "exclude_modules" in config_run["api_tracer"]: mwmon.exclude_modules_addrs = [] mwmon.exclude_modules = [ s.lower() for s in config_run["api_tracer"]["exclude_modules"] ] else: mwmon.exclude_modules = None if "exclude_origin_modules" in config_run["api_tracer"]: mwmon.exclude_origin_modules_addrs = [] mwmon.exclude_origin_modules = [ s.lower() for s in config_run["api_tracer"]["exclude_origin_modules"] ] else: mwmon.exclude_origin_modules = None mwmon.exclude_origin_modules_addrs = None # interproc configuration if mwmon.interproc: # Static config mwmon.interproc_bin_log_name = config.get('interproc', 'bin_log_name') mwmon.interproc_text_log_name = config.get('interproc', 'text_log_name') mwmon.interproc_basic_stats_name = config.get('interproc', 'basic_stats_name') # Run config mwmon.interproc_bin_log = config_run['interproc']['bin_log'] mwmon.interproc_text_log = config_run['interproc']['text_log'] mwmon.interproc_basic_stats = config_run['interproc']['basic_stats'] if mwmon.interproc_text_log: mwmon.interproc_text_log_handle = open( mwmon.interproc_text_log_name, "w") if mwmon.coverage: # Static config mwmon.coverage_log_name = config.get('coverage', 'cov_log_name') mwmon.coverage_text_name = config.get('coverage', 'cov_text_name') # Run config if "procs" in config_run["coverage"]: mwmon.coverage_procs = config_run["coverage"]["procs"] else: mwmon.coverage_procs = None # Static config mwmon.dumper_path = config.get('dumper', 'path') # DUMPER CONFIGURATION if mwmon.dumper: if os.path.isdir(mwmon.dumper_path): shutil.rmtree(mwmon.dumper_path) os.makedirs(mwmon.dumper_path) # Run config mwmon.dumper_onexit = config_run['dumper']['dump_on_exit'] # Possible formats for dump_at: # 0x00400000 # user32.dll!CharNextW # user32.dll!CharNextW!0x00400000 if "dump_at" in config_run["dumper"]: mwmon.dumper_dumpat = config_run['dumper']['dump_at'] mwmon.printer("Initializing callbacks") mwmon.cm = CallbackManager(module_hdl, new_style=True) # Initialize first process proc_name = mwmon.main_executable mwmon.data.procs = [Process(proc_name)] procs = api.get_process_list() match_procs = [] for proc in procs: name = proc["name"] pid = proc["pid"] pgd = proc["pgd"] if proc_name is not None and (proc_name in name or name in proc_name): match_procs.append((pid, pgd, name)) if len(match_procs) == 0: mwmon.printer( "No process matching that process name, deferring process detection" ) mwmon.printer("Initializing process creation callback") # Monitor creation of new processes, to start tracing the first one. mwmon.cm.add_callback(CallbackManager.CREATEPROC_CB, new_process, name="vmi_new_proc") elif len(match_procs) == 1: mwmon.printer( "Process found with the name specified, monitoring process...") new_process({ "pid": match_procs[0][0], "pgd": match_procs[0][1], "name": match_procs[0][2] }) else: mwmon.printer( "Too many procs matching that name, please narrow down!!") if mwmon.dumper: mwmon.printer("Adding dumper commands") # Create and activate new command (dump_mwmon) add_command("dump_mwmon", dumper.dump_command) # Add a callback on process remove, to know when # we dont have any monitored process left. mwmon.cm.add_callback(CallbackManager.REMOVEPROC_CB, remove_process, name="mwmon_vmi_remove_proc") mwmon.printer("Initialized callbacks")