Skip to content
Open
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
2,620 changes: 2,620 additions & 0 deletions plugins/gcpaudit_rs/Cargo.lock

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions plugins/gcpaudit_rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "gcpaudit"
version = "0.3.0"
edition = "2021"
authors = ["The Falco Authors"]
license = "Apache-2.0"
description = "Read GCP Audit Logs"

[lib]
crate-type = ["cdylib"]

[dependencies]
# falco_plugin = { version = "0.8", features = ["source-plugin", "extract-plugin"] }
falco_event = "0.5.1"
falco_plugin = "0.5.1"
anyhow = "1"
serde = "1"
serde_json = { version = "1", features = ["preserve_order"] }
serde_spanned = "1"
schemars = "1"
google-cloud-pubsub = "0.30.0"
google-cloud-googleapis = "0.16.1"
tokio = { version = "1.49.0", features = ["rt-multi-thread"] }
tokio-util = "0.7"
async-trait = "0.1.89"

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true
54 changes: 54 additions & 0 deletions plugins/gcpaudit_rs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco 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
#
# 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.
#

.PHONY: all build clean release debug test

NAME := gcpaudit
OUTPUT := lib$(NAME).so

all: release

build: release

release:
@echo "Building release version..."
cargo build --release
@cp target/release/lib$(NAME).so $(OUTPUT) || cp target/release/lib$(NAME).dylib $(OUTPUT) 2>/dev/null || true

debug:
@echo "Building debug version..."
cargo build
@cp target/debug/lib$(NAME).so $(OUTPUT) || cp target/debug/lib$(NAME).dylib $(OUTPUT) 2>/dev/null || true

debug-universal:
@echo "Building debug version..."
cargo build
@cp target/debug/lib$(NAME).so $(OUTPUT) || cp target/debug/lib$(NAME).dylib $(OUTPUT) 2>/dev/null || true

clean:
cargo clean
rm -f $(OUTPUT)

test:
cargo test

check:
cargo clippy -- -D warnings
cargo fmt -- --check

fmt:
cargo fmt

readme:
@echo "Generate README with falco plugin tool if available"
198 changes: 198 additions & 0 deletions plugins/gcpaudit_rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# GCP audit logs Events Plugin, Rust version

This is a Rust version fo the GCP Audit Logs Plugin and is designed to ingest GCP audit logs for several GCP services, including Compute Engine, KMS, Cloud Armor WAF, IAM, Firewall, Cloud Storage, BigQuery, CloudSQL, Pub/Sub, Cloud Logging, and Cloud Functions.

The GCP Audit Logs Plugin's primary purpose is to detect security threats, vulnerabilities, and compliance risks by analyzing the ingested GCP audit logs. The default security detection rules were built with the MITRE & ATT&CK framework in mind, which provides a comprehensive and industry-standard way to identify and classify different types of security threats.

The GCP Audit Logs Plugin can help security teams identify and respond to security incidents quickly, improve compliance posture, and reduce overall risk to the organization. It provides a comprehensive and centralized view of security events across multiple GCP services and can help detect and prevent unauthorized access, data exfiltration, and other types of malicious activity.

By leveraging GCP audit logs, the GCP Audit Logs Plugin provides deep insights into the activities of different users, services, and resources in your GCP environment. The GCP Audit Logs Plugin's advanced ebpf capabilities enable it to identify anomalous activities and raise alerts when it detects suspicious or malicious behavior.

The GCP Audit Logs Plugin also offers customizable detection rules that enable you to fine-tune the detection capabilities to suit your organization's specific needs. You can customize the rules to detect specific types of security threats, monitor specific users or services, and track specific resources or data types.


For more details about what GCP Audit logs are, see the [GCP official documentation](https://cloud.google.com/logging/docs/audit/understanding-audit-logs).

### Functionality

The GCP Audit Logs Plugin comes with pre-built security detection rules designed to detect security threats based on the MITRE & ATT&CK framework. These rules are constantly updated to ensure that the security agent is always detecting the latest threats and vulnerabilities.

The default security detection rules cover the following areas:

* Identity and Access Management (IAM)
* Network Security
* Data Security
* Compliance
* Infrastructure Security
* Cloud Service Providers

The GCP Audit Logs Plugin's detection rules can identify threats such as:

* Privilege escalation
* Unauthorized access
* Data exfiltration
* Denial of Service (DoS) attacks
* Insider threats
* Suspicious network activity

- [GCP Audit Logs Plugin](#GCP Audit Logs Plugin)
- [Event Source](#event-source)
- [Supported Fields](#supported-fields)
- [Development](#development)
- [Requirements](#requirements)
- [Build](#build)
- [Settings](#settings)
- [Configurations](#configurations)
- [Usage](#usage)
- [Requirements](#requirements-1)
- [Results](#results)

# Event Source

The event source for `GCP Audit Logs Plugin` events is `GCP Audit Logs`.

This GCP Audit Logs Plugin is designed to ingest GCP audit logs from several GCP services, including:
* Compute Engine
* KMS
* Cloud Armor WAF
* IAM
* Firewall
* Cloud Storage
* BigQuery
* Cloud SQL
* Pub/Sub
* Cloud Logging
* Cloud Functions

The GCP Audit Logs Plugin subscribes to a Pub/Sub topic service and is backed by an optimized sink that exports the most important log entries.

```sql
log_name="projects/your-gcp-project-id/logs/cloudaudit.googleapis.com%2Factivity" AND
(protoPayload.serviceName="cloudsql.googleapis.com" OR
protoPayload.serviceName="logging.googleapis.com" OR
protoPayload.serviceName="iam.googleapis.com" OR
(protoPayload.serviceName="compute.googleapis.com" AND NOT protoPayload.authenticationInfo.principalEmail=~"^service-") OR
protoPayload.serviceName="pubsub.googleapis.com" OR
protoPayload.serviceName="cloudkms.googleapis.com" OR
protoPayload.serviceName="cloudfunctions.googleapis.com" OR
protoPayload.serviceName="storage.googleapis.com" OR
protoPayload.serviceName="cloudresourcemanager.googleapis.com" OR
protoPayload.serviceName="bigquery.googleapis.com")
```

You can change the log query to fit your specific needs.

For more details about what Cloud logging log queries, see the [GCP official documentation](https://cloud.google.com/logging/docs/view/logging-query-language).

# Supported Fields

<!-- README-PLUGIN-FIELDS -->
| NAME | TYPE | ARG | DESCRIPTION |
|-------------------------------|----------|------|------------------------------------------|
| `gcp.user` | `string` | None | GCP principal, actor of the action |
| `gcp.callerIP` | `string` | None | Actor's IP |
| `gcp.userAgent` | `string` | None | Actor's User Agent |
| `gcp.authorizationInfo` | `string` | None | GCP authorization (JSON) |
| `gcp.serviceName` | `string` | None | GCP API service name |
| `gcp.policyDelta` | `string` | None | GCP service resource access policy delta |
| `gcp.request` | `string` | None | GCP API raw request (JSON) |
| `gcp.methodName` | `string` | None | GCP API service method executed |
| `gcp.cloudfunctions.function` | `string` | None | GCF name |
| `gcp.cloudsql.databaseId` | `string` | None | GCP SQL database ID |
| `gcp.compute.instanceId` | `string` | None | GCE instance ID |
| `gcp.compute.networkId` | `string` | None | GCP network ID |
| `gcp.compute.subnetwork` | `string` | None | GCP subnetwork name |
| `gcp.compute.subnetworkId` | `string` | None | GCP subnetwork ID |
| `gcp.dns.zone` | `string` | None | GCP DNS zone |
| `gcp.iam.serviceAccount` | `string` | None | GCP service account |
| `gcp.iam.serviceAccountId` | `string` | None | GCP IAM unique ID |
| `gcp.location` | `string` | None | GCP region |
| `gcp.logging.sink` | `string` | None | GCP logging sink |
| `gcp.projectId` | `string` | None | GCP project ID |
| `gcp.resourceName` | `string` | None | GCP resource name |
| `gcp.resourceType` | `string` | None | GCP resource type |
| `gcp.resourceLabels` | `string` | None | GCP resource labels (JSON) |
| `gcp.storage.bucket` | `string` | None | GCP bucket name |
| `gcp.time` | `string` | None | Timestamp of the event in RFC3339 format |
<!-- /README-PLUGIN-FIELDS -->

# Development
## Requirements

You need:
* `Go` >= 1.17

## Build

```shell
make
```

# Settings

Only `init` accepts settings:
* `project_id`: the name of your GCP project
* `num_goroutines`: is the number of goroutines that each datastructure along the Receive path will spawn (default: 10)
* `maxout_stand_messages`: is the maximum number of unprocessed messages (default: 1000)
* `sub_id`: The subscriber name for your pub/sub topic

# Configurations

* `falco.yaml`

```yaml
plugins:
- name: json
library_path: libjson.so

- name: gcpaudit
library_path: libgcpaudit.so
open_params: "your-subscription-ID"
init_config:
project_id: "your-gcp-project-ID"
load_plugins: [gcpaudit, json]
```

* `rules.yaml`

The `source` for rules must be `gcp_auditlog`.

See example:
```yaml
- rule: GCP Bucket configured to be public
desc: Detect when access on a GCP Bucket granted to the public internet.
condition: is_gcs_service and gcp.methodName="storage.setIamPermissions" and is_binded_delta_to_public
output: >
project=%gcp.projectId
A GCP bucket access granted to be public by user=%gcp.user userIP=%gcp.callerIP userAgent=%gcp.userAgent bindedDelta=%gcp.policyDelta
authorizationInfo=%gcp.authorizationInfo
rawRequest=%gcp.request
bucketName=%gcp.storage.bucket
priority: CRITICAL
source: auditlogs
tags: [GCP, buckets, compliance]
```

# Usage

```shell
falco -c falco.yaml -r auditlogs_rules.yaml
```

## Requirements

* `Falco` >= 0.35

## Results

```shell
{"hostname":"sherlock","output":"01:43:54.476694000: Notice project=********** A GCP WAF network policy or waf rule modified by user=ahmed.amin@test.com userIP=41.45.115.69 userAgent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe) authorizationInfo=[{\"granted\":true,\"permission\":\"compute.securityPolicies.update\",\"resourceAttributes\":{\"name\":\"projects/=**********/global/securityPolicies/**********\",\"service\":\"compute\",\"type\":\"compute.securityPolicies\"}}] rawRequest={\"@type\":\"type.googleapis.com/compute.securityPolicies.addRule\",\"action\":\"deny(403)\",\"description\":\"\",\"match\":{\"config\":{\"srcIpRanges\":[\"1.1.1.1\"]},\"versionedExpr\":\"SRC_IPS_V1\"},\"preview\":false,\"priority\":\"0\"} policyName=**********","priority":"Notice","rule":"GCP WAF rule modified or deleted","source":"gcp_auditlog","tags":["CloudArmor","GCP","T1562-impair-defenses","TA0005-defense-evasion","WAF"],"time":"2023-07-06T22:43:54.476694000Z", "output_fields": {"evt.time":1688683434476694000,"gcp.authorizationInfo":"[{\"granted\":true,\"permission\":\"compute.securityPolicies.update\",\"resourceAttributes\":{\"name\":\"projects/=**********/global/securityPolicies/**********\",\"service\":\"compute\",\"type\":\"compute.securityPolicies\"}}]","gcp.callerIP":"41.45.115.69","gcp.request":"{\"@type\":\"type.googleapis.com/compute.securityPolicies.addRule\",\"action\":\"deny(403)\",\"description\":\"\",\"match\":{\"config\":{\"srcIpRanges\":[\"1.1.1.1\"]},\"versionedExpr\":\"SRC_IPS_V1\"},\"preview\":false,\"priority\":\"0\"}","gcp.user":"ahmed.amin@test.com","gcp.userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe)","json.value[/resource/labels/policy_name]":"**********","gcp.projectId":"****"}}

{"hostname":"sherlock","output":"03:36:21.780289000: Critical project=********** A GCP bucket access granted to be public by user=ahmed.amin@test.com userIP=156.204.230.94 userAgent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe) bindedDelta=[{\"action\":\"ADD\",\"member\":\"allUsers\",\"role\":\"roles/storage.objectViewer\"}] authorizationInfo=[{\"granted\":true,\"permission\":\"storage.buckets.setIamPolicy\",\"resource\":\"projects/_/buckets/amin-test\",\"resourceAttributes\":{}}] bucketName=ahmed-test","priority":"Critical","rule":"GCP Bucket configured to be public","source":"gcp_auditlog","tags":["GCP","buckets","compliance"],"time":"2023-06-30T00:36:21.780289000Z", "output_fields": {"evt.time":1688085381780289000,"gcp.authorizationInfo":"[{\"granted\":true,\"permission\":\"storage.buckets.setIamPolicy\",\"resource\":\"projects/_/buckets/ahmed-test\",\"resourceAttributes\":{}}]","gcp.callerIP":"156.204.230.94","gcp.policyDelta":"[{\"action\":\"ADD\",\"member\":\"allUsers\",\"role\":\"roles/storage.objectViewer\"}]","gcp.user":"ahmed.amin@test.com","gcp.userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe)","gcp.storage.bucket":"ahmed-test","gcp.projectId":"**********"}}

{"hostname":"sherlock","output":"01:36:49.223570000: Notice project=-***-**-*** A GCP WAF network policy or waf rule modified by user=ahmed.amin@test.com userIP=x.x.x.x userAgent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe) authorizationInfo=[{\"granted\":true,\"permission\":\"compute.securityPolicies.update\",\"resourceAttributes\":{\"name\":\"projects/-***-**-***/global/securityPolicies/xxx-xxxx-xxxx\",\"service\":\"compute\",\"type\":\"compute.securityPolicies\"}}] policyName=xxx-xxxx-xxxx","priority":"Notice","rule":"GCP WAF rule modified or deleted","source":"auditlogs","tags":["CloudArmor","GCP","T1562-impair-defenses","TA0005-defense-evasion","WAF"],"time":"2023-04-22T23:36:49.223570000Z", "output_fields": {"gcp.authorizationInfo ":"[{\"granted\":true,\"permission\":\"compute.securityPolicies.update\",\"resourceAttributes\":{\"name\":\"projects/-***-**-***/global/securityPolicies/xxx-xxxx-xxxx\",\"service\":\"compute\",\"type\":\"compute.securityPolicies\"}}]","gcp.user":"ahmed.amin@test.com","al.principal.ip":"x.x.x.x","gcp.userAgent ":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36,gzip(gfe),gzip(gfe)","evt.time":1682206609223570000,"json.value[/resource/labels/policy_name]":"xxx-xxxx-xxxx","gcp.projectId":"-***-**-***"}}

{"hostname":"sherlock-ThinkBook-15-G2-ITL","output":"02:48:23.599777000: Notice project=xxx-xxxx-xxxx A GCP serviceAccount delete by user=ahmed.amin@test.com userIP=156.204.230.94 userAgent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe) authorizationInfo=[{\"granted\":true,\"permission\":\"iam.serviceAccounts.delete\",\"resource\":\"projects/-/serviceAccounts/101363364166838521279\",\"resourceAttributes\":{\"name\":\"projects/-/serviceAccounts/101363364166838521279\"}}]","priority":"Notice","rule":"GCP IAM serviceAccount deleted","source":"gcp_auditlog","tags":["GCP","IAM","abuse-elevation-control-mechanism"],"time":"2023-06-29T23:48:23.599777000Z", "output_fields": {"evt.time":1688082503599777000,"gcp.authorizationInfo":"[{\"granted\":true,\"permission\":\"iam.serviceAccounts.delete\",\"resource\":\"projects/-/serviceAccounts/101363364166838521279\",\"resourceAttributes\":{\"name\":\"projects/-/serviceAccounts/101363364166838521279\"}}]","gcp.callerIP":"156.204.230.94","gcp.user":"ahmed.amin@test.com","gcp.userAgent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36,gzip(gfe)","gcp.projectId":"xxx-xxxx-xxxx"}}


```
Loading
Loading