예제 #1
0
    def check_core_alteration(self, core_url: str) -> List[Alteration]:
        self.get_archive_name()
        alterations = []
        temp_directory = uCMS.TempDir.create()

        LOGGER.print_cms("info", "[+] Checking core alteration", "", 0)

        try:
            response = requests.get(core_url)
            response.raise_for_status()

            if response.status_code == 200:
                zip_file = zipfile.ZipFile(io.BytesIO(response.content), "r")
                zip_file.extractall(temp_directory)
                zip_file.close()

        except requests.exceptions.HTTPError as e:
            LOGGER.print_cms(
                "alert", "[-] Unable to find the original archive. Search manually !", "", 0
            )
            self.core.alterations = alterations
            LOGGER.debug(str(e))
            return self.core.alterations

        clean_core_path = os.path.join(temp_directory, Path(self.get_archive_name()))

        dcmp = dircmp(clean_core_path, self.dir_path, self.core.ignored_files)
        uCMS.diff_files(dcmp, alterations, self.dir_path) # type: ignore # ignore for "dcmp" variable

        self.core.alterations = alterations
        if alterations is not None:
            msg = "[+] For further analysis, archive downloaded here : " + clean_core_path
            LOGGER.print_cms("info", msg, "", 0)

        return self.core.alterations
예제 #2
0
    def addon_analysis(self, addon_type: str) -> List[Addon]:
        temp_directory = uCMS.TempDir.create()
        addons = []
        addons_path = ""

        LOGGER.print_cms(
            "info",
            "#######################################################" +
            "\n\t\t" + addon_type + " analysis" +
            "\n#######################################################",
            "",
            0,
        )

        # Get the list of addon to work with
        if addon_type == "plugins":
            addons_path = self.plugins_dir

        elif addon_type == "themes":
            addons_path = self.themes_dir

        addons_name = uCMS.fetch_addons(
            os.path.join(self.dir_path, addons_path), "standard")

        for addon_name in addons_name:
            addon = Addon()
            addon.type = addon_type
            addon.name = addon_name
            addon.filename = addon_name + self.addon_extension

            LOGGER.print_cms("info", "[+] " + addon_name, "", 0)

            addon_path = os.path.join(self.dir_path, addons_path, addon_name)

            try:
                # Get addon version
                self.get_addon_version(addon, addon_path,
                                       self.regex_version_addon, '"')

                # Check addon last version
                self.get_addon_last_version(addon)

                # Check if there are known CVE
                self.check_vulns_addon(addon)

                # Check if the addon have been altered
                self.check_addon_alteration(addon, addon_path, temp_directory)

                addons.append(addon)
            except Exception as e:
                LOGGER.debug(str(e))
                addons.append(addon)
                pass

        if addon_type == "plugins":
            self.plugins = addons
        elif addon_type == "themes":
            self.themes = addons

        return addons
예제 #3
0
    def check_addon_alteration(self, addon: Addon, addon_path: str,
                               temp_directory: str) -> str:

        addon_url = self.get_addon_url(addon)

        LOGGER.print_cms("default", f"To download the addon: {addon_url}", "",
                         1)
        altered = ""

        try:
            response = requests.get(addon_url)
            response.raise_for_status()

            if response.status_code == 200:
                zip_file = zipfile.ZipFile(io.BytesIO(response.content), "r")
                zip_file.extractall(temp_directory)
                zip_file.close()

                project_dir_hash = dirhash(addon_path, "sha1")
                ref_dir = os.path.join(temp_directory, addon.name)
                ref_dir_hash = dirhash(ref_dir, "sha1")

                if project_dir_hash == ref_dir_hash:
                    altered = "NO"
                    LOGGER.print_cms("good",
                                     f"Different from sources : {altered}", "",
                                     1)

                else:
                    altered = "YES"
                    LOGGER.print_cms("alert",
                                     f"Different from sources : {altered}", "",
                                     1)

                    dcmp = dircmp(addon_path, ref_dir,
                                  self.ignored_files_addon)
                    uCMS.diff_files(dcmp, addon.alterations, addon_path)

                addon.altered = altered

                if addon.alterations is not None:
                    LOGGER.print_cms(
                        "info",
                        f"[+] For further analysis, archive downloaded here : {ref_dir}",
                        "",
                        1,
                    )

        except requests.exceptions.HTTPError as e:
            addon.notes = "The download link is not standard. Search manually !"
            LOGGER.print_cms("alert", addon.notes, "", 1)
            LOGGER.debug(str(e))
            return addon.notes

        return altered
예제 #4
0
    def detect_core_major_version(self) -> str:
        version_major = ""
        dpl_file_paths = {
            "8": "core/lib/Drupal.php",
            "7": "includes/bootstrap.inc"
        }

        for dpl_version, dpl_file_path in dpl_file_paths.items():
            if os.path.isfile(os.path.join(self.dir_path, dpl_file_path)):
                version_major = dpl_version

        LOGGER.debug(version_major)

        return version_major
예제 #5
0
    def get_core_last_version(self) -> str:
        """
        Fetch information on last release
        """
        url_release = self.get_url_release()

        try:
            response = requests.get(url_release)
            response.raise_for_status()

            if response.status_code == 200:
                self.last_version = self.extract_core_last_version(response)

        except requests.exceptions.HTTPError as e:
            LOGGER.print_cms("alert", "[-] Unable to retrieve last version. Search manually !", "", 1)
            LOGGER.debug(str(e))
            pass
        return self.last_version
예제 #6
0
    def get_core_version(self) -> str:
        suspects = []

        try:
            with open(
                    os.path.join(self.dir_path,
                                 self.core_suspect_file_path)) as version_file:
                for line in version_file:
                    version_core_match = self.regex_version_core.search(line)
                    if version_core_match:
                        suspects.append(version_core_match.group(1).strip())
                        break
        except FileNotFoundError as e:
            LOGGER.debug(str(e))
            pass

        suspects_length = len(suspects)

        if suspects_length == 0:
            LOGGER.print_cms("alert",
                             "[-] Version not found. Search manually !", "", 0)
            return ""

        elif suspects_length == 1:
            LOGGER.print_cms("info", "[+] Version used : " + suspects[0], "",
                             0)
            self.core.version = suspects[0]
            self.core.version_major = suspects[0].split(".")[0]
            return suspects[0]

        else:
            for suspect in suspects:
                LOGGER.print_cms(
                    "alert",
                    "[-] Multiple versions found." + suspect + " You "
                    "should probably check by yourself manually.",
                    "",
                    0,
                )
            return ""