Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: Disable VPC Flow Logs on a Subnet
---

# Disable VPC Flow Logs on a Subnet


<span class="smallcaps w3-badge w3-blue w3-round w3-text-white" title="This attack technique can be detonated multiple times">idempotent</span>

Platform: GCP

## Mappings

- MITRE ATT&CK
- Defense Evasion



## Description


Disables VPC flow logging on a subnet by patching its log configuration.
VPC flow logs record network traffic metadata for all VM instances in a subnet,
providing visibility for network monitoring and forensic investigation.

<span style="font-variant: small-caps;">Warm-up</span>:

- Create a VPC network
- Create a subnet with VPC flow logs enabled

<span style="font-variant: small-caps;">Detonation</span>:

- Disable VPC flow logs on the subnet by patching its <code>logConfig.enable</code> field to <code>false</code>

Revert:

- Re-enable VPC flow logs on the subnet

References:

- https://cloud.google.com/vpc/docs/using-flow-logs
- https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks/patch
- https://github.com/GoogleCloudPlatform/security-analytics/blob/main/src/3.02/3.02.md
- https://securitylabs.datadoghq.com/cloud-security-atlas/attacks/removing-vpc-flow-logs/


## Instructions

```bash title="Detonate with Stratus Red Team"
stratus detonate gcp.defense-evasion.remove-vpc-flow-logs
```
## Detection


Identify when VPC flow logging is disabled on a subnet by monitoring for
<code>v1.compute.subnetworks.patch</code> events in GCP Admin Activity audit logs
where the request sets <code>logConfig.enable</code> to <code>false</code>.


2 changes: 2 additions & 0 deletions docs/attack-techniques/GCP/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Note that some Stratus attack techniques may correspond to more than a single AT

- [Attempt to Remove a GCP Project from its Organization](./gcp.defense-evasion.remove-project-from-organization.md)

- [Disable VPC Flow Logs on a Subnet](./gcp.defense-evasion.remove-vpc-flow-logs.md)

- [Delete a GCP Log Sink](./gcp.defense-evasion.delete-logging-sink.md)

- [Disable a GCP Log Sink](./gcp.defense-evasion.disable-logging-sink.md)
Expand Down
1 change: 1 addition & 0 deletions docs/attack-techniques/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ This page contains the list of all Stratus Attack Techniques.
| [Delete a Cloud DNS Logging Policy](./GCP/gcp.defense-evasion.delete-dns-logs.md) | [GCP](./GCP/index.md) | Defense Evasion |
| [Disable Data Access Audit Logs for a GCP Service](./GCP/gcp.defense-evasion.disable-audit-logs.md) | [GCP](./GCP/index.md) | Defense Evasion |
| [Attempt to Remove a GCP Project from its Organization](./GCP/gcp.defense-evasion.remove-project-from-organization.md) | [GCP](./GCP/index.md) | Defense Evasion |
| [Disable VPC Flow Logs on a Subnet](./GCP/gcp.defense-evasion.remove-vpc-flow-logs.md) | [GCP](./GCP/index.md) | Defense Evasion |
| [Enumerate Permissions of a GCP Service Account](./GCP/gcp.discovery.enumerate-permissions.md) | [GCP](./GCP/index.md) | Discovery |
| [Exfiltrate Compute Disk by sharing it](./GCP/gcp.exfiltration.share-compute-disk.md) | [GCP](./GCP/index.md) | Exfiltration |
| [Exfiltrate Compute Image by sharing it](./GCP/gcp.exfiltration.share-compute-image.md) | [GCP](./GCP/index.md) | Exfiltration |
Expand Down
5 changes: 3 additions & 2 deletions docs/attack-techniques/mitre-attack-coverage-matrices.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ This provides coverage matrices of MITRE ATT&CK tactics and techniques currently
<tr><td><a href="../GCP/gcp.initial-access.use-compute-sa-outside-gcp">Steal and Use the GCE Default Service Account Token from Outside Google Cloud</a></td><td><a href="../GCP/gcp.lateral-movement.add-sshkey-instance-metadata">Register SSH public key to instance metadata</a></td><td><a href="../GCP/gcp.persistence.create-admin-service-account">Create an Admin GCP Service Account</a></td><td><a href="../GCP/gcp.defense-evasion.delete-dns-logs">Delete a Cloud DNS Logging Policy</a></td><td><a href="../GCP/gcp.credential-access.secretmanager-retrieve-secrets">Retrieve a High Number of Secret Manager secrets</a></td><td><a href="../GCP/gcp.discovery.enumerate-permissions">Enumerate Permissions of a GCP Service Account</a></td><td><a href="../GCP/gcp.lateral-movement.add-sshkey-instance-metadata">Register SSH public key to instance metadata</a></td><td><a href="../GCP/gcp.exfiltration.share-compute-disk">Exfiltrate Compute Disk by sharing it</a></td><td><a href="../GCP/gcp.impact.create-gpu-vm">Create a GCE GPU Virtual Machine</a></td></tr>
<tr><td></td><td><a href="../GCP/gcp.persistence.backdoor-service-account-policy">Backdoor a GCP Service Account through its IAM Policy</a></td><td><a href="../GCP/gcp.persistence.create-service-account-key">Create a GCP Service Account Key</a></td><td><a href="../GCP/gcp.defense-evasion.disable-audit-logs">Disable Data Access Audit Logs for a GCP Service</a></td><td><a href="../GCP/gcp.initial-access.use-compute-sa-outside-gcp">Steal and Use the GCE Default Service Account Token from Outside Google Cloud</a></td><td></td><td></td><td><a href="../GCP/gcp.exfiltration.share-compute-image">Exfiltrate Compute Image by sharing it</a></td><td><a href="../GCP/gcp.impact.create-instances-in-multiple-zones">Create GCE Instances in Multiple Zones</a></td></tr>
<tr><td></td><td><a href="../GCP/gcp.persistence.create-admin-service-account">Create an Admin GCP Service Account</a></td><td><a href="../GCP/gcp.privilege-escalation.impersonate-service-accounts">Impersonate GCP Service Accounts</a></td><td><a href="../GCP/gcp.defense-evasion.remove-project-from-organization">Attempt to Remove a GCP Project from its Organization</a></td><td></td><td></td><td></td><td><a href="../GCP/gcp.exfiltration.share-compute-snapshot">Exfiltrate Compute Disk by sharing a snapshot</a></td><td></td></tr>
<tr><td></td><td><a href="../GCP/gcp.persistence.create-service-account-key">Create a GCP Service Account Key</a></td><td></td><td><a href="../GCP/gcp.defense-evasion.delete-logging-sink">Delete a GCP Log Sink</a></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td><a href="../GCP/gcp.persistence.invite-external-user">Invite an External User to a GCP Project</a></td><td></td><td><a href="../GCP/gcp.defense-evasion.disable-logging-sink">Disable a GCP Log Sink</a></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td><a href="../GCP/gcp.persistence.create-service-account-key">Create a GCP Service Account Key</a></td><td></td><td><a href="../GCP/gcp.defense-evasion.remove-vpc-flow-logs">Disable VPC Flow Logs on a Subnet</a></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td><a href="../GCP/gcp.persistence.invite-external-user">Invite an External User to a GCP Project</a></td><td></td><td><a href="../GCP/gcp.defense-evasion.delete-logging-sink">Delete a GCP Log Sink</a></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td><a href="../GCP/gcp.defense-evasion.disable-logging-sink">Disable a GCP Log Sink</a></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td><a href="../GCP/gcp.defense-evasion.reduce-sink-log-retention">Reduce Log Retention Period on a Cloud Logging Sink Bucket</a></td><td></td><td></td><td></td><td></td><td></td></tr>
</tbody>
</table>
Expand Down
7 changes: 7 additions & 0 deletions docs/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,13 @@ GCP:
- Defense Evasion
platform: GCP
isIdempotent: true
- id: gcp.defense-evasion.remove-vpc-flow-logs
name: Disable VPC Flow Logs on a Subnet
isSlow: false
mitreAttackTactics:
- Defense Evasion
platform: GCP
isIdempotent: true
- id: gcp.defense-evasion.delete-logging-sink
name: Delete a GCP Log Sink
isSlow: false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package gcp

import (
"context"
_ "embed"
"fmt"
"log"

compute "cloud.google.com/go/compute/apiv1"
"cloud.google.com/go/compute/apiv1/computepb"
"github.com/datadog/stratus-red-team/v2/pkg/stratus"
"github.com/datadog/stratus-red-team/v2/pkg/stratus/mitreattack"
)

//go:embed main.tf
var tf []byte

func init() {
stratus.GetRegistry().RegisterAttackTechnique(&stratus.AttackTechnique{
ID: "gcp.defense-evasion.remove-vpc-flow-logs",
FriendlyName: "Disable VPC Flow Logs on a Subnet",
Description: `
Disables VPC flow logging on a subnet by patching its log configuration.
VPC flow logs record network traffic metadata for all VM instances in a subnet,
providing visibility for network monitoring and forensic investigation.

Warm-up:

- Create a VPC network
- Create a subnet with VPC flow logs enabled

Detonation:

- Disable VPC flow logs on the subnet by patching its <code>logConfig.enable</code> field to <code>false</code>

Revert:

- Re-enable VPC flow logs on the subnet

References:

- https://cloud.google.com/vpc/docs/using-flow-logs
- https://cloud.google.com/compute/docs/reference/rest/v1/subnetworks/patch
- https://github.com/GoogleCloudPlatform/security-analytics/blob/main/src/3.02/3.02.md
- https://securitylabs.datadoghq.com/cloud-security-atlas/attacks/removing-vpc-flow-logs/
`,
Detection: `
Identify when VPC flow logging is disabled on a subnet by monitoring for
<code>v1.compute.subnetworks.patch</code> events in GCP Admin Activity audit logs
where the request sets <code>logConfig.enable</code> to <code>false</code>.
`,
Platform: stratus.GCP,
IsIdempotent: true,
MitreAttackTactics: []mitreattack.Tactic{mitreattack.DefenseEvasion},
PrerequisitesTerraformCode: tf,
Detonate: detonate,
Revert: revert,
})
}

func setFlowLogsEnabled(providers stratus.CloudProviders, subnetName string, region string, enabled bool) error {
gcp := providers.GCP()
ctx := context.Background()
projectId := gcp.GetProjectId()

subnetsClient, err := compute.NewSubnetworksRESTClient(ctx, gcp.Options())
if err != nil {
return fmt.Errorf("failed to create subnetworks client: %w", err)
}
defer subnetsClient.Close()

subnet, err := subnetsClient.Get(ctx, &computepb.GetSubnetworkRequest{
Project: projectId,
Region: region,
Subnetwork: subnetName,
})
if err != nil {
return fmt.Errorf("failed to get subnet %s: %w", subnetName, err)
}

op, err := subnetsClient.Patch(ctx, &computepb.PatchSubnetworkRequest{
Project: projectId,
Region: region,
Subnetwork: subnetName,
SubnetworkResource: &computepb.Subnetwork{
Fingerprint: subnet.Fingerprint,
LogConfig: &computepb.SubnetworkLogConfig{
Enable: ptr(enabled),
},
},
})
if err != nil {
return fmt.Errorf("failed to patch subnet %s: %w", subnetName, err)
}

if err = op.Wait(ctx); err != nil {
return fmt.Errorf("failed waiting for subnet patch to complete: %w", err)
}

return nil
}

func detonate(params map[string]string, providers stratus.CloudProviders) error {
subnetName := params["subnet_name"]
region := params["region"]

log.Printf("Disabling VPC flow logs on subnet %s in region %s\n", subnetName, region)
if err := setFlowLogsEnabled(providers, subnetName, region, false); err != nil {
return err
}
log.Printf("Successfully disabled VPC flow logs on subnet %s\n", subnetName)
return nil
}

func revert(params map[string]string, providers stratus.CloudProviders) error {
subnetName := params["subnet_name"]
region := params["region"]

log.Printf("Re-enabling VPC flow logs on subnet %s in region %s\n", subnetName, region)
if err := setFlowLogsEnabled(providers, subnetName, region, true); err != nil {
return err
}
log.Printf("Successfully re-enabled VPC flow logs on subnet %s\n", subnetName)
return nil
}

func ptr[T any](v T) *T {
return &v
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.18.1"
}
random = {
source = "hashicorp/random"
version = "~> 3.3.2"
}
}
}

locals {
resource_prefix = "stratus-red-team-rvfl" # stratus red team remove vpc flow logs
}

resource "random_string" "suffix" {
length = 8
special = false
min_lower = 8
}

resource "google_compute_network" "vpc" {
name = "${local.resource_prefix}-vpc-${random_string.suffix.result}"
auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnet" {
name = "${local.resource_prefix}-subnet-${random_string.suffix.result}"
ip_cidr_range = "10.10.0.0/24"
region = "us-central1"
network = google_compute_network.vpc.id

log_config {
aggregation_interval = "INTERVAL_5_SEC"
flow_sampling = 0.5
metadata = "INCLUDE_ALL_METADATA"
}
}

output "subnet_name" {
value = google_compute_subnetwork.subnet.name
}

output "region" {
value = google_compute_subnetwork.subnet.region
}

output "display" {
value = format("Subnet %s in region %s with VPC flow logs enabled", google_compute_subnetwork.subnet.name, google_compute_subnetwork.subnet.region)
}
1 change: 1 addition & 0 deletions v2/internal/attacktechniques/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import (
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/defense-evasion/disable-logging-sink"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/defense-evasion/reduce-sink-log-retention"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/defense-evasion/remove-project-from-organization"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/defense-evasion/remove-vpc-flow-logs"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/discovery/enumerate-permissions"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/exfiltration/share-compute-disk"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/exfiltration/share-compute-image"
Expand Down
Loading