Skip to content

Commit

Permalink
Merge pull request #120 from timoles:plugin_CVE-2021-3129
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 404652894
Change-Id: I7ea7df1d87cee148d94eab224d91c97306ee641c
  • Loading branch information
Copybara-Service committed Oct 20, 2021
2 parents b36a97a + 3205bb5 commit e5a0123
Show file tree
Hide file tree
Showing 7 changed files with 432 additions and 1 deletion.
8 changes: 7 additions & 1 deletion community/README.md
Expand Up @@ -7,6 +7,12 @@ This directory contains plugins contributed by community members.
## Currently released plugins

### Detectors
- [CVE-2021-29441 Nacos < 1.4.1 Authentication Bypass](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/CVE-2021-29441)

#### Authentication Bypass
* [CVE-2021-29441 Nacos < 1.4.1 Authentication Bypass](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/CVE-2021-29441)

#### Remote Code Execution
* [Unauthenticated RCE in Laravel <= 8.4.2 using Debug Mode (CVE-2021-3129) Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/laravel_cve_2021_3129)

#### Path Traversal
* [Apache HTTP Server Path traversal and disclosure (CVE-2021-41773) Detector](https://github.com/google/tsunami-security-scanner-plugins/tree/master/community/detectors/apache_http_server_cve_2021_41773)
18 changes: 18 additions & 0 deletions community/detectors/laravel_cve_2021_3129/README.md
@@ -0,0 +1,18 @@
# Laravel CVE-2021-3129 Detector

This plugin detects an pre-auth remote code execution vulnerability in Laravel <= 8.4.2 running in debug mode.

More information on the vulnerability:

* [CVE-2021-3129](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3129)
* [National Vulnerability Database (NVD)](https://nvd.nist.gov/vuln/detail/CVE-2021-3129)

## Build jar file for this plugin

Using `gradlew`:

```shell
./gradlew jar
```

A Tsunami identifiable jar file is located in the `build/libs` directory.
69 changes: 69 additions & 0 deletions community/detectors/laravel_cve_2021_3129/build.gradle
@@ -0,0 +1,69 @@
plugins {
id 'java-library'
}

description = 'Tsunami CVE-2021-3129 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_1_8
targetCompatibility = JavaVersion.VERSION_1_8

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 {
tsunamiVersion = '0.0.2'
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.google.truth.extensions:truth-java8-extension:${truthVersion}"
testImplementation "com.google.truth.extensions:truth-proto-extension:${truthVersion}"

testImplementation "com.squareup.okhttp3:mockwebserver:${okhttpVersion}"
}
1 change: 1 addition & 0 deletions community/detectors/laravel_cve_2021_3129/settings.gradle
@@ -0,0 +1 @@
rootProject.name = 'cve20213129detector'
@@ -0,0 +1,146 @@
/*
* 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.detectors.rce.cve20213129;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.net.HttpHeaders.ACCEPT;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;

import com.google.common.collect.ImmutableList;
import com.google.common.flogger.GoogleLogger;
import com.google.common.net.MediaType;
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.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 the CVE-2021-3129 vulnerability. */
@PluginInfo(
type = PluginType.VULN_DETECTION,
name = "Cve20213129VulnDetector",
version = "0.1",
description =
"This plugin detects Laravel (Version <= 8.4.2) running in debug mode, while using Ignition"
+ " (Version <= v2.5.1). Such instances are vulnerable to an unauthenticated remote"
+ " code execution vulnerability (CVE-2021-3129), due to unsafe user input handling.",
author = "Timo Mueller (work@mtimo.de)",
bootstrapModule = Cve20213129VulnDetectorBootstrapModule.class)

@ForWebService
public final class Cve20213129VulnDetector implements VulnDetector {
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
private static final String QUERY_PATH = "_ignition/execute-solution";
private static final String QUERY_PAYLOAD =
"{\"solution\":"
+ " \"Facade\\\\Ignition\\\\Solutions\\\\MakeViewVariableOptionalSolution\",\"parameters\":"
+ " {\"variableName\": \"cve20213129_tsunami\", \"viewFile\":"
+ " \"phar://Tsunami_iDontExist\"}}";
private static final CharSequence DETECTION_STRING =
"file_get_contents(phar://Tsunami_iDontExist";

private final HttpClient httpClient;
private final Clock utcClock;

@Inject
Cve20213129VulnDetector(@UtcClock Clock utcClock, HttpClient httpClient) {
this.utcClock = checkNotNull(utcClock);
this.httpClient = checkNotNull(httpClient);
}

@Override
public DetectionReportList detect(
TargetInfo targetInfo, ImmutableList<NetworkService> matchedServices) {
logger.atInfo().log("Cve20213129VulnDetector 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) {
String targetUri = NetworkServiceUtils.buildWebApplicationRootUrl(networkService) + QUERY_PATH;
try {
HttpResponse httpResponse =
httpClient.send(
HttpRequest.post(targetUri)
.setHeaders(
HttpHeaders.builder()
.addHeader(CONTENT_TYPE, MediaType.JSON_UTF_8.toString())
.addHeader(ACCEPT, MediaType.JSON_UTF_8.toString())
.build())
.setRequestBody(ByteString.copyFromUtf8(QUERY_PAYLOAD))
.build(),
networkService);
return httpResponse.bodyString().orElseGet(() -> "").contains(DETECTION_STRING);
} catch (IOException e) {
logger.atWarning().withCause(e).log("Request to target %s failed", networkService);
return false;
}
}

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_2021_3129"))
.setSeverity(Severity.CRITICAL)
.setTitle("CVE-2021-3129: Unauthenticated RCE in Laravel using Debug Mode")
.setDescription(
"Ignition before 2.5.2, as used in Laravel, allows unauthenticated remote"
+ " attackers to execute arbitrary code because of insecure usage of"
+ " file_get_contents() and file_put_contents(). This is exploitable on"
+ " sites using debug mode with Laravel before 8.4.3")
.setRecommendation(
"Update Laravel to at least version 8.4.3, and facade/ignition to at least"
+ " version 2.5.2.For production systems it is advised to disable debug"
+ " mode within the Laravel configuration."))
.build();
}
}
@@ -0,0 +1,27 @@
/*
* 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.detectors.rce.cve20213129;

import com.google.tsunami.plugin.PluginBootstrapModule;

/** A {@link PluginBootstrapModule} for {@link Cve20213129VulnDetector}. */
public final class Cve20213129VulnDetectorBootstrapModule extends PluginBootstrapModule {

@Override
protected void configurePlugin() {
registerPlugin(Cve20213129VulnDetector.class);
}
}

0 comments on commit e5a0123

Please sign in to comment.