Article by Aloïs THÉVENOT.
Enumerate Service Account Permissions
Link to Tool: GitHub
On GCP it is possible to use the projects.testIamPermissions
method to check the permissions that a caller has on the specified Project.
To enumerate permissions you will need either a service account key file or an access token as well as the project ID.
Info
The project ID can be retrieved from the metadata endpoint at /computeMetadata/v1/project/project-id
The following script taken from the ThunderCTF repository can be used to enumerate permissions:
from googleapiclient import discovery
import google.oauth2.service_account
from google.oauth2.credentials import Credentials
import os, sys
from permissions import permissions
if len(sys.argv) != 2:
sys.exit("Usage python test-permissions <token | path_to_key_file>")
if os.getenv('GOOGLE_CLOUD_PROJECT'):
PROJECT_ID = os.getenv('GOOGLE_CLOUD_PROJECT')
print(PROJECT_ID)
else:
sys.exit("Please set your GOOGLE_CLOUD_PROJECT environment variable via gcloud config set project [PROJECT_ID]")
if (os.path.exists(sys.argv[1])):
print(f'JSON credential: {sys.argv[1]}')
# Create credentials using service account key file
credentials = google.oauth2.service_account.Credentials.from_service_account_file(sys.argv[1])
else:
print(f'Access token: {sys.argv[1][0:4]}...{sys.argv[1][-4:]}')
ACCESS_TOKEN = sys.argv[1]
# Create credentials using access token
credentials = Credentials(token=sys.argv[1])
# Split testable permissions list into lists of 100 items each
chunked_permissions = (
[permissions[i * 100:(i + 1) * 100] for i in range((len(permissions)+99) // 100)])
# Build cloudresourcemanager REST API python object
crm_api = discovery.build('cloudresourcemanager',
'v1', credentials=credentials)
# For each list of 100 permissions, query the api to see if the service account has any of the permissions
given_permissions = []
for permissions_chunk in chunked_permissions:
response = crm_api.projects().testIamPermissions(resource=PROJECT_ID, body={
'permissions': permissions_chunk}).execute()
# If the service account has any of the permissions, add them to the output list
if 'permissions' in response:
given_permissions.extend(response['permissions'])
print(given_permissions)
Updating the list of permissions
The file containing the list of permissions needs to be created / updated before using the enumeration script.
The file permissions.py
should look like this:
permissions = [
'accessapproval.requests.approve',
...
'vpcaccess.operations.list'
]
The list of existing permissions can be obtained from the IAM permissions reference page or from the IAM Dataset powering gcp.permissions.cloud.