184 lines
6.1 KiB
Python
Executable File
184 lines
6.1 KiB
Python
Executable File
#!/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?
|
|
# 2) If active, can you read monitoring configs, can you write?
|
|
# 3) Okay, you can read monitoring configs. We recommend things to avoid. Want to go further? Use write access to disable (if applicable)
|
|
# 4) Don't want to do anything with monitoring? That's fine, let's guide you through figuring out what your access looks like
|
|
# 5) Help with a printout of options from this point forward
|
|
|
|
import boto3
|
|
import argparse
|
|
import os
|
|
import sys
|
|
from botocore.exceptions import ClientError
|
|
from modules import *
|
|
import sys
|
|
import builtins
|
|
import re
|
|
from tabulate import tabulate
|
|
import textwrap
|
|
|
|
# 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)
|
|
|
|
|
|
# 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'
|
|
|
|
sys.path.append("modules")
|
|
for module in all_modules:
|
|
exec("from %s import *" % module)
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("-m", "--module", help="list the module you would like to run", action="store", type=str, required=False)
|
|
parser.add_argument("-t", "--target", help="Give your target a name so we can track results", action="store", type=str, required=False)
|
|
parser.add_argument("-a", "--arguments", help="Provide a list of arguments, comma separated. Ex: arg1,arg2,arg3", action="store", type=str, required=False)
|
|
parser.add_argument("-l", "--list", help="list modules", required=False, action="store_true")
|
|
parser.add_argument("-v", "--verbosity", help="increase output verbosity", action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
# Provides us with a global var "db_name" we can access anywhere
|
|
builtins.db_name = "weirdAAL.db"
|
|
|
|
|
|
def perform_credential_check():
|
|
'''
|
|
Check that the AWS keys work before we go any further. It picks the keys up from the local .env file
|
|
We are letting boto3 do all the work that way we can handle session tokens natively
|
|
'''
|
|
|
|
try:
|
|
client = boto3.client("sts")
|
|
account_id = client.get_caller_identity()["Account"]
|
|
except botocore.exceptions.NoCredentialsError as e:
|
|
print("Error: Unable to locate credentials")
|
|
sys.exit("fix your credentials file -exiting...")
|
|
except ClientError as e:
|
|
print("The AWS Access Keys are not valid/active")
|
|
sys.exit(1)
|
|
|
|
def method_create():
|
|
try:
|
|
arg = globals()["module_" + args.module]
|
|
return arg
|
|
except KeyError:
|
|
print("That module does not exist")
|
|
exit(1)
|
|
|
|
builtins.aws_module_methods_info = {}
|
|
builtins.gcp_module_methods_info = {}
|
|
|
|
def get_methods_for_classname(classname):
|
|
methods = []
|
|
all_methods = dir(sys.modules[classname])
|
|
for meth in all_methods:
|
|
if meth.startswith("module_"):
|
|
narg = "{}.__doc__".format(meth)
|
|
narg = eval(narg)
|
|
nhash = {}
|
|
nhash[meth] = narg
|
|
methods.append(nhash)
|
|
return methods
|
|
|
|
|
|
def make_list_of_methods(cloud_service, mod):
|
|
meths = get_methods_for_classname(mod)
|
|
if cloud_service == 'aws':
|
|
new_mod_name = re.sub("modules.aws.", "", mod)
|
|
aws_module_methods_info[new_mod_name.upper()] = meths
|
|
elif cloud_service == 'gcp':
|
|
new_mod_name = re.sub("modules.gcp.", "", mod)
|
|
gcp_module_methods_info[new_mod_name.upper()] = meths
|
|
|
|
|
|
def make_the_list():
|
|
for m in sys.modules.keys():
|
|
if (m.startswith("modules.aws")
|
|
and not (m == "modules.aws")):
|
|
make_list_of_methods("aws", m)
|
|
elif ((m.startswith("modules.gcp"))
|
|
and not (m == "modules.gcp")):
|
|
make_list_of_methods("gcp", m)
|
|
|
|
def normalize_comments(string):
|
|
string = textwrap.fill(string.strip(), 40)
|
|
return string
|
|
|
|
|
|
def make_tabulate_rows(hash, cloud_provider):
|
|
entire_contents = []
|
|
for (key) in hash:
|
|
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
|
|
|
|
|
|
|
|
def print_the_list():
|
|
aws_rows = make_tabulate_rows(aws_module_methods_info, 'AWS')
|
|
gcp_rows = make_tabulate_rows(gcp_module_methods_info, 'GCP')
|
|
print(tabulate(aws_rows, headers=['Cloud Provider', 'Service', 'Mod', 'Desc']))
|
|
print(tabulate(gcp_rows, headers=['Cloud Provider', 'Service', 'Mod', 'Desc']))
|
|
|
|
if (args.list):
|
|
make_the_list()
|
|
print_the_list()
|
|
sys.exit(1)
|
|
|
|
# Need to figure out if we have keys in the ENV or not
|
|
try:
|
|
perform_credential_check()
|
|
except:
|
|
print("Check the above error message and fix to use weirdAAL")
|
|
sys.exit(1)
|
|
|
|
|
|
# arg_list has to be defined otherwise will cause an exception
|
|
arg_list = None
|
|
|
|
if (args.arguments):
|
|
arg_list = args.arguments.split(',')
|
|
|
|
# We need the user to tell us the module they want to proceed on
|
|
if (args.module):
|
|
if not (args.target):
|
|
print("Use -t to give your target a name so we can track results!!!")
|
|
sys.exit(1)
|
|
else:
|
|
# Provides us with a global var "target" we can access anywhere
|
|
builtins.target = args.target
|
|
arg = method_create()
|
|
if callable(arg):
|
|
if arg_list:
|
|
arg(arg_list)
|
|
else:
|
|
arg()
|
|
|
|
|
|
# Allow the user to specify verbosity for debugging
|
|
if (args.verbosity):
|
|
print("Verbosity is enabled")
|