Example #1
0
def import_module(module_name):
    global MODULE_COUNTER
    import api_internal
    from ipython_shell import add_command
    try:
        already_imported = False
        for mod in modules:
            if module_name == modules[mod][0]:
                already_imported = True
                break
        if not already_imported:
            pp_print("[*]  Importing %s\n" % module_name)
            mod = __import__(module_name, fromlist=[''])
            mod.initialize_callbacks(
                MODULE_COUNTER, functools.partial(
                    api_internal.print_internal, module_name))
            # Add commands declared by the module
            for element in dir(mod):
                if element.startswith("do_"):
                    add_command(element[3:], getattr(mod, element))
            modules[MODULE_COUNTER] = (module_name, mod)
            MODULE_COUNTER += 1
        else:
            pp_warning("[*]  Module %s already imported\n" % module_name)
    except Exception as e:
        pp_error("[!] Could not initialize python module due to exception\n")
        pp_error("    %s\n" % str(e))
        return
Example #2
0
 def load(self):
     import api_internal
     from ipython_shell import add_command
     pp_print("[*]  Loading python module %s\n" % self.__module_name)
     self.__module = __import__(self.__module_name, fromlist=[''])
     self.__loaded = True
     self.__module.initialize_callbacks(
         self.__id,
         functools.partial(api_internal.print_internal, self.__module_name))
     # Add commands declared by the module
     for element in dir(self.__module):
         if element.startswith("do_"):
             add_command(element[3:], getattr(self.__module, element))
Example #3
0
 def reload(self):
     import api_internal
     from ipython_shell import add_command
     if self.__module is not None:
         pp_print("[*]  Reloading python module %s\n" % self.__module_name)
         if self.__loaded is True:
             self.unload()
         reload(self.__module)
         # Add again commands and call initialize_callbacks:
         self.__module.initialize_callbacks(self.__id,
                                            functools.partial(api_internal.print_internal, self.__module_name))
         # Add commands declared by the module
         for element in dir(self.__module):
             if element.startswith("do_"):
                 add_command(element[3:], getattr(self.__module, element))
         self.__loaded = True
     else:
         pp_warning("[!] The module was not correctly imported!\n")
Example #4
0
 def reload(self):
     import api_internal
     from ipython_shell import add_command
     if self.__module is not None:
         pp_print("[*]  Reloading python module %s\n" % self.__module_name)
         if self.__loaded is True:
             self.unload()
         reload(self.__module)
         # Add again commands and call initialize_callbacks:
         self.__module.initialize_callbacks(self.__id,
                                            functools.partial(api_internal.print_internal, self.__module_name))
         # Add commands declared by the module
         for element in dir(self.__module):
             if element.startswith("do_"):
                 add_command(element[3:], getattr(self.__module, element))
         self.__loaded = True
     else:
         pp_warning("[!] The module was not correctly imported!\n")
Example #5
0
    def load(self):
        import api_internal
        from ipython_shell import add_command
        pp_print("[*]  Loading python module %s\n" % self.__module_name)
        self.__module = __import__(self.__module_name, fromlist=[''])

        # Import other modules or plugins required by the module
        if hasattr(self.__module, "requirements"):
            for el in self.__module.requirements:
                import_module(el)

        self.__loaded = True
        self.__module.initialize_callbacks(self.__id,
                                           functools.partial(api_internal.print_internal, self.__module_name))

        # Add commands declared by the module
        for element in dir(self.__module):
            if element.startswith("do_"):
                add_command(element[3:], getattr(self.__module, element))
Example #6
0
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")
Example #7
0
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")