Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into refactoring/gcp/cloudsql
- Loading branch information
Showing
13 changed files
with
131 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from ScoutSuite.providers.gcp.facade.base import GCPBaseFacade | ||
from ScoutSuite.providers.gcp.facade.utils import GCPFacadeUtils | ||
from ScoutSuite.providers.utils import run_concurrently | ||
|
||
class IAMFacade(GCPBaseFacade): | ||
def __init__(self): | ||
super(IAMFacade, self).__init__('iam', 'v1') | ||
|
||
async def get_bindings(self, project_id: str, service_account_email: str): | ||
resource = 'projects/{}/serviceAccounts/{}'.format(project_id, service_account_email) | ||
iam_client = self._get_client() | ||
response = await run_concurrently( | ||
lambda: iam_client.projects().serviceAccounts().getIamPolicy(resource=resource).execute() | ||
) | ||
return response.get('bindings', []) | ||
|
||
async def get_keys(self, project_id: str, service_account_email: str): | ||
name = 'projects/{}/serviceAccounts/{}'.format(project_id, service_account_email) | ||
iam_client = self._get_client() | ||
response = await run_concurrently( | ||
lambda: iam_client.projects().serviceAccounts().keys().list(name=name).execute() | ||
) | ||
return response.get('keys', []) | ||
|
||
async def get_service_accounts(self, project_id: str): | ||
name = 'projects/{}'.format(project_id) | ||
iam_client = self._get_client() | ||
request = iam_client.projects().serviceAccounts().list(name=name) | ||
service_accounts_group = iam_client.projects().serviceAccounts() | ||
return await GCPFacadeUtils.get_all('accounts', request, service_accounts_group) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from ScoutSuite.providers.gcp.facade.gcp import GCPFacade | ||
from ScoutSuite.providers.base.configs.resources import Resources | ||
|
||
class Bindings(Resources): | ||
def __init__(self, gcp_facade: GCPFacade, project_id: str, service_account_email: str): | ||
self.gcp_facade = gcp_facade | ||
self.project_id = project_id | ||
self.service_account_email = service_account_email | ||
|
||
async def fetch_all(self): | ||
raw_bindings = await self.gcp_facade.iam.get_bindings(self.project_id, self.service_account_email) | ||
for raw_binding in raw_bindings: | ||
binding_id, binding = self._parse_binding(raw_binding) | ||
self[binding_id] = binding | ||
|
||
def _parse_binding(self, raw_binding): | ||
return len(self), raw_binding |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from ScoutSuite.providers.gcp.facade.gcp import GCPFacade | ||
from ScoutSuite.providers.base.configs.resources import Resources | ||
|
||
class Keys(Resources): | ||
def __init__(self, gcp_facade: GCPFacade, project_id: str, service_account_email: str): | ||
self.gcp_facade = gcp_facade | ||
self.project_id = project_id | ||
self.service_account_email = service_account_email | ||
|
||
async def fetch_all(self): | ||
raw_keys = await self.gcp_facade.iam.get_keys(self.project_id, self.service_account_email) | ||
for raw_key in raw_keys: | ||
key_id, key = self._parse_key(raw_key) | ||
self[key_id] = key | ||
|
||
def _parse_key(self, raw_key): | ||
key_dict = {} | ||
# The name of the key has the following format: | ||
# projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{key} | ||
# https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts.keys | ||
key_dict['id'] = raw_key['name'].split('/')[-1] | ||
key_dict['valid_after'] = raw_key['validAfterTime'] | ||
key_dict['valid_before'] = raw_key['validBeforeTime'] | ||
key_dict['key_algorithm'] = raw_key['keyAlgorithm'] | ||
return key_dict['id'], key_dict |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from ScoutSuite.providers.gcp.facade.gcp import GCPFacade | ||
from ScoutSuite.providers.gcp.resources.projects import Projects | ||
from ScoutSuite.providers.gcp.resources.iam.service_accounts import ServiceAccounts | ||
|
||
class IAM(Projects): | ||
_children = [ | ||
(ServiceAccounts, 'service_accounts') | ||
] |
30 changes: 30 additions & 0 deletions
30
ScoutSuite/providers/gcp/resources/iam/service_accounts.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from ScoutSuite.providers.gcp.facade.gcp import GCPFacade | ||
from ScoutSuite.providers.gcp.resources.resources import GCPCompositeResources | ||
from ScoutSuite.providers.gcp.resources.iam.bindings import Bindings | ||
from ScoutSuite.providers.gcp.resources.iam.keys import Keys | ||
|
||
class ServiceAccounts(GCPCompositeResources): | ||
_children = [ | ||
(Bindings, 'bindings'), | ||
(Keys, 'keys') | ||
] | ||
|
||
def __init__(self, gcp_facade: GCPFacade, project_id: str): | ||
self.gcp_facade = gcp_facade | ||
self.project_id = project_id | ||
|
||
async def fetch_all(self): | ||
raw_service_accounts = await self.gcp_facade.iam.get_service_accounts(self.project_id) | ||
for raw_service_account in raw_service_accounts: | ||
service_account_id, service_account = self._parse_service_account(raw_service_account) | ||
self[service_account_id] = service_account | ||
await self._fetch_children(self[service_account_id], gcp_facade = self.gcp_facade, project_id = self.project_id, service_account_email = service_account['email']) | ||
|
||
def _parse_service_account(self, raw_service_account): | ||
service_account_dict = {} | ||
service_account_dict['id'] = raw_service_account['uniqueId'] | ||
service_account_dict['display_name'] = raw_service_account.get('displayName', 'N/A') | ||
service_account_dict['name'] = raw_service_account['email'] | ||
service_account_dict['email'] = raw_service_account['email'] | ||
service_account_dict['project_id'] = raw_service_account['projectId'] | ||
return service_account_dict['id'], service_account_dict |
4 changes: 2 additions & 2 deletions
4
ScoutSuite/providers/gcp/rules/findings/iam-old-service-account-keys.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
{ | ||
"dashboard_name": "Service Accounts", | ||
"description": "Old Service Account Keys (over 90 days)", | ||
"path": "iam.service_accounts.id.keys.id", | ||
"path": "iam.projects.id.service_accounts.id.keys.id", | ||
"display_path": "iam.service_accounts.id", | ||
"conditions": [ "and", | ||
[ "iam.service_accounts.id.keys.id.valid_after", "olderThan", ["90", "days"] ] | ||
[ "iam.projects.id.service_accounts.id.keys.id.valid_after", "olderThan", ["90", "days"] ] | ||
], | ||
"id_suffix": "this.valid_after" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.