Compare commits
8 Commits
05276732f1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c58d6b63 | ||
|
|
d9d25fa442 | ||
|
|
1a712a8299 | ||
|
|
2ea16cc882 | ||
|
|
a60b7a8676 | ||
|
|
8dec167c7a | ||
|
|
dcc62019bc | ||
|
|
104118b280 |
@@ -438,9 +438,9 @@ def get_instance_volume_details2():
|
||||
print("CTRL-C received, exiting...")
|
||||
|
||||
|
||||
def describe_addresses():
|
||||
def describe_elastic_addresses():
|
||||
'''
|
||||
Describe EC2 addresses (loop through all regions)
|
||||
Describe EC2 elastic addresses (loop through all regions)
|
||||
'''
|
||||
try:
|
||||
for region in regions:
|
||||
@@ -472,6 +472,45 @@ def describe_addresses():
|
||||
except KeyboardInterrupt:
|
||||
print("CTRL-C received, exiting...")
|
||||
|
||||
def describe_publicips():
|
||||
'''
|
||||
Describe EC2 Public IPs (loop through all regions)
|
||||
'''
|
||||
try:
|
||||
for region in regions:
|
||||
try:
|
||||
client = boto3.client('ec2', region_name=region)
|
||||
response = client.describe_network_interfaces()
|
||||
# print(response)
|
||||
except botocore.exceptions.ClientError as e:
|
||||
if e.response['Error']['Code'] == 'UnauthorizedOperation':
|
||||
print('{} : (UnauthorizedOperation) when calling describe_network_interfaces -- sure you have required ec2 permissions?' .format(AWS_ACCESS_KEY_ID))
|
||||
sys.exit()
|
||||
else:
|
||||
print(e)
|
||||
if response.get('NetworkInterfaces') is None:
|
||||
print("{} likely does not have EC2 permissions\n" .format(AWS_ACCESS_KEY_ID))
|
||||
elif len(response['NetworkInterfaces']) <= 0:
|
||||
print("[-] DescribeNetworkInterfaces allowed for {} but no results [-]" .format(region))
|
||||
else:
|
||||
# print(response)
|
||||
print("[+] Listing Public IPs for region: {} [+]" .format(region))
|
||||
for r in response['NetworkInterfaces']:
|
||||
if 'Association' in r:
|
||||
pp.pprint(r['Association']['PublicIp'])
|
||||
else:
|
||||
#pp.pprint(r)
|
||||
next
|
||||
except botocore.exceptions.ClientError as e:
|
||||
if e.response['Error']['Code'] == 'UnauthorizedOperation':
|
||||
print('{} : (UnauthorizedOperation) when calling the describe_network_interfaces-- sure you have ec2 permissions?' .format(AWS_ACCESS_KEY_ID))
|
||||
elif e.response['Error']['Code'] == 'SubscriptionRequiredException':
|
||||
print('{} : Has permissions but isnt signed up for service - usually means you have a root account' .format(AWS_ACCESS_KEY_ID))
|
||||
else:
|
||||
print(e)
|
||||
except KeyboardInterrupt:
|
||||
print("CTRL-C received, exiting...")
|
||||
|
||||
|
||||
def describe_network_interfaces():
|
||||
'''
|
||||
@@ -485,7 +524,7 @@ def describe_network_interfaces():
|
||||
# print(response)
|
||||
except botocore.exceptions.ClientError as e:
|
||||
if e.response['Error']['Code'] == 'UnauthorizedOperation':
|
||||
print('{} : (UnauthorizedOperation) when calling get_console_screenshot -- sure you have required ec2 permissions?' .format(AWS_ACCESS_KEY_ID))
|
||||
print('{} : (UnauthorizedOperation) when calling describe_network_interfaces -- sure you have required ec2 permissions?' .format(AWS_ACCESS_KEY_ID))
|
||||
sys.exit()
|
||||
else:
|
||||
print(e)
|
||||
@@ -500,7 +539,7 @@ def describe_network_interfaces():
|
||||
pp.pprint(r)
|
||||
except botocore.exceptions.ClientError as e:
|
||||
if e.response['Error']['Code'] == 'UnauthorizedOperation':
|
||||
print('{} : (UnauthorizedOperation) when calling the DescribeInstances-- sure you have ec2 permissions?' .format(AWS_ACCESS_KEY_ID))
|
||||
print('{} : (UnauthorizedOperation) when calling the describe_network_interfaces -- sure you have ec2 permissions?' .format(AWS_ACCESS_KEY_ID))
|
||||
elif e.response['Error']['Code'] == 'SubscriptionRequiredException':
|
||||
print('{} : Has permissions but isnt signed up for service - usually means you have a root account' .format(AWS_ACCESS_KEY_ID))
|
||||
else:
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
'''
|
||||
GCP BigQuery functions for WeirdAAL
|
||||
'''
|
||||
|
||||
import google.auth
|
||||
import googleapiclient.discovery
|
||||
import os
|
||||
import sys
|
||||
|
||||
from google.oauth2 import service_account
|
||||
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
from google.cloud import bigquery, exceptions
|
||||
from google.cloud.exceptions import *
|
||||
|
||||
|
||||
def gcp_bigquery_list_datasets(project_id, credentials):
|
||||
bigquery_client = bigquery.Client(project=credentials.project_id)
|
||||
datasets = list(bigquery_client.list_datasets())
|
||||
project = bigquery_client.project
|
||||
|
||||
if datasets:
|
||||
print('Datasets in project {}:'.format(project))
|
||||
for dataset in datasets: # API request(s)
|
||||
print('\t{}'.format(dataset.dataset_id))
|
||||
else:
|
||||
print('{} project does not contain any datasets.'.format(project))
|
||||
@@ -1,43 +0,0 @@
|
||||
'''
|
||||
GCP IAM functions for WeirdAAL
|
||||
'''
|
||||
|
||||
import google.auth
|
||||
import googleapiclient.discovery
|
||||
import os
|
||||
import sys
|
||||
|
||||
from google.oauth2 import service_account
|
||||
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
|
||||
|
||||
# [START iam_list_keys]
|
||||
def gcp_iam_list_keys(service_account_email, service):
|
||||
"""Lists all keys for a service account."""
|
||||
|
||||
# pylint: disable=no-member
|
||||
keys = service.projects().serviceAccounts().keys().list(
|
||||
name='projects/-/serviceAccounts/' + service_account_email).execute()
|
||||
|
||||
for key in keys['keys']:
|
||||
print('Key: ' + key['name'])
|
||||
# [END iam_list_keys]
|
||||
|
||||
|
||||
# [START iam_list_service_accounts]
|
||||
def gcp_iam_list_service_accounts(project_id, service):
|
||||
"""Lists all service accounts for the current project."""
|
||||
|
||||
# pylint: disable=no-member
|
||||
service_accounts = service.projects().serviceAccounts().list(
|
||||
name='projects/' + project_id).execute()
|
||||
|
||||
for account in service_accounts['accounts']:
|
||||
print('Name: ' + account['name'])
|
||||
print('Email: ' + account['email'])
|
||||
print(' ')
|
||||
return service_accounts
|
||||
# [END iam_list_service_accounts]
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
'''
|
||||
GCP Storage functions for WeirdAAL
|
||||
'''
|
||||
|
||||
import google.auth
|
||||
import googleapiclient.discovery
|
||||
import os
|
||||
import sys
|
||||
|
||||
from google.oauth2 import service_account
|
||||
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
from google.cloud import storage, exceptions
|
||||
from google.cloud.exceptions import *
|
||||
|
||||
|
||||
|
||||
def gcp_storage_list_buckets(credentials):
|
||||
list_of_buckets = []
|
||||
'''list Google storage buckets for account'''
|
||||
storage_client = storage.Client()
|
||||
buckets = storage_client.list_buckets()
|
||||
for buck in buckets:
|
||||
print(buck.name)
|
||||
list_of_buckets.append(buck.name)
|
||||
return list_of_buckets
|
||||
|
||||
|
||||
def gcp_storage_list_blobs(credentials, bucket_name):
|
||||
'''Lists all the blobs in the bucket.'''
|
||||
storage_client = storage.Client()
|
||||
bucket = storage_client.get_bucket(bucket_name)
|
||||
|
||||
blobs = bucket.list_blobs()
|
||||
|
||||
for blob in blobs:
|
||||
print('\t{}'.format(blob.name))
|
||||
print('\n')
|
||||
@@ -64,12 +64,12 @@ def module_ec2_review_encrypted_volumes():
|
||||
review_encrypted_volumes()
|
||||
|
||||
|
||||
def module_ec2_describe_addresses():
|
||||
def module_ec2_describe_elastic_addresses():
|
||||
'''
|
||||
This function is used to describe ec2 network addresses.
|
||||
python3 weirdAAL.py -m ec2_describe_addresses -t demo
|
||||
'''
|
||||
describe_addresses()
|
||||
describe_elastic_addresses()
|
||||
|
||||
|
||||
def module_ec2_describe_network_interfaces():
|
||||
@@ -79,6 +79,12 @@ def module_ec2_describe_network_interfaces():
|
||||
'''
|
||||
describe_network_interfaces()
|
||||
|
||||
def module_ec2_describe_publicips():
|
||||
'''
|
||||
This function is used to describe ec2 network interfaces.
|
||||
python3 weirdAAL.py -m ec2_describe_publicips -t demo
|
||||
'''
|
||||
describe_publicips()
|
||||
|
||||
def module_ec2_describe_route_tables():
|
||||
'''
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
'''
|
||||
This module handles the core GCP recon functionality by asking all the services
|
||||
that have functions that done have arguments if we can access them :-)
|
||||
'''
|
||||
|
||||
|
||||
|
||||
from libs.gcp.gcp_iam import *
|
||||
from libs.gcp.gcp_storage import *
|
||||
from libs.gcp.gcp_bigquery import *
|
||||
|
||||
credentials = service_account.Credentials.from_service_account_file(
|
||||
filename=os.environ['GOOGLE_APPLICATION_CREDENTIALS'],
|
||||
scopes=['https://www.googleapis.com/auth/cloud-platform'])
|
||||
|
||||
service = googleapiclient.discovery.build(
|
||||
'iam', 'v1', credentials=credentials)
|
||||
|
||||
def module_gcp_recon_all():
|
||||
'''
|
||||
Main gcp_recon_all module - attempt to connect to each of the services to see if we have some privs
|
||||
python3 weirdAAL.py -m gcp_recon_all -t demo
|
||||
'''
|
||||
try:
|
||||
print("GCP IAM List Keys check")
|
||||
# print(credentials)
|
||||
gcp_iam_list_keys(credentials.service_account_email, service)
|
||||
except HttpError as e:
|
||||
# print(e)
|
||||
if e.resp.status in [403, 500, 503]:
|
||||
print("\tGCP IAM access denied for {}\n".format(credentials.service_account_email))
|
||||
else:
|
||||
print('{}\n'.format(e))
|
||||
except google.auth.exceptions.RefreshError as f:
|
||||
print(f)
|
||||
print("Service key is invalid exiting")
|
||||
sys.exit()
|
||||
|
||||
try:
|
||||
print("GCP IAM list service accounts for the current project: {}.".format(credentials.project_id))
|
||||
# print(credentials)
|
||||
gcp_iam_list_service_accounts(credentials.project_id, service)
|
||||
except HttpError as e:
|
||||
# print(e)
|
||||
if e.resp.status in [403, 500, 503]:
|
||||
print("\tIAM access denied for {}\n".format(credentials.service_account_email))
|
||||
else:
|
||||
print('{}\n'.format(e))
|
||||
except google.auth.exceptions.RefreshError as f:
|
||||
print(f)
|
||||
print("Service key is invalid exiting")
|
||||
sys.exit()
|
||||
|
||||
'''
|
||||
Storage bucket access checks
|
||||
'''
|
||||
try:
|
||||
print("GCP Storage check")
|
||||
buckets = gcp_storage_list_buckets(credentials)
|
||||
if buckets:
|
||||
print("\nAttempting to list bucket contents:")
|
||||
for a in buckets:
|
||||
print('Bucket: {}'.format(a))
|
||||
gcp_storage_list_blobs(credentials, a)
|
||||
except googleapiclient.errors.HttpError as e:
|
||||
print('{}\n'.format(e))
|
||||
except exceptions.Forbidden as e:
|
||||
print("\t Forbidden")
|
||||
print('{}\n'.format(e))
|
||||
except exceptions.PermissionDenied as e:
|
||||
print("\t PermissionDenied")
|
||||
except google.auth.exceptions.RefreshError as f:
|
||||
print(f)
|
||||
|
||||
'''
|
||||
BigQuery access checks
|
||||
'''
|
||||
try:
|
||||
print("GCP BigQuery check")
|
||||
gcp_bigquery_list_datasets(credentials.project_id, credentials)
|
||||
except googleapiclient.errors.HttpError as e:
|
||||
print('{}\n'.format(e))
|
||||
except exceptions.Forbidden as e:
|
||||
print("\t Forbidden")
|
||||
print('{}\n'.format(e))
|
||||
except exceptions.PermissionDenied as e:
|
||||
print("\t PermissionDenied")
|
||||
except google.auth.exceptions.RefreshError as f:
|
||||
print(f)
|
||||
@@ -7,8 +7,3 @@ s3transfer==0.1.11
|
||||
six==1.11.0
|
||||
virtualenv==15.1.0
|
||||
tabulate==0.8.2
|
||||
|
||||
google-api-python-client==1.7.4
|
||||
google.cloud==0.34.0
|
||||
google-cloud-storage==1.12.0
|
||||
google-cloud-bigquery==1.5.1
|
||||
|
||||
36
weirdAAL.py
36
weirdAAL.py
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This file will help to serve as a starting point for using the rest of the tools
|
||||
# Things we want to figure out
|
||||
# 1) Is your key active?
|
||||
@@ -9,6 +11,7 @@
|
||||
import boto3
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from botocore.exceptions import ClientError
|
||||
from modules import *
|
||||
import sys
|
||||
@@ -17,19 +20,24 @@ import re
|
||||
from tabulate import tabulate
|
||||
import textwrap
|
||||
|
||||
# not pythonic but keeping google imports separate for now
|
||||
import google.auth
|
||||
import googleapiclient.discovery
|
||||
# Let a user set .aws/credentials or another file as the credentials source
|
||||
# If user-defined, must be an absolute path
|
||||
AWS_SHARED_CREDS_PATH='.env'
|
||||
if 'AWS_SHARED_CREDENTIALS_FILE' not in os.environ and os.path.exists(AWS_SHARED_CREDS_PATH):
|
||||
os.environ['AWS_SHARED_CREDENTIALS_FILE'] = AWS_SHARED_CREDS_PATH
|
||||
else:
|
||||
print('No Key Information available. Place creds in .env file or export variables.')
|
||||
print('Shared Creds Example File:')
|
||||
print('[default]\n\
|
||||
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID\n\
|
||||
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY')
|
||||
print()
|
||||
print('Or to export them in running shell:')
|
||||
print('export AWS_ACCESS_KEY_ID=<hereyourkeyid>')
|
||||
print('export AWS_SECRET_ACCESS_KEY=<hereyoursecretaccesskey>')
|
||||
print()
|
||||
sys.exit(1)
|
||||
|
||||
from google.oauth2 import service_account
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
from google.cloud import storage, exceptions
|
||||
from google.cloud.exceptions import *
|
||||
|
||||
os.environ['AWS_SHARED_CREDENTIALS_FILE'] = '.env'
|
||||
|
||||
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'gcp_keys/34.json'
|
||||
|
||||
# If you want to use a transparent + supports SSL proxy you can put it here
|
||||
# os.environ['HTTPS_PROXY'] = 'https://127.0.0.1:3128'
|
||||
@@ -67,9 +75,6 @@ def perform_credential_check():
|
||||
except ClientError as e:
|
||||
print("The AWS Access Keys are not valid/active")
|
||||
sys.exit(1)
|
||||
# excepetion to catch the lack of aws cred here - temp fix
|
||||
except Exception as e:
|
||||
print('\t -')
|
||||
|
||||
def method_create():
|
||||
try:
|
||||
@@ -125,6 +130,7 @@ def make_tabulate_rows(hash, cloud_provider):
|
||||
for item in hash[key]:
|
||||
for (k,v) in item.items():
|
||||
normalized_comment = normalize_comments(v)
|
||||
k = re.sub("module_", "", k)
|
||||
entire_contents.append([cloud_provider, key, k, normalized_comment])
|
||||
|
||||
return entire_contents
|
||||
|
||||
Reference in New Issue
Block a user