Esempio n. 1
0
 def _install_one_gadget_by_version(cls,
                                    name,
                                    version,
                                    mappings=None,
                                    verbose=False):
     stdout, stderr = verbose_func.verbose_output(verbose)
     # get complete version, e.g. 18.03.1~ce-0~ubuntu
     complete_version = cls._get_apt_complete_version(name,
                                                      version,
                                                      verbose=verbose)
     if complete_version:
         color_print.debug(
             'installing {gadget} with {version} version'.format(
                 gadget=name, version=complete_version))
         # install with the specified version
         temp_cmd = copy.copy(cls.cmd_apt_install)
         temp_cmd.append('{name}={version}'.format(
             name=name, version=complete_version))
         try:
             subprocess.run(temp_cmd,
                            stderr=stderr,
                            stdout=stdout,
                            check=True)
         except subprocess.CalledProcessError:
             return False
         if mappings:
             mappings[name] = complete_version
         return True
     color_print.warning('no candidate version for %s' % name)
     return False
Esempio n. 2
0
    def install_by_version(cls, gadgets, context=None, verbose=False):
        """Install Linux kernel with specified version.

        Args:
            gadgets: Kernel gadgets (e.g. kernel).
            context: Currently not used.
            verbose: Verbose or not.

        Returns:
            Boolean indicating whether kernel is successfully installed or not.
        """
        # refer to
        # https://blog.csdn.net/u013431916/article/details/82530523
        # https://wiki.ubuntu.com/KernelTeam/KernelMaintenance
        # and
        # https://en.wikipedia.org/wiki/Linux_kernel#Version_numbering
        version = gadgets[0]['version']
        color_print.debug('switching kernel by version')
        for repo in config.kernel_apt_repo_entries:
            cls._add_apt_repository(repo_entry=repo, verbose=verbose)

        if cls._is_version_available_in_apt(version, verbose=verbose):
            return cls._install_by_version_with_apt(version, verbose=verbose)
        else:
            color_print.warning(
                'no apt package for kernel %s' %
                version)
            if version.endswith('.0'):
                version = version.rstrip('.0') + '-'
            return cls._install_by_version_with_download(
                version, verbose=verbose)
Esempio n. 3
0
 def _install_by_version_with_download(cls, version, verbose=False):
     color_print.debug('switching kernel version with downloading packages')
     stdout, stderr = verbose_func.verbose_output(verbose)
     try:
         debs = cls._fetch_package_list_by_version(version, verbose=verbose)
         if not debs:
             return
         # download necessary *.deb and install
         temp_cmd = copy.copy(cls.cmd_dpkg_install)
         version_suffix = None
         for deb in debs:
             cls.download_file(deb, config.kernel_packages_dir)
             filename = deb.split('/')[-1]
             temp_cmd.append(
                 '{prefix}/{filename}'.format(prefix=config.kernel_packages_dir, filename=filename))
             if 'linux-image-' in filename:  # get full version for further modification in grub
                 try:
                     version_suffix = re.search(
                         r'linux-image-[a-z]*-?([\d].*?)_', filename).group(1)
                 except AttributeError:  # failed to derive complete kernel version
                     pass
         color_print.debug('installing kernel packages')
         # installation of kernel may return nonzero, currently ignore them
         subprocess.run(temp_cmd, stdout=stdout, stderr=stderr, check=False)
         if version_suffix:
             color_print.debug('kernel version: %s' % version_suffix)
             cls._modify_grub(version=version_suffix)
         else:
             color_print.warning('failed to derive complete kernel version')
             color_print.warning('please update grub manually')
         return True
     except subprocess.CalledProcessError:
         return False
Esempio n. 4
0
def remove(args):
    """Remove an installed cloud native gadget.

    Args:
        args.gadget: Name of the specified cloud native gadget.
        args.verbose: Verbose or not.

    Returns:
        None.
    """
    if args.gadget == 'docker':
        DockerInstaller.uninstall(verbose=args.verbose)
        color_print.debug(
            '{gadget} successfully removed'.format(gadget=args.gadget))
    if args.gadget == 'k8s':
        KubernetesInstaller.uninstall(verbose=args.verbose)
        color_print.debug(
            '{gadget} successfully removed'.format(gadget=args.gadget))
    if args.gadget == 'kata':
        if KataContainersInstaller.uninstall(verbose=args.verbose):
            color_print.debug(
                '{gadget} successfully removed'.format(gadget=args.gadget))
        else:
            color_print.error(
                'failed to remove {gadget}'.format(gadget=args.gadget))
    if args.gadget == 'kernel':
        color_print.warning(
            'removal of {gadget} is unsupported'.format(gadget=args.gadget))
Esempio n. 5
0
def remove(args):
    """Remove an installed cloud native vulnerability.

    Remove the vulnerable cloud native gadget with the cloud native vulnerability
    specified by args.cnv.

    Args:
        args.cnv: Name of the specified cloud native vulnerability.
        args.verbose: Verbose or not.

    Returns:
        None.
    """
    vulns = vuln_loader.load_vulns_by_dir(config.vuln_cn_dir_wildcard)
    vuln = filters.filter_vuln_by_name(vulns=vulns, name=args.cnv)
    if not vuln:
        color_print.error_and_exit(
            'no cloud native vulnerability named {cnv}'.format(cnv=args.cnv))

    if vuln['class'] == 'config' or vuln['class'] == 'mount' or vuln[
            'class'] == 'no-vuln':
        vulns = vuln_loader.load_vulns_by_dir(config.vuln_cn_dir_wildcard)
        vuln = filters.filter_vuln_by_name(vulns=vulns, name=args.cnv)
        if not vuln:
            color_print.error_and_exit(
                'no vulnerability named {cnv}'.format(cnv=args.cnv))

        internal_cmds.delete_vuln_resources_in_k8s(vuln, verbose=args.verbose)
        return

    color_print.debug(
        '{vuln} is going to be removed'.format(vuln=vuln['name']))

    if vuln['class'].startswith('docker'):
        DockerInstaller.uninstall(verbose=args.verbose)
        color_print.debug('{v} successfully removed'.format(v=vuln['name']))

    if vuln['class'] == 'kubernetes':
        KubernetesInstaller.uninstall(verbose=args.verbose)
        color_print.debug('{v} successfully removed'.format(v=vuln['name']))

    if vuln['class'] == 'kata-containers':
        if KataContainersInstaller.uninstall(verbose=args.verbose):
            color_print.debug(
                '{v} successfully removed'.format(v=vuln['name']))
        else:
            color_print.error('failed to remove {v}'.format(v=vuln['name']))

    if vuln['class'] == 'kernel':
        color_print.warning(
            'removal of vulnerabilities in class {vuln_class} is unsupported'.
            format(vuln_class=vuln['class']))
        return
Esempio n. 6
0
 def _fetch_package_list_by_version(cls, version, verbose=False):
     color_print.debug('retrieving package list for kernel %s' % version)
     try:
         f = open(config.kernel_packages_list, 'r')
     except FileNotFoundError:
         color_print.warning('%s does not exist.' %
                             config.kernel_packages_list)
         package_list_downloader.download_package_list()
         f = open(config.kernel_packages_list, 'r')
     try:
         packages = yaml.load(f, Loader=yaml.SafeLoader)
         for key in packages.keys():
             if version in key:
                 color_print.debug('kernel package list found:')
                 color_print.debug(json.dumps(packages[key]))
                 return packages[key]
     except yaml.scanner.ScannerError:
         return None
     color_print.error('kernel package list not found')
     return None
Esempio n. 7
0
def load_vuln(filename):
    """Load information about one vulnerability from one file.

    Args:
        filename: File storing information of specific vulnerability.

    Returns:
        If loading succeeds, return information dict about the vulnerability,
        else, return None.
    """
    try:
        with open(filename, 'r') as f:
            # for SafeLoader, see
            # https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation
            vuln = yaml.load(f, Loader=yaml.SafeLoader)
            vuln['path'] = re.sub('[^/]+.yaml$', '', filename)
            return vuln
    except FileNotFoundError:
        color_print.warning(
            '{filename} does not exist, skipped.'.format(filename=filename))
        return None
Esempio n. 8
0
    def install_by_version(cls, gadgets, context=None, verbose=False):
        """Install Docker with specified version.

        Args:
            gadgets: Docker gadgets (e.g. docker-ce).
            context: Currently not used.
            verbose: Verbose or not.

        Returns:
            Boolean indicating whether Docker is successfully installed or not.
        """
        if not cls._pre_install(verbose=verbose):
            color_print.error('failed to install prerequisites')
            return False
        for gadget in gadgets:
            if not cls._install_one_gadget_by_version(
                    gadget['name'], gadget['version'], verbose=verbose):
                color_print.warning(
                    'docker seems to be installed, but some errors happened during installation')
                # sometimes docker is installed but error occurs during installation
                # so currently we just return true for it
                return True
        return True
Esempio n. 9
0
def load_vuln(filename):
    """Load information about one vulnerability from one file.

    Args:
        filename: File storing information of specific vulnerability.

    Returns:
        If loading succeeds, return information dict about the vulnerability,
        else, return None.
    """
    try:
        with open(filename, 'r') as f:
            # for SafeLoader, see
            # https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation
            vuln = yaml.load(f, Loader=yaml.SafeLoader)
            # e.g. path: vulns_app/thinkphp/5.0.23-rce/
            vuln['path'] = filename[:len(filename) -
                                    len(config.vuln_app_desc_file)]
            return vuln
    except FileNotFoundError:
        color_print.warning(
            '{filename} does not exist, skipped.'.format(filename=filename))
        return None
Esempio n. 10
0
def kata_specified_installed(temp_gadget, kata_runtime_type, verbose=False):
    """Check whether kata-containers with specified version has been installed.

    Args:
        temp_gadget: Kata-containers gadgets (e.g. kata-containers).
        kata_runtime_type: Runtime of Kata (e.g. qemu/clh/...).
        verbose:

    Returns:
        If kata-containers with specified version has been installed, return True,
        else False.
    """
    try:
        _, stderr = verbose_func.verbose_output(verbose)
        temp_cmd = '{base_dir}/bin/kata-runtime --version'.format(
            base_dir=config.kata_tar_decompress_dest).split()
        res = subprocess.run(
            temp_cmd,
            stdout=subprocess.PIPE,
            stderr=stderr,
            check=True)
        version_string = res.stdout.decode('utf-8').split('\n')[0]
        server_version = re.search(
            r'.*([\d]+\.[\d]+\.[\d]+)',
            version_string).group(1)
        if server_version == temp_gadget[0]['version']:
            # check whether kata runtime type is also correct
            try:
                link_target = os.readlink(
                    '{kata_config_dir}/configuration.toml'.format(kata_config_dir=config.kata_config_dir))
                actual_runtime_type = link_target.split('.')[0].split('-')[-1]
                if actual_runtime_type != kata_runtime_type:
                    color_print.warning(
                        'your expected kata runtime type is {expected}, while current type is {actual}'.format(
                            expected=kata_runtime_type, actual=actual_runtime_type))
                    color_print.warning(
                        'you can configure runtime type manually')
            except (FileNotFoundError, OSError):
                color_print.warning(
                    'configuration.toml does not exist or is not an effective symbol link to real configurations')
                color_print.warning(
                    'please check configurations in {kata_config_dir} manually'.format(
                        kata_config_dir=config.kata_config_dir))
            return True
        return False
    except (IndexError, AttributeError, FileNotFoundError, subprocess.CalledProcessError):
        return False