Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GCP Improvements Quicky #314

Merged
merged 12 commits into from
Feb 16, 2025
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ eeauditor/processor/outputs/*.html
LOCAL_external_providers.toml
output.json
output_ocsf_v1-4-0_events.json
gcp_cred.json
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
#specific language governing permissions and limitations
#under the License.

# latest hash as of 27 AUG 2024 - Alpine 3.20.2
# https://hub.docker.com/layers/library/alpine/3.20.2/images/sha256-eddacbc7e24bf8799a4ed3cdcfa50d4b88a323695ad80f317b6629883b2c2a78?context=explore
# latest hash as of 13 FEB 2025 - Alpine 3.21.3
# https://hub.docker.com/layers/library/alpine/3.20.2/images/sha256-a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c?context=explore
# use as builder image to pull in required deps
FROM alpine@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099 AS builder
FROM alpine@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c AS builder

ENV PYTHONUNBUFFERED=1

Expand All @@ -40,9 +40,9 @@ RUN \
rm -rf /tmp/* && \
rm -f /var/cache/apk/*

# latest hash as of 27 AUG 2024 - Alpine 3.20.2
# https://hub.docker.com/layers/library/alpine/3.20.2/images/sha256-eddacbc7e24bf8799a4ed3cdcfa50d4b88a323695ad80f317b6629883b2c2a78?context=explore
FROM alpine@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099 as electriceye
# latest hash as of 13 FEB 2025 - Alpine 3.21.3
# https://hub.docker.com/layers/library/alpine/3.20.2/images/sha256-a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c?context=explore
FROM alpine@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c as electriceye

COPY --from=builder /usr /usr

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ In total there are:

- **4** Supported Public CSPs: `AWS`, `GCP`, `OCI`, and `Azure`
- **4** Supported SaaS Providers: `ServiceNow`, `M365`, `Salesforce`, and `Snowflake`
- **1193** ElectricEye Checks
- **177** Supported CSP & SaaS Asset Components across all Services
- **133** ElectricEye Auditors
- **1196** ElectricEye Checks
- **179** Supported CSP & SaaS Asset Components across all Services
- **135** ElectricEye Auditors

The tables of supported Services and Checks have been migrated to the respective per-Provider setup documentation linked above in [Configuring ElectricEye](#configuring-electriceye).

Expand Down Expand Up @@ -389,6 +389,8 @@ The controls frameworks that ElectricEye supports is always being updated as new
- CIS Amazon Web Services Foundations Benchmark V2.0
- CIS Amazon Web Services Foundations Benchmark V3.0
- CIS Microsoft Azure Foundations Benchmark V2.0.0
- CIS Snowflake Foundations Benchmark V1.0.0
- CIS Google Cloud Platform Foundation Benchmark V2.0

## Repository Security

Expand Down
24 changes: 15 additions & 9 deletions docs/setup/Setup_GCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To configure the TOML file, you need to modify the values of the variables in th

- `gcp_project_ids`: Set this variable to specify a list of GCP Project IDs, ensure you only specify the GCP Projects which the Service Account specified in `gcp_service_account_json_payload_value` has access to.

- `gcp_service_account_json_payload_value`: This variable is used to specify the contents of the Google Cloud Platform (GCP) service account key JSON file that ElectricEye should use to authenticate to GCP. The contents of the JSON file should be provided as a string, and the entire string should be assigned to the `gcp_service_account_json_payload_value` setting.
- `gcp_service_account_json_payload_value`: This variable is used to specify the contents of the Google Cloud Platform (GCP) service account key JSON file that ElectricEye should use to authenticate to GCP. If `credentials_location` is set to `CONFIG_FILE` you should paste the entire contents of the Service Account JSON within triple single-quotes (`'''`) otherwise the newline characters (`\n`) will cause an issue within the TOML.

It's important to note that this setting is a sensitive credential, and as such, its value should be stored in a secure manner that matches the location specified in the `[global]` section's `credentials_location` setting. For example, if `credentials_location` is set to `"AWS_SSM"`, then the gcp_service_account_json_payload_value should be the name of an AWS Systems Manager Parameter Store SecureString parameter that contains the contents of the GCP service account key JSON file.

Expand All @@ -32,16 +32,19 @@ Refer [here](#gcp-multi-project-service-account-support) for information on addi

1. Enable the following APIs for all GCP Projects you wish to assess with ElectricEye.

> - Compute Engine API
> - Cloud SQL Admin API
> - Cloud Logging API
> - OS Config API
> - Service Networking API
- Compute Engine API
- Cloud SQL Admin API
- Cloud Logging API
- OS Config API
- Service Networking API
- BigQuery API

2. Create a **Service Account** with the following permissions per Project you want to assess with ElectricEye (**Note**: In the future, Organizations will be supported for GCP, you can instead create a single **Service Account** and add it's Email into all of your other Projects)

> - Security Reviewer
> - Project Viewer
- Security Reviewer
- Viewer
- BigQuery Data Viewer
- BigQuery Metadata Viewer

#### NOTE: For evaluating multiple GCP Projects, you only need ONE Service Account, refer to [GCP Multi-Project Service Account Support](#gcp-multi-project-service-account-support) for more information on adding permissions to other Projects.

Expand Down Expand Up @@ -150,10 +153,13 @@ done

## GCP Checks & Services

These are the following services and checks perform by each Auditor, there are currently **53 Checks** across **3 Auditors** that support the secure configuration of **2 services/components**
These are the following services and checks perform by each Auditor, there are currently **56 Checks** across **5 Auditors** that support the secure configuration of **4 services/components**

| Auditor File Name | Scanned Resource Name | Auditor Scan Description |
|---|---|---|
| GCP_BigQuery_Auditor | BigQuery table | Has the table been updated in the last 90 days |
| GCP_BigQuery_Auditor | BigQuery table | Do tables use CMEKs for encryption |
| GCP_IAM_Auditor | Service Account | Are user-managed keys in use (lol, yes, at least one!) |
| GCP_ComputeEngine_Auditor | GCE VM Instance | Is deletion protection enabled |
| GCP_ComputeEngine_Auditor | GCE VM Instance | Is IP forwarding disabled |
| GCP_ComputeEngine_Auditor | GCE VM Instance | Is auto-restart enabled |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# Instantiate a NMAP scanner for TCP scans to define ports
nmap = nmap3.NmapScanTechniques()

def get_compute_engine_instances(cache: dict, gcpProjectId: str):
def get_compute_engine_instances(cache: dict, gcpProjectId: str, gcpCredentials):
'''
AggregatedList result provides Zone information as well as every single Instance in a Project
'''
Expand All @@ -39,7 +39,7 @@ def get_compute_engine_instances(cache: dict, gcpProjectId: str):

results = []

compute = googleapiclient.discovery.build('compute', 'v1')
compute = googleapiclient.discovery.build('compute', 'v1', credentials=gcpCredentials)

aggResult = compute.instances().aggregatedList(project=gcpProjectId).execute()

Expand Down Expand Up @@ -79,11 +79,11 @@ def scan_host(hostIp, assetName, assetComponent):
results = None

@registry.register_check("gce")
def gce_attack_surface_open_tcp_port_check(cache: dict, awsAccountId: str, awsRegion: str, awsPartition: str, gcpProjectId: str):
def gce_attack_surface_open_tcp_port_check(cache: dict, awsAccountId: str, awsRegion: str, awsPartition: str, gcpProjectId: str, gcpCredentials):
"""[AttackSurface.GCP.GCE.{checkIdNumber}] Google Compute Engine VM instances should not be publicly reachable on {serviceName}"""
iso8601Time = datetime.datetime.now(datetime.timezone.utc).isoformat()

for gce in get_compute_engine_instances(cache, gcpProjectId):
for gce in get_compute_engine_instances(cache, gcpProjectId, gcpCredentials):
# B64 encode all of the details for the Asset
assetJson = json.dumps(gce,default=str).encode("utf-8")
assetB64 = base64.b64encode(assetJson)
Expand Down
Loading
Loading