diff --git a/google/detectors/rce/ai/cve20236018/README.md b/google/detectors/rce/ai/cve20236018/README.md deleted file mode 100644 index 8662764d7..000000000 --- a/google/detectors/rce/ai/cve20236018/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# h2o CVE-2023-6018 Detector - -This plugin for Tsunami detects a remote code execution (RCE) vulnerability in -h2o, which is an ML platform. - -More information on the vulnerability: - -* [CVE-2023-6018](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-6018) -* [POC](https://github.com/protectai/ai-exploits/blob/main/h2o/nuclei-templates/h2o-pojo-rce.yaml) - -## 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/ai/cve20236018/build.gradle b/google/detectors/rce/ai/cve20236018/build.gradle deleted file mode 100644 index 13f39fc30..000000000 --- a/google/detectors/rce/ai/cve20236018/build.gradle +++ /dev/null @@ -1,65 +0,0 @@ -plugins { - id 'java-library' -} - -description = 'Tsunami detector for CVE-2023-6018.' -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/ai/cve20236018/settings.gradle b/google/detectors/rce/ai/cve20236018/settings.gradle deleted file mode 100644 index e0767094d..000000000 --- a/google/detectors/rce/ai/cve20236018/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'cve20236018' diff --git a/google/detectors/rce/ai/cve20236018/src/main/java/com/google/tsunami/plugins/cve20236018/Cve20236018Detector.java b/google/detectors/rce/ai/cve20236018/src/main/java/com/google/tsunami/plugins/cve20236018/Cve20236018Detector.java deleted file mode 100644 index 4f423770e..000000000 --- a/google/detectors/rce/ai/cve20236018/src/main/java/com/google/tsunami/plugins/cve20236018/Cve20236018Detector.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.cve20236018; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.ImmutableList.toImmutableList; - -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.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.Instant; -import javax.inject.Inject; - -/** A VulnDetector plugin for CVE 20236018. */ -@PluginInfo( - type = PluginType.VULN_DETECTION, - name = "CVE-2023-6018 Detector", - version = "0.1", - description = - "This detector checks for occurrences of CVE-2023-6018 in h2o default installations.", - author = "Marius Steffens (mariussteffens@google.com)", - bootstrapModule = Cve20236018DetectorModule.class) -@ForWebService -public final class Cve20236018Detector implements VulnDetector { - private static final GoogleLogger logger = GoogleLogger.forEnclosingClass(); - - private final Clock utcClock; - private final HttpClient httpClient; - private final PayloadGenerator payloadGenerator; - - @Inject - Cve20236018Detector( - @UtcClock Clock utcClock, HttpClient httpClient, PayloadGenerator payloadGenerator) { - this.utcClock = checkNotNull(utcClock); - this.httpClient = checkNotNull(httpClient).modify().setFollowRedirects(false).build(); - this.payloadGenerator = checkNotNull(payloadGenerator); - } - - @Override - public DetectionReportList detect( - TargetInfo targetInfo, ImmutableList matchedServices) { - return DetectionReportList.newBuilder() - .addAllDetectionReports( - matchedServices.stream() - .filter(this::isServiceVulnerable) - .map(networkService -> buildDetectionReport(targetInfo, networkService)) - .collect(toImmutableList())) - .build(); - } - - private boolean isServiceVulnerable(NetworkService networkService) { - var payload = getTsunamiCallbackHttpPayload(); - - if (!payload.getPayloadAttributes().getUsesCallbackServer()) { - logger.atWarning().log( - "Tsunami callback server is not setup for this environment, cannot run CVE-2023-6018" - + " Detector."); - return false; - } - - var requestWithPayload = getExploitRequest(networkService, payload); - - try { - var response = this.httpClient.send(requestWithPayload, networkService); - - return looksLikeH2oResponse(response) && payload.checkIfExecuted(); - } catch (IOException e) { - logger.atWarning().withCause(e).log("Failed to send request."); - return false; - } - } - - private Payload getTsunamiCallbackHttpPayload() { - return this.payloadGenerator.generate( - PayloadGeneratorConfig.newBuilder() - .setVulnerabilityType(PayloadGeneratorConfig.VulnerabilityType.SSRF) - .setInterpretationEnvironment( - PayloadGeneratorConfig.InterpretationEnvironment.INTERPRETATION_ANY) - .setExecutionEnvironment(PayloadGeneratorConfig.ExecutionEnvironment.EXEC_ANY) - .build()); - } - - private HttpRequest getExploitRequest(NetworkService networkService, Payload payload) { - String rootUrl = NetworkServiceUtils.buildWebApplicationRootUrl(networkService); - String body = String.format("model_id=irrelevant&path=http://%s", payload.getPayload()); - return HttpRequest.post(rootUrl + "3/ModelBuilders/generic") - .setHeaders( - HttpHeaders.builder() - .addHeader("content-type", "application/x-www-form-urlencoded") - .build()) - .setRequestBody(ByteString.copyFromUtf8(body)) - .build(); - } - - private boolean looksLikeH2oResponse(HttpResponse response) { - return response.status().isSuccess() - && response.bodyString().get().contains("model_id") - && response.bodyString().get().contains("Import MOJO Model"); - } - - 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("GOOGLE").setValue("CVE-2023-6018")) - .setSeverity(Severity.CRITICAL) - .setTitle("CVE-2023-6018") - .setDescription( - "An attacker can use the model upload functionality to load remote Java code" - + " and gains code execution on the server hosting the h2o application.") - .setRecommendation( - "There is no patch available as this is considered intended functionality." - + " Restrict access to h2o to be local only, and do not expose it to the" - + " network.")) - .build(); - } -} diff --git a/google/detectors/rce/ai/cve20236018/src/main/java/com/google/tsunami/plugins/cve20236018/Cve20236018DetectorModule.java b/google/detectors/rce/ai/cve20236018/src/main/java/com/google/tsunami/plugins/cve20236018/Cve20236018DetectorModule.java deleted file mode 100644 index bfd01f892..000000000 --- a/google/detectors/rce/ai/cve20236018/src/main/java/com/google/tsunami/plugins/cve20236018/Cve20236018DetectorModule.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.cve20236018; - -import com.google.tsunami.plugin.PluginBootstrapModule; - -/** An module registering the detector for CVE-2023-6018. */ -public final class Cve20236018DetectorModule extends PluginBootstrapModule { - @Override - protected void configurePlugin() { - registerPlugin(Cve20236018Detector.class); - } -} diff --git a/google/detectors/rce/ai/cve20236018/src/main/resources/com/google/tsunami/plugins/cve20236018/response.json b/google/detectors/rce/ai/cve20236018/src/main/resources/com/google/tsunami/plugins/cve20236018/response.json deleted file mode 100644 index f2e291bdf..000000000 --- a/google/detectors/rce/ai/cve20236018/src/main/resources/com/google/tsunami/plugins/cve20236018/response.json +++ /dev/null @@ -1 +0,0 @@ -{"__meta":{"schema_version":3,"schema_name":"GenericV3","schema_type":"Generic"},"_exclude_fields":null,"job":{"__meta":{"schema_version":3,"schema_name":"JobV3","schema_type":"Job"},"key":{"__meta":{"schema_version":3,"schema_name":"JobKeyV3","schema_type":"Key"},"name":"$0301ac13000232d4ffffffff$_b856232cfb8180f591ebc1cc02c94ece","type":"Key","URL":"/3/Jobs/$0301ac13000232d4ffffffff$_b856232cfb8180f591ebc1cc02c94ece"},"description":"Generic","status":"RUNNING","progress":0.0,"progress_msg":null,"start_time":1704983654930,"msec":0,"dest":{"__meta":{"schema_version":3,"schema_name":"ModelKeyV3","schema_type":"Key"},"name":"random","type":"Key","URL":"/3/Models/random"},"warnings":null,"exception":null,"stacktrace":null,"auto_recoverable":false,"ready_for_view":true},"algo":"generic","algo_full_name":"Import MOJO Model","can_build":["Unknown","Binomial","Multinomial","Ordinal","Regression","HGLMRegression","Clustering","AutoEncoder","TargetEncoder","DimReduction","WordEmbedding","CoxPH","AnomalyDetection","KLime","BinomialUplift"],"visibility":"Stable","supervised":false,"messages":[],"error_count":0,"parameters":[{"__meta":{"schema_version":3,"schema_name":"ModelParameterSchemaV3","schema_type":"Iced"},"name":"model_id","label":"model_id","help":"Destination id for this model; auto-generated if not specified.","required":false,"type":"Key","default_value":null,"actual_value":{"__meta":{"schema_version":3,"schema_name":"ModelKeyV3","schema_type":"Key"},"name":"random","type":"Key","URL":"/3/Models/random"},"input_value":null,"level":"critical","values":[],"is_member_of_frames":[],"is_mutually_exclusive_with":[],"gridable":false},{"__meta":{"schema_version":3,"schema_name":"ModelParameterSchemaV3","schema_type":"Iced"},"name":"model_key","label":"model_key","help":"Key to the self-contained model archive already uploaded to H2O.","required":false,"type":"Key","default_value":null,"actual_value":null,"input_value":null,"level":"critical","values":[],"is_member_of_frames":[],"is_mutually_exclusive_with":[],"gridable":false},{"__meta":{"schema_version":3,"schema_name":"ModelParameterSchemaV3","schema_type":"Iced"},"name":"path","label":"path","help":"Path to file with self-contained model archive.","required":false,"type":"string","default_value":null,"actual_value":"http://d853834d35fcd018738a0ed53127266c88beef52708fe59008ee1da9.asm-prod.cb.goog","input_value":null,"level":"critical","values":[],"is_member_of_frames":[],"is_mutually_exclusive_with":[],"gridable":false}]} diff --git a/google/detectors/rce/ai/cve20236018/src/test/java/com/google/tsunami/plugins/cve20236018/Cve20236018DetectorTest.java b/google/detectors/rce/ai/cve20236018/src/test/java/com/google/tsunami/plugins/cve20236018/Cve20236018DetectorTest.java deleted file mode 100644 index 6637e966e..000000000 --- a/google/detectors/rce/ai/cve20236018/src/test/java/com/google/tsunami/plugins/cve20236018/Cve20236018DetectorTest.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2020 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.cve20236018; - -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.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.TargetInfo; -import com.google.tsunami.proto.Vulnerability; -import com.google.tsunami.proto.VulnerabilityId; -import java.io.IOException; -import java.security.SecureRandom; -import java.time.Instant; -import java.util.Arrays; -import javax.inject.Inject; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for the {@link Cve20236018Detector}. */ -@RunWith(JUnit4.class) -public final class Cve20236018DetectorTest { - 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")); - private final SecureRandom testSecureRandom = - new SecureRandom() { - @Override - public void nextBytes(byte[] bytes) { - Arrays.fill(bytes, (byte) 0xFF); - } - }; - - private static String vulnerableResponseBody; - - @Inject private Cve20236018Detector detector; - - @BeforeClass - public static void setUpAll() throws IOException { - vulnerableResponseBody = - Resources.toString( - Resources.getResource(Cve20236018Detector.class, "response.json"), UTF_8); - } - - @Before - public void setUp() throws IOException { - mockTargetService.start(); - mockCallbackServer.start(); - - Guice.createInjector( - new FakeUtcClockModule(fakeUtcClock), - new HttpClientModule.Builder().build(), - FakePayloadGeneratorModule.builder() - .setCallbackServer(mockCallbackServer) - .setSecureRng(testSecureRandom) - .build(), - new Cve20236018DetectorModule()) - .injectMembers(this); - } - - @After - public void tearDown() throws Exception { - mockTargetService.shutdown(); - mockCallbackServer.shutdown(); - } - - @Test - public void detect_withCallbackServer_onVulnerableTarget_returnsVulnerability() - throws IOException { - mockTargetService.enqueue( - new MockResponse().setResponseCode(HttpStatus.OK.code()).setBody(vulnerableResponseBody)); - 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)); - - 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("GOOGLE") - .setValue("CVE-2023-6018")) - .setSeverity(Severity.CRITICAL) - .setTitle("CVE-2023-6018")) - .build()); - } - - @Test - public void detect_withCallbackServer_butNoCallback_returnsEmpty() throws IOException { - mockTargetService.enqueue( - new MockResponse().setResponseCode(HttpStatus.OK.code()).setBody(vulnerableResponseBody)); - 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_withCallbackServer_onNonH2oPageButCallback_returnsEmpty() throws IOException { - mockTargetService.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.code())); - 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)); - - assertThat(detectionReports.getDetectionReportsList()).isEmpty(); - } - - @Test - public void detect_withoutCallbackServer_returnsEmpty() throws IOException { - NetworkService targetNetworkService = - NetworkService.newBuilder() - .setNetworkEndpoint( - forHostnameAndPort(mockTargetService.getHostName(), mockTargetService.getPort())) - .addSupportedHttpMethods("POST") - .build(); - TargetInfo targetInfo = - TargetInfo.newBuilder() - .addNetworkEndpoints(targetNetworkService.getNetworkEndpoint()) - .build(); - Guice.createInjector( - new FakeUtcClockModule(fakeUtcClock), - new HttpClientModule.Builder().build(), - FakePayloadGeneratorModule.builder().build(), - new Cve20236018DetectorModule()) - .injectMembers(this); - - DetectionReportList detectionReports = - detector.detect(targetInfo, ImmutableList.of(targetNetworkService)); - - assertThat(detectionReports.getDetectionReportsList()).isEmpty(); - } -} diff --git a/templated/templateddetector/plugins/cve/2023/H2o_CVE_2023_6018.textproto b/templated/templateddetector/plugins/cve/2023/H2o_CVE_2023_6018.textproto new file mode 100644 index 000000000..5939a9d19 --- /dev/null +++ b/templated/templateddetector/plugins/cve/2023/H2o_CVE_2023_6018.textproto @@ -0,0 +1,78 @@ +# proto-file: proto/templated_plugin.proto +# proto-message: TemplatedPlugin + +############### +# PLUGIN INFO # +############### + +info: { + type: VULN_DETECTION + name: "H2o_CVE_2023_6018" + author: "Marius Steffens (mariussteffens@google.com)" + version: "1.0" +} + +finding: { + main_id: { + publisher: "GOOGLE" + value: "CVE-2023-6018" + } + title: "CVE-2023-6018" + description: "An attacker can use the model upload functionality to load remote Java code and gains code execution on the server hosting the h2o application." + recommendation: "There is no patch available as this is considered intended functionality. Restrict access to h2o to be local only, and do not expose it to the network." + related_id: { + publisher: "CVE" + value: "CVE-2023-6018" + } +} + +config: {} + +########### +# ACTIONS # +########### + +actions: { + name: "trigger_code_execution" + http_request: { + method: POST + uri: "3/ModelBuilders/generic" + headers: [ + { name: "Content-Type" value: "application/x-www-form-urlencoded" } + ] + data: "model_id=irrelevant&path={{ T_CBS_URI }}" + response: { + http_status: 200 + expect_all: { + conditions: [ + { body: {} contains: "model_id" }, + { body: {} contains: "Import MOJO Model" } + ] + } + } + } +} + +actions: { + name: "sleep" + utility: { sleep: { duration_ms: 1000 } } +} + +actions: { + name: "check_callback_server_logs" + callback_server: { action_type: CHECK } +} + + +############# +# WORKFLOWS # +############# + +workflows: { + condition: REQUIRES_CALLBACK_SERVER + actions: [ + "trigger_code_execution", + "sleep", + "check_callback_server_logs" + ] +} diff --git a/templated/templateddetector/plugins/cve/2023/H2o_CVE_2023_6018_test.textproto b/templated/templateddetector/plugins/cve/2023/H2o_CVE_2023_6018_test.textproto new file mode 100644 index 000000000..231c1af66 --- /dev/null +++ b/templated/templateddetector/plugins/cve/2023/H2o_CVE_2023_6018_test.textproto @@ -0,0 +1,66 @@ +# proto-file: proto/templated_plugin_tests.proto +# proto-message: TemplatedPluginTests + +config: { + tested_plugin: "H2o_CVE_2023_6018" +} + +tests: { + name: "whenVulnerable_returnsTrue" + expect_vulnerability: true + + mock_callback_server: { + enabled: true + has_interaction: true + } + + mock_http_server: { + mock_responses: [ + { + uri: "3/ModelBuilders/generic" + status: 200 + body_content: "{\"model_id\"=\"irrelevant\"&\"algo_full_name\"=\"Import MOJO Model\"}" + } + ] + } +} + +tests: { + name: "whenNoCallback_returnsFalse" + expect_vulnerability: false + + mock_callback_server: { + enabled: true + has_interaction: false + } + + mock_http_server: { + mock_responses: [ + { + uri: "3/ModelBuilders/generic" + status: 200 + body_content: "{\"model_id\"=\"irrelevant\"&\"algo_full_name\"=\"Import MOJO Model\"}" + } + ] + } +} + +tests: { + name: "whenNotH2o_returnsFalse" + expect_vulnerability: false + + mock_callback_server: { + enabled: true + has_interaction: true + } + + mock_http_server: { + mock_responses: [ + { + uri: "TSUNAMI_ANY_URI" + status: 200 + body_content: "Login to your Drupal account" + } + ] + } +} \ No newline at end of file