Ejemplo n.º 1
0
    def run(self):
        """
        Captures remote hosts memory
        """
        logger = logging.getLogger(__name__)
        try:
            # Check repository GPG settings before starting workers
            # Handling this here prevents subprocesses from needing stdin access
            repo_conf = self.config['repository']
            repo = None
            if repo_conf['enabled'] and repo_conf['gpg_verify']:
                try:
                    repo = Repository(repo_conf['url'],
                                      repo_conf['gpg_verify'])
                    repo.init_gpg()
                except Exception as ex:
                    # Do not prompt to install gpg keys unless running interactively
                    if repo is not None and self.library is False:
                        if isinstance(ex, RepositoryUntrustedSigningKeyError):
                            installed = repo.prompt_for_install()
                            if installed is False:
                                logger.critical(("repository signature not "
                                                 "installed, install the "
                                                 "signature manually or use "
                                                 "the --gpg-no-verify flag "
                                                 "to bypass this check"))
                                quit(1)
                    else:
                        logger.critical(ex)
                        quit(1)

            conf = self.map_config()
            workers = Workers(conf,
                              self.config['workers'],
                              name=self.name,
                              library=self.library)
            description = 'memory capture action'
            results = workers.spawn(description)

            self.statistics(results)
            if self.library is True:
                return dict([('total', self.total),
                             ('completed', self.completed_addresses),
                             ('failed', self.failed_addresses)])
            else:
                logger.info(("{0} hosts processed. completed: {1} "
                             "failed {2}".format(self.total, self.completed,
                                                 self.failed)))
                logger.info("completed_hosts: {0}".format(
                    self.completed_addresses))
                logger.info("failed_hosts: {0}".format(self.failed_addresses))
                quit()
        except KeyboardInterrupt:
            workers.cleanup(terminate=True)
            if self.library:
                raise
            else:
                quit(1)
Ejemplo n.º 2
0
    def get_memory(
        self,
        bucket,
        ip,
        user,
        key,
        case_number,
        port=None,
        password=None
    ):
        name = 'margaritashotgun'
        config = dict(
            aws=dict(bucket=bucket),
            hosts=[
                dict(
                    addr=ip, port=port,
                    username=user,
                    password=password,
                    key=key
                )
            ],
            workers='auto',
            logging={
                    'dir': '/tmp/',
                    'prefix': ("{case_number}-{ip}").format(
                        ip=ip,
                        case_number=case_number
                    )
            },
            repository=dict(
                enabled=True,
                url=('https://threatresponse-lime'
                     '-modules.s3.amazonaws.com/')
            )
        )
        if 'Darwin' in platform.system():
            config['repository']['gpg_verify'] = False
        capture_client = margaritashotgun.client(
            name=name,
            config=config,
            library=True,
            verbose=self.verbose
        )

        try:
            repository_url = 'https://threatresponse-lime-modules.s3.amazonaws.com/'
            if 'Darwin' in platform.system():
                repository_gpg_verify = False
            else:
                repository_gpg_verify = True

            self.repo = Repository(repository_url, repository_gpg_verify)

            if 'Darwin' not in platform.system():
                self.repo.init_gpg()

            return capture_client.run()
        except Exception:
            if 'Darwin' not in platform.system():
                logger.critical("GPG key not in trust chain attempting interactive installation.")
                self.repo.prompt_for_install()
            return capture_client.run()
Ejemplo n.º 3
0
def process(conf):
    """
    """

    remote_addr = conf['host']['addr']
    remote_port = conf['host']['port']
    username = conf['host']['username']
    password = conf['host']['password']
    lime_module = conf['host']['module']
    filename = conf['host']['filename']
    key = conf['host']['key']
    bucket = conf['aws']['bucket']
    progressbar = conf['host']['progressbar']
    tunnel_addr = '127.0.0.1'
    tunnel_port = random.randint(10000, 30000)
    remote_module_path = '/tmp/lime.ko'

    repository_enabled = conf['repository']['enabled']
    repository_url = conf['repository']['url']

    queue_handler = QueueHandler(log_queue)
    logger = logging.getLogger('margaritashotgun')
    logger.addHandler(queue_handler)

    if bucket is not None:
        dest = OutputDestinations.s3
    else:
        dest = OutputDestinations.local

    if filename is None:
        tm = int(time.time())
        dt = datetime.utcfromtimestamp(tm).isoformat()
        filename = "{0}-{1}-mem.lime".format(remote_addr, dt)

    try:
        host = Host()
        host.connect(username, password, key, remote_addr, remote_port)
        host.start_tunnel(tunnel_port, tunnel_addr, tunnel_port)
        if lime_module is None:
            kernel_version = host.kernel_version()
            if repository_enabled:
                repo = Repository(repository_url)
                match = repo.search_modules(kernel_version)
                if match is not None:
                    lime_module = repo.fetch_module(match)
                    host.upload_module(lime_module)
                else:
                    raise KernelModuleNotFoundError(kernel_version, repo.url)
            else:
                # TODO: prompt user to search repository when running interactively
                raise KernelModuleNotProvidedError(kernel_version)
        else:
            host.upload_module(lime_module, remote_module_path)

        host.load_lime(remote_module_path, tunnel_port)
        lime_loaded = host.wait_for_lime(tunnel_port)

        if lime_loaded:
            result = host.capture_memory(dest, filename, bucket, progressbar)
        else:
            result = False

        logger.removeHandler(queue_handler)
        queue_handler.close()
        host.cleanup()

        return (remote_addr, result)
    except KeyboardInterrupt:
        logger.removeHandler(queue_handler)
        queue_handler.close()
        host.cleanup()
        return (remote_addr, False)
    except Exception as ex:
        logger.removeHandler(queue_handler)
        queue_handler.close()
        host.cleanup()
        logger.critical(ex)
        return (remote_addr, False)
Ejemplo n.º 4
0
def process(conf):
    """
    """
    jump_host = conf['host']['jump_host']
    remote_addr = conf['host']['addr']
    remote_port = conf['host']['port']
    username = conf['host']['username']
    password = conf['host']['password']
    lime_module = conf['host']['module']
    filename = conf['host']['filename']
    key = conf['host']['key']
    bucket = conf['aws']['bucket']
    azure_blob_config = conf['azure_blob']
    progressbar = conf['host']['progressbar']
    tunnel_addr = '127.0.0.1'
    tunnel_port = random.randint(10000, 30000)
    remote_module_path = '/tmp/lime.ko'

    repository_enabled = conf['repository']['enabled']
    repository_url = conf['repository']['url']
    repository_manifest = conf['repository']['manifest']
    repository_gpg_verify = conf['repository']['gpg_verify']

    queue_handler = QueueHandler(log_queue)
    logger = logging.getLogger('margaritashotgun')
    logger.addHandler(queue_handler)

    if bucket is not None:
        dest = OutputDestinations.s3
    elif any([ v is not None for v in azure_blob_config.values() ]):
        dest = OutputDestinations.azure_blob
    else:
        dest = OutputDestinations.local

    if filename is None:
        tm = int(time.time())
        dt = datetime.utcfromtimestamp(tm).isoformat()
        filename = "{0}-{1}-mem.lime".format(remote_addr, dt)

    try:
        host = Host()
        host.connect(username, password, key, remote_addr, remote_port,
                     jump_host)
        host.start_tunnel(tunnel_port, tunnel_addr, tunnel_port)
        if lime_module is None:
            kernel_version = host.kernel_version()
            if repository_enabled:
                repo = Repository(repository_url, repository_gpg_verify)
                repo.init_gpg()
                lime_module = repo.fetch(kernel_version, repository_manifest)
                host.upload_module(lime_module)
            else:
                raise KernelModuleNotProvidedError(kernel_version)
        else:
            host.upload_module(lime_module, remote_module_path)

        host.load_lime(remote_module_path, tunnel_port)
        lime_loaded = host.wait_for_lime(tunnel_port)

        if lime_loaded:
            result = host.capture_memory(dest, filename, bucket, azure_blob_config, progressbar)
        else:
            logger.debug("lime failed to load on {0}".format(remote_addr))
            result = False

        logger.removeHandler(queue_handler)
        queue_handler.close()
        host.cleanup()

        return (remote_addr, result)
    except SSHConnectionError as ex:
        logger.error(ex)
        logger.removeHandler(queue_handler)
        queue_handler.close()
        return (remote_addr, False)
    except KeyboardInterrupt as ex:
        logger.removeHandler(queue_handler)
        queue_handler.close()
        host.cleanup()
        return (remote_addr, False)
    except (SSHCommandError, Exception) as ex:
        logger.error(ex)
        logger.removeHandler(queue_handler)
        queue_handler.close()
        host.cleanup()
        return (remote_addr, False)