Esempio n. 1
0
def check_version(banner: str, raw: str, url: str) -> List[Result]:
    results = []

    if not banner.startswith("PHP/"):
        return []

    # we've got a PHP version
    results.append(
        Result(
            f"PHP Version Exposed: {banner}",
            Vulnerabilities.HTTP_PHP_VERSION_EXPOSED,
            url,
            raw,
        )
    )

    # parse the version, and get the latest version - see if the server is up to date
    ver = cast(version.Version, version.parse(banner.split("/")[1]))
    curr_version = version_checker.get_latest_version("php", ver)

    if curr_version is not None and curr_version > ver:
        results.append(
            Result(
                f"PHP Outdated: {ver} - Current: {curr_version}",
                Vulnerabilities.SERVER_PHP_OUTDATED,
                url,
                raw,
            )
        )

    return results
Esempio n. 2
0
def identify(url: str) -> Tuple[Union[str, None], List[Result]]:
    results = []

    # find WordPress
    res, path = _identify_by_path(url, "")

    if path is None:
        res, path = _identify_by_path(url, "blog/")

    # check to see if we have a valid hit
    if path is not None:
        # we have a WordPress install, let's see if we can get a version
        body = res.text

        ver = "Unknown"
        # this works for modern versions
        m = re.search(r"login.min.css\?ver=\d+\.\d+\.?\d*", body)
        if m:
            ver = m.group(0).split("=")[1]
        else:
            # the current method doesn't work, fall back to an older method
            m = re.search(r"load-styles.php\?[\w,;=&%]+;ver=\d+\.\d+\.?\d*", body)
            if m:
                ver = m.group(0).split("=")[-1]

        # report that we found WordPress
        results.append(
            Result.from_evidence(
                Evidence.from_response(res, {"version": ver}),
                f"Found WordPress v{ver} at {path}",
                Vulnerabilities.APP_WORDPRESS_VERSION,
            )
        )

        # is this a current version?
        ver = cast(version.Version, version.parse(ver))
        curr_version = version_checker.get_latest_version("wordpress", ver)

        if curr_version is not None and curr_version > ver:
            results.append(
                Result.from_evidence(
                    Evidence.from_response(
                        res,
                        {
                            "installed_version": str(ver),
                            "current_verison": str(curr_version),
                        },
                    ),
                    f"WordPress Outdated: {ver} - Current: {curr_version}",
                    Vulnerabilities.APP_WORDPRESS_OUTDATED,
                )
            )

        return path, results
    else:
        return None, []
Esempio n. 3
0
def check_banner(banner: str, raw: str, url: str) -> List[Result]:
    if not banner.startswith("nginx"):
        return []

    results: List[Result] = []

    if "/" in banner:
        # we've got a Nginx version
        results.append(
            Result(
                f"Nginx Version Exposed: {banner}",
                Vulnerabilities.HTTP_BANNER_NGINX_VERSION,
                url,
                {
                    "response": raw,
                    "banner": banner
                },
            ))

        # parse the version, and get the latest version - see if the server is up to date
        ver = cast(version.Version, version.parse(banner.split("/")[1]))
        curr_version = version_checker.get_latest_version("nginx", ver)

        if curr_version is not None and curr_version > ver:
            results.append(
                Result(
                    f"Nginx Outdated: {ver} - Current: {curr_version}",
                    Vulnerabilities.SERVER_NGINX_OUTDATED,
                    url,
                    {
                        "response": raw,
                        "banner": banner
                    },
                ))
    else:
        # this means that it's just a generic banner, with no info
        results.append(
            Result(
                "Generic Nginx Server Banner Found",
                Vulnerabilities.HTTP_BANNER_GENERIC_NGINX,
                url,
                {
                    "response": raw,
                    "banner": banner
                },
            ))

    return results
Esempio n. 4
0
def _check_version_outdated(ver: str, url: str, body: str) -> List[Result]:
    results: List[Result] = []

    # parse the version, and get the latest version - see if the server is up to date
    ver = cast(version.Version, version.parse(ver))
    curr_version = version_checker.get_latest_version("apache_tomcat", ver)

    if curr_version is not None and curr_version > ver:
        results.append(
            Result(
                f"Apache Tomcat Outdated: {ver} - Current: {curr_version}",
                Vulnerabilities.SERVER_TOMCAT_OUTDATED,
                url,
                [ver, curr_version, body],
            ))

    return results
Esempio n. 5
0
def check_version(banner: str, raw: str, url: str, headers: Dict) -> List[Result]:
    results: List[Result] = []

    if not banner.startswith("Microsoft-IIS/"):
        return results

    # we've got an IIS version
    results.append(
        Result(
            f"IIS Version Exposed: {banner}",
            Vulnerabilities.HTTP_BANNER_IIS_VERSION,
            url,
            raw,
        )
    )

    # parse the version, and get the latest version - see if the server is up to date
    ver = cast(version.Version, version.parse(banner.split("/")[1]))
    curr_version = version_checker.get_latest_version("iis", ver)

    if curr_version is not None and curr_version > ver:
        results.append(
            Result(
                f"IIS Outdated: {ver} - Current: {curr_version}",
                Vulnerabilities.SERVER_IIS_OUTDATED,
                url,
                raw,
            )
        )

    # IIS servers may expose a couple other versions, related to ASP.NET, check for those
    if "X-AspNetMvc-Version" in headers:
        results.append(
            Result(
                f'ASP.NET MVC Version Exposed: {headers["X-AspNetMvc-Version"]}',
                Vulnerabilities.HTTP_HEADER_X_ASPNETMVC_VERSION,
                url,
                raw,
            )
        )

        ver = cast(version.Version, version.parse(headers["X-AspNetMvc-Version"]))
        curr_version = version_checker.get_latest_version("aspnet_mvc", ver)

        if curr_version is not None and curr_version > ver:
            results.append(
                Result(
                    f"ASP.NET MVC Outdated: {ver} - Current: {curr_version}",
                    Vulnerabilities.SERVER_ASPNETMVC_OUTDATED,
                    url,
                    raw,
                )
            )

    if "X-AspNet-Version" in headers:
        results.append(
            Result(
                f'ASP.NET CLR Version Exposed: {headers["X-AspNet-Version"]}',
                Vulnerabilities.HTTP_HEADER_X_ASPNET_VERSION,
                url,
                raw,
            )
        )

        ver = cast(version.Version, version.parse(headers["X-AspNet-Version"]))
        curr_version = version_checker.get_latest_version("aspnet", ver)

        if curr_version is not None and curr_version > ver:
            results.append(
                Result(
                    f"ASP.NET Outdated: {ver} - Current: {curr_version}",
                    Vulnerabilities.SERVER_ASPNET_OUTDATED,
                    url,
                    raw,
                )
            )

    return results
Esempio n. 6
0
def check_banner(banner: str, raw: str, url: str) -> List[Result]:
    # don't bother if this doesn't look like Apache
    if "Apache" not in banner or "Apache-" in banner:
        return []

    results = []

    if "/" in banner:
        # this means that we have a version
        modules = banner.split(" ")

        # double check that we have a '/' in the first part
        if "/" in modules[0]:
            # we have a version
            results.append(
                Result(
                    f"Apache Server Version Exposed: {modules[0]}",
                    Vulnerabilities.HTTP_BANNER_APACHE_VERSION,
                    url,
                    raw,
                ))

            # parse the version, and get the latest version - see if the server is up to date
            ver = cast(version.Version,
                       version.parse(modules[0].split("/")[1]))
            curr_version = version_checker.get_latest_version(
                "apache_httpd", ver)

            if curr_version is not None and curr_version > ver:
                results.append(
                    Result(
                        f"Apache Server Outdated: {ver} - Current: {curr_version}",
                        Vulnerabilities.SERVER_APACHE_OUTDATED,
                        url,
                        raw,
                    ))

        # check to see what else we have
        if len(modules) > 1:
            if modules[1].startswith("("):
                # this is a distro string, garbage
                modules.remove(modules[1])

            for module in modules:
                if module.startswith("PHP/"):
                    results += php.check_version(module, raw, url)

                if module.startswith("OpenSSL/"):
                    results.append(
                        Result(
                            f"OpenSSL Version Exposed: {module}",
                            Vulnerabilities.HTTP_BANNER_OPENSSL_VERSION,
                            url,
                            raw,
                        ))

    else:
        # this means that it's just a generic 'Apache' banner, with no info
        results.append(
            Result(
                "Generic Apache Server Banner Found",
                Vulnerabilities.HTTP_BANNER_GENERIC_APACHE,
                url,
                raw,
            ))

    return results