{"id":19528827,"url":"https://github.com/netspi/gcpwn","last_synced_at":"2026-05-02T07:05:32.448Z","repository":{"id":243947568,"uuid":"813705902","full_name":"NetSPI/gcpwn","owner":"NetSPI","description":"Enumeration/exploit/analysis/download/etc pentesting framework for GCP; modeled like Pacu for AWS; a product of numerous hours via @WebbinRoot","archived":false,"fork":false,"pushed_at":"2025-03-20T05:31:44.000Z","size":424,"stargazers_count":241,"open_issues_count":0,"forks_count":22,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-13T00:45:37.466Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NetSPI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-11T15:26:41.000Z","updated_at":"2025-04-12T21:41:25.000Z","dependencies_parsed_at":"2024-07-07T03:48:52.373Z","dependency_job_id":"2d15be4d-c4b7-493c-aef8-07ff0cbd8be4","html_url":"https://github.com/NetSPI/gcpwn","commit_stats":null,"previous_names":["netspi/gcpwn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NetSPI%2Fgcpwn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NetSPI%2Fgcpwn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NetSPI%2Fgcpwn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NetSPI%2Fgcpwn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NetSPI","download_url":"https://codeload.github.com/NetSPI/gcpwn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650420,"owners_count":21139672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T01:20:10.899Z","updated_at":"2026-05-02T07:05:32.441Z","avatar_url":"https://github.com/NetSPI.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![GCPwnLogo](https://github.com/user-attachments/assets/1ad93c63-37f2-42fd-95e9-ec05966cb6b2)\n\n[![PyPI](https://img.shields.io/pypi/v/gcpwn)](https://pypi.org/project/gcpwn/)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/)\n[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](./LICENSE)\n[![Stars](https://img.shields.io/github/stars/NetSPI/gcpwn.svg)](https://github.com/NetSPI/gcpwn/stargazers)\n[![Forks](https://img.shields.io/github/forks/NetSPI/gcpwn.svg)](https://github.com/NetSPI/gcpwn/network)\n[![Issues](https://img.shields.io/github/issues/NetSPI/gcpwn.svg)](https://github.com/NetSPI/gcpwn/issues)\n\n# GCPwn\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Documentation](#documentation)\n- [Installation TLDR](#installation-tldr)\n- [First-Run TLDR](#first-run-tldr)\n- [Unauthenticated Run TLDR](#unauthenticated-run-tldr)\n- [OpenGraph TLDR](#opengraph-tldr)\n- [Module/Data Output TLDR](#moduledata-output-tldr)\n- [Scripts Folder TLDR](#scripts-folder-tldr)\n- [Dependency Inventory](#dependency-inventory)\n- [Repository Layout](#repository-layout)\n- [Who Is This For?](#who-is-this-for)\n- [Author, Contributors, and License](#author-contributors-and-license)\n- [Resources](#resources)\n- [Credits](#credits)\n\n## Overview\n\n\u003e In the spirit of transparency: parts of this project and documentation were developed with LLM coding assistance. Review code and behavior in your environment before operational use. Ideally the dependency summary at the end of the README and explanations throughout should be enough to meet and verify your operational needs.\n\nGCPwn (gee-see-pwn) is a Google Cloud offensive security assessment framework built for workspace-driven credential handling, service enumeration, artifact collection, and graph-based attack-path analysis.\n\nIt is designed as a one-stop shop for three primary workflows:\n\n- **Reconnaissance and Enumeration:** Use success/fail API behavior trackedin the background, explicit `testIamPermissions` calls, and IAM binding analysis to understand effective permissions from clear-box (probably a config audit) to opaque scenarios (finding creds during a pentest). Export data in JSON/CSV/Excel formats, download artifacts as they are found (for example, Artifact Registry Python packages), and run broad discovery with `enum_all` and download data throughout with the `--download` flag.\n- **Exploitation:** Execute pre-packaged exploit workflows for blue-team validation and professional penetration-testing exercises.\n- **Graphing and OpenGraph:** Convert collected data into OpenGraph output for BloodHound-style analysis (see below). By default, graphing focuses on selected privilege-escalation edges and can be expanded with more verbose output, inheritance evaluation, and multi-permission edge logic.\n\n\u003cp\u003e\u003cstrong\u003e\u003cspan style=\"color:red\"\u003eDisclaimer:\u003c/span\u003e\u003c/strong\u003e \u003cspan style=\"color:red\"\u003eUse this tool only in systems, projects, and environments you own or are explicitly authorized to assess. Unauthorized use may violate law, policy, or terms of service.\u003c/span\u003e\u003c/p\u003e\n\n\n## Documentation\n\nDocumentation is maintained in the GitHub Wiki:\n\n- https://github.com/NetSPI/gcpwn/wiki\n\nAdditional project docs:\n\n- Contributing: `CONTRIBUTING.md`\n- Roadmap: `ROADMAP.md`\n- License: `LICENSE`\n\n## Installation TLDR\n\nThe installation strategy is to keep non-google dependencies minimal hopefully making it easier for you to get the tool approved if needed. `xlsxwriter` and `prettytable` are optional and can be installed only if you want those extra features, as shown below.\n\n### Option 1: Local Git Clone Install\n\n```bash\ngit clone https://github.com/NetSPI/gcpwn.git\ncd gcpwn\n\npython3 -m venv .venv\nsource .venv/bin/activate\npip install --upgrade pip\n```\n\nBase install (no optional table/excel dependencies):\n\n```bash\npip install -r requirements.txt\n```\n\nInstall optional table output support:\n\n```bash\npip install prettytable==3.17.0\n```\n\nInstall optional Excel export support:\n\n```bash\npip install xlsxwriter==3.2.9\n```\n\nRun the tool:\n\n```bash\npython -m gcpwn\n```\n\n### Option 2: Pip Install (PyPI)\n\n```bash\npip3 install gcpwn\n```\n\nIf you want optional table rendering (table std output option in configs) and/or Excel export support (`data export excel` option):\n\n```bash\npip3 install \"gcpwn[table]\"\npip3 install \"gcpwn[excel]\"\n# both extras\npip3 install \"gcpwn[table,excel]\"\n```\n\nRun the tool:\n\n```bash\ngcpwn\n```\n\nIf your shell cannot find `gcpwn`, run:\n\n```bash\npython -m gcpwn\n```\n\n### Option 3: Release Download\n\nDownload a release binary from GitHub Releases:\n\n- https://github.com/NetSPI/gcpwn/releases\n\nUse the binary asset that aligns with your operating system and CPU architecture (for example, Linux/macOS/Windows and `amd64` vs `arm64`).\n\nExample (Linux/macOS):\n\n```bash\nchmod +x ./gcpwn\n./gcpwn\n```\n\n### Option 4: Docker\n\n```bash\ndocker build -t gcpwn .\ndocker run --rm -it gcpwn\n```\n\nBuild with optional extras (if you want table rendering and/or Excel export available in the container):\n\n```bash\n# prettytable extra\ndocker build --build-arg GCPWN_EXTRAS=table -t gcpwn .\n\n# xlsxwriter extra\ndocker build --build-arg GCPWN_EXTRAS=excel -t gcpwn .\n\n# both extras\ndocker build --build-arg GCPWN_EXTRAS=table,excel -t gcpwn .\n```\n\nIf you want local persistence for DB/output between runs, mount volumes:\n\n```bash\ndocker run --rm -it \\\n  -v \"$(pwd)/databases:/opt/gcpwn/databases\" \\\n  -v \"$(pwd)/gcpwn_output:/opt/gcpwn/gcpwn_output\" \\\n  gcpwn\n```\n\n## First-Run TLDR\n\n1. Create/select a workspace by starting the program using one of the commands in the Installation section above.\n2. Load credentials (user/service/OAuth token). If you are using `gcloud`, you may need to run `gcloud config set project \u003cPROJECT_ID\u003e` when loading ADC-style credentials.\n3. Start with broad enumeration, ideally with **ONE of the options below**:\n\n```bash\n# Minimal first pass: enumerate discovered resources only (no testIamPermissions or download calls).\nmodules run enum_all\n\n# Common first pass: run testIamPermissions checks on supported resources.\n# Also runs a condensed list of permissions for org/folder/project resources.\nmodules run enum_all --iam\n\n# Common first pass + downloads: run testIamPermissions and attempt content downloads where supported.\nmodules run enum_all --iam --download\n\n# In-depth pass: --all-permissions includes large org/folder/project permission sets (10,000+ perms, executed in batches). Can take some time.\n# See: gcpwn/modules/resourcemanager/utilities/data/all_*_permissions.txt for the full list or to customize it.\nmodules run enum_all --iam --all-permissions\n\n# In-depth pass + downloads: enable artifact/content downloads where supported.\n# Use `modules run enum_all -h` for token options.\n# Example token: cloudrun_revision_env\nmodules run enum_all --iam --all-permissions --download\n```\n\n4. Review what was collected:\n\n```bash\n# Downloaded artifacts are written under gcpwn_output/ by default.\n\n# Export collected data.\n# CSV/JSON work in base install; Excel requires the optional Excel dependency from the installation section.\ndata export csv\ndata export json\ndata export excel\n\n# Review current credential permissions discovered via testIamPermissions.\n# Use --csv to export full row-level permission data (to avoid truncation in terminal output).\ncreds info\ncreds info --csv\n\n# Process enumerated IAM bindings and build IAM summaries.\nmodules run process_iam_bindings\n\n# Build BloodHound-compatible graph JSON.\n# Import output.json into BloodHound CE:\n# https://bloodhound.specterops.io/get-started/quickstart/community-edition-quickstart\nmodules run enum_gcp_cloud_hound_data --expand-inheritance --reset --out output.json\n```\n\n## Unauthenticated Run TLDR\n\nSometimes you may want to run unauthenticated or quick modules without starting a full interactive session. You can run unauthenticated modules directly without entering the interactive workspace shell. This implicitly creates a workspace called `PASSTHROUGH`.\n\nExamples:\n\n```bash\n# Run via installed console script\ngcpwn --module unauth_apikey_enum_all_scopes --api-key AIza...\n\n# Same flow via python module entrypoint\npython -m gcpwn --module unauth_apikey_gemini_exploit --api-key AIza...\n```\n\n## OpenGraph TLDR\n\nBy default, the OpenGraph module only graphs edges and related resource edges tied to privilege escalation paths. The default OpenGraph escalation-rule allowlist lives in `gcpwn/mappings/og_privilege_escalation_paths.json`. Review the wiki for explanations of the available flags, but the best option is usually the following:\n```bash\nmodules run enum_gcp_cloud_hound_data --expand-inheritance --reset --out Bloodhound_Output.json\n```\n\n### Graphing Strategy\n\nYou might notice edges go to `role@location` instead of going directly to the project. This preserves authorization fidelity in the graph. If User A has `compute.admin` on Project A and User B has `storage.admin` on Project A, drawing both users directly to Project A and then Project A to all resources would incorrectly imply both users can reach the same resources when User A can only get to compute and User B can only get to storage. The correct model is to route each user through their specific role binding node at that location, and only then fan out to resources that role can actually affect.\n\nIncorrect method (over-broad reach):\n\n```text\nUser A --\u003e Project A --\u003e Compute \u0026 Storage\nUser B --\u003e Project A --\u003e Compute \u0026 Storage\n```\n\nCorrect method (binding-scoped reach):\n\n```text\nUser A --\u003e compute_admin@project:A --\u003e Compute Resources in Project A\nUser B --\u003e storage_admin@project:A --\u003e Storage Resources in Project A\n```\n\n![OpenGraph example graph](images/Opengraph_Example.png)\n\nGenerate OpenGraph JSON:\n\n```bash\nmodules run enum_gcp_cloud_hound_data --out opengraph_output.json --reset [--include-all] [--expand-inherited] [--cond-eval]\n\n# Example\n(\u003cstaging-project-2\u003e:ABC)\u003e modules run enum_gcp_cloud_hound_data --expand-inherited --reset --out my_output.json\n[*] Step 1: users_groups (Users/Groups graph)\n[*] Completed users_groups: +92 nodes, +0 edges\n[*] Step 2: iam_bindings (IAM bindings graph)\n[*] Completed iam_bindings: +109 nodes, +201 edges\n[*] Step 3: inferred_permissions (Inferred permissions graph)\n[*] Completed inferred_permissions: +2 nodes, +2 edges\n[*] Step 4: resource_expansion (Resource expansion graph)\n[*] Completed resource_expansion: +63 nodes, +62 edges\n[*] Pruned isolated service-account IAM-binding islands (pairs=17, key_islands=5, nodes=50, edges=28).\n[*] Pruned orphan implied-IAM-binding nodes (implied_bindings=2, nodes=2, edges=2).\n[*] Pruned isolated service-account nodes (service_accounts=43, nodes=43, edges=0).\n[*] OpenGraph generation complete. Nodes: 171 | Edges: 235\n[*] Saved graph JSON to my_output.json\n\n\n# Pass the output JSON into your local installation of BloodHound\n\u003e head TEST.json -n 20\n{\n  \"metadata\": {\n    \"source_kind\": \"GCPBase\"\n  },\n  \"graph\": {\n    \"nodes\": [\n      {\n        \"id\": \"allUsers\",\n        \"kinds\": [\n          \"GCPAllUsers\",\n          \"GCPPrincipal\"\n        ],\n        \"properties\": {\n          \"display_name\": \"allUsers\",\n          \"source\": \"iam_members\"\n        }\n      },\n      {\n        \"id\": \"combo_iambinding:RESET_COMPUTE_STARTUP_SA@project:\u003cProject_ID\u003e#06e0003fe1\",\n        \"kinds\": [\n      [TRUNCATED]\n\n```\n\nOptional flags:\n\n- `--include-all`: include broader relationship output that might not be a direct privilege-escalation path (for example, a binding that exists but is not a direct avenue to escalate privileges).\n- `--expand-inherited`: expand inherited IAM scope relationships.\n- `--cond-eval`: currently preserves conditional workflow plumbing (placeholder behavior).\n- `--reset`: clear prior OpenGraph DB state before generation.\n\nThen import the JSON into [BloodHound CE](https://bloodhound.specterops.io/get-started/quickstart/community-edition-quickstart).\n\n### Adding Your Own Edges TLDR\n\nIf you want to add your own privilege-escalation edge (or any edge) to be called out by default, edit `og_privilege_escalation_paths.json` and add your rule. You need to know which permissions you want to flag. We cover adding a single-permission edge below, and the wiki covers multi-permission edge rules.\n\n#### Add a Single-Permission Edge\n\nLet's assume we want to call out `cloudkms.cryptoKeys.update` and add it to our default single-permission rules.\n\n1. Add to the permission --\u003e role dictionary\n   - If your target permission (i.e. `cloudkms.cryptoKeys.update`) is not already included, add the permission on a newline to `scripts/build_predfined_perm_to_role_input.txt`\n   - With your own GCP creds (for example, a free GCP account) in your own private GCP environment, run `./build_predefined_perm_to_roles.sh build_predfined_perm_to_role_input.txt \u003e perm_to_role_mappings.json` as an authenticated user. This bash script gets all permissions for all predefined roles in a GCP environment to show which roles map to your target permission. You can also add the mapping manually to `gcpwn/data/core/mappings/og_permission_to_roles_map.json` using https://docs.cloud.google.com/iam/docs/roles-permissions\n   - You should see the permission --\u003e role(s) mapping in `perm_to_role_mappings.json`. Replace `gcpwn/data/core/mappings/og_permission_to_roles_map.json` with content of `perm_to_role_mappings.json`\n2. Add a rule definition to `og_privilege_escalation_paths.json` (Note multi-permission rules are covered in the wiki). In our case, it might look like the entry below. Note `resource_scopes_possible` is where one might see a binding with those permissions, and `resource_types` are the actual resource nodes you will be drawing edges to. For example, you might see `cloudkms.cryptoKeys.update` attached to a project IAM binding or attached directly to a key IAM binding, but the final node in either case will be a key node and NOT a project per the reasoning stated above. If `cloudkms.cryptoKeys.update` is attached to a project IAm binding, gcpwn will fan out edges to key nodes discovered in that project rather than end at a project node.\n\n```json\n\"single_permission_rules\": {\n  \"CAN_DISABLE_KMS_KEY\": {\n    \"permission\": \"cloudkms.cryptoKeys.update\",\n    \"description\": \"Can update KMS crypto key settings including disabling or changing key behavior.\",\n    \"resource_scopes_possible\": [\"project\", \"kmscryptokey\"],\n    \"target_selector\": {\n      \"mode\": \"resource_types\",\n      \"resource_types\": [\"kmscryptokey\"]\n    }\n  }\n}\n```\n\n3. A final OpenGraph edge might then look like the following when ingested in BloodHound\n\n```text\nuser:alice@example.com\n  -[HAS_IAM_BINDING]-\u003e\niambinding:roles/cloudkms.admin@project:my-project\n  -[CAN_DISABLE_KMS_KEY]-\u003e\nresource:projects/my-project/locations/us-central1/keyRings/prod/cryptoKeys/app-key\n```\n\n### OpenGraph Cypher TLDR\n\nThese examples assume your OpenGraph JSON has already been imported into Neo4j/BloodHound-compatible tooling. Remove/alter `LIMIT` line as needed.\n\n1. See all nodes and edges\n\n```cypher\nMATCH (n)-[r]-\u003e(m)\nRETURN n, r, m\nLIMIT 1000\n```\n\n2. See all nodes and edges minus service-agent-associated data\n\n```cypher\nMATCH (n)-[r]-\u003e(m)\nWHERE coalesce(n.is_service_agent, false) = false\n  AND coalesce(m.is_service_agent, false) = false\n  AND coalesce(n.service_agent_role, false) = false\n  AND coalesce(m.service_agent_role, false) = false\nRETURN n, r, m\nLIMIT 1000\n```\n\n3. See all nodes and edges where IAM edges are inferred only\n\n```cypher\nMATCH (p)-[:HAS_IMPLIED_PERMISSIONS]-\u003e(g)-[r]-\u003e(t)\nWHERE type(r) STARTS WITH \"INFERRED_\"\nRETURN p, g, r, t\nLIMIT 1000\n```\n\n4. See all nodes and edges where IAM edges are binding-based only\n\n```cypher\nMATCH (p)-[seed:HAS_IAM_BINDING|HAS_COMBO_BINDING]-\u003e(g)\nOPTIONAL MATCH (g)-[r]-\u003e(t)\nWHERE r IS NULL OR NOT type(r) STARTS WITH \"INFERRED_\"\nRETURN p, seed, g, r, t\nLIMIT 1000\n```\n\n5. Find paths to `roles/owner` or any custom role (replace `ABC_Name`)\n\n```cypher\nMATCH p=(principal)-[:HAS_IAM_BINDING]-\u003e(binding:GCPIamSimpleBinding)\nWHERE binding.role_name IN [\"roles/owner\", \"ABC_Name\"]\nOPTIONAL MATCH (binding)-[r]-\u003e(target)\nRETURN principal, binding, r, target, p\nLIMIT 1000\n```\n\n6. Identify paths where a service account leads to another service account\n\n```cypher\nMATCH p=(sa1:GCPServiceAccount)-[*1..6]-\u003e(sa2)\nWHERE (sa2:GCPServiceAccount OR sa2:GCPServiceAccountResource)\n  AND sa1 \u003c\u003e sa2\nRETURN p\nLIMIT 500\n```\n\n## Module/Data Output TLDR\n\n### Module output format\n\nDefault output is `text`. You can switch workspace output format with:\n\n```text\nconfigs list\nconfigs set std_output_format text\nconfigs set std_output_format table\n```\n\n`table` mode requires the optional dependency `prettytable` covered in the installation section above.\n\n### Data output and exports\n\n```text\n# Export all collected service data to one CSV blob\ndata export csv\n\n# Export all collected service data to one JSON blob\ndata export json\n\n# Export all collected service data to one Excel workbook\ndata export excel\n\n# Export all collected service data to a specific Excel file path\ndata export excel --out-file ./gcpwn_export.xlsx\n\n# Export hierarchy image (SVG)\ndata export treeimage\n\n# Run direct SQL against SQLite (service DB by default)\ndata sql --db service \"SELECT * FROM iam_allow_policies LIMIT 25\"\n\n# Wipe service DB rows for current workspace (destructive)\ndata wipe-service --yes\n```\n\n## Scripts Folder TLDR\n\nScripts under `scripts/` are included in this GitHub repository to support setup, customization, and development workflows.\n\nThey are not required for normal tool usage and are not part of the standard runtime path for the installed package.\n\nUse them when you want to modify behavior, regenerate mapping data, or follow advanced project workflows.\n\nFor context, review the wiki and the OpenGraph instructions for adding an edge in this README.\n\n## Dependency Inventory\n\nDirect runtime dependencies are sourced from `requirements.txt` (and loaded via `pyproject.toml`).\n\n### Core utilities\n\n- `boto3\u003e=1.43.1,\u003c2` (includes `botocore` transitively)\n- `pandas==3.0.2`\n- `requests==2.33.1`\n\n### Google API and auth libraries\n\n- `google-api-core==2.30.3`\n- `google-api-python-client==2.195.0`\n- `google-auth-httplib2==0.3.1`\n- `google-auth-oauthlib==1.3.1`\n\n### Google Cloud client libraries\n\n- `google-cloud-*` packages are pinned in `requirements.txt` (for example: `google-cloud-compute`, `google-cloud-storage`, `google-cloud-resource-manager`, `google-cloud-container`, etc.).\n\n### Vertex/GenAI support\n\n- `google-genai==1.74.0`\n\n### Optional extras\n\n- `prettytable==3.17.0` via `pip install \"gcpwn[table]\"`\n- `xlsxwriter==3.2.9` via `pip install \"gcpwn[excel]\"`\n\n### Dev-only extra\n\n- `pytest\u003e=9.0` via `pip install \"gcpwn[dev]\"`\n\n### Release-build only dependency\n\n- `pyinstaller==6.20.0` is used by `.github/workflows/build_release.yml` to package standalone executables for release artifacts.\n- It is not required for normal runtime usage of GCPwn.\n\nTip: If you want an SBOM from GitHub, open this repository and go to `Insights` -\u003e `Dependency graph`, then use `Export SBOM`.\n\n## Repository Layout\n\n- `gcpwn/`: main package root.\n- `gcpwn/__main__.py`: `python -m gcpwn` entrypoint.\n- `gcpwn/cli/`: command processor and workspace command handlers.\n- `gcpwn/core/`: session/config/db/runtime/export primitives.\n- `gcpwn/modules/`: service modules (`everything`, `opengraph`, service-specific modules).\n- `gcpwn/mappings/`: static mapping/config data used across modules.\n- `tests/`: unit/integration/module tests.\n- `databases/`: SQLite stores for workspaces, sessions, and service data.\n\n## Who Is This For?\n\n- **Pentesters:** automate large portions of GCP recon and exploit-path discovery.\n- **Cloud security learners:** quickly map APIs/resources and permission behavior.\n- **Security researchers:** batch module execution + centralized data/action collection for deeper analysis/proxying.\n\n## Author, Contributors, and License\n\n- Author: NetSPI\n- License: BSD-3-Clause (`LICENSE`)\n- Contributors: PRs and issues welcome\n\n## Resources\n\nTool has changed in several ways and new videos are coming. For now, the following should provide a good resource:\n\n- fwd:cloudsec 2024: https://www.youtube.com/watch?v=opvv9h3Qe0s\n- DEF CON 32 Cloud Village: https://www.youtube.com/watch?v=rxXyYo1n9cw\n- Introduction blog: https://www.netspi.com/blog/technical-blog/cloud-pentesting/introduction-to-gcpwn-part-1/\n\n## Credits\n\nBuilt on the shoulders of giants; inspiration, code, and/or supporting research included from:\n\n- GMap API Scanner: https://github.com/ozguralp/gmapsapiscanner\n- Rhino Security: https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/\n- GCPBucketBrute: https://github.com/RhinoSecurityLabs/GCPBucketBrute\n- Google Cloud Python docs: https://cloud.google.com/python/docs/reference\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetspi%2Fgcpwn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetspi%2Fgcpwn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetspi%2Fgcpwn/lists"}