Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 73 additions & 66 deletions credmaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,94 +39,85 @@ def __init__(self, args, pargs):
self.api_list = args.api_list

self.pargs = pargs
self.parse_all_args(args)

self.do_input_error_handling()

# Utility handling, else run spray
if args.clean:
self.clear_all_apis()
elif args.api_destroy != None:
self.destroy_single_api(args.api_destroy)
elif args.api_list:
self.list_apis()
else:
self.Execute(args)


def parse_all_args(self, args):
#
# this function will parse both config files and CLI args
# If a value is specified in both config and CLI, the CLI value will be preferred
# Reason: if someone wants to take a standard config from client to client, they can override a value
#

self.args = args

if args.config is not None and not os.path.exists(args.config):
self.log_entry(f"Config file {args.config} cannot be found")
sys.exit()

# assign variables
# TOO MANY MF VARIABLES THIS HAS GOTTEN OUT OF CONTROL
# This is fine ;)
# No, it's really not :(

config_dict = {}
if args.config != None:
config_dict = json.loads(open(args.config).read())
# TODO: either move to fucntion named args, or (*args, **kwargs)
# TODO: Make all the self.fobar args match the argparse.args.foo_bar args

self.plugin = args.plugin or config_dict.get("plugin")
self.userfile = args.userfile or config_dict.get("userfile")
self.passwordfile = args.passwordfile or config_dict.get("passwordfile")
self.userpassfile = args.userpassfile or config_dict.get("userpassfile")
self.useragentfile = args.useragentfile or config_dict.get("useragentfile")
self.trim = args.trim or config_dict.get("trim")
# TODO: Why are we storing the entire args namespace, but also coppying almost all of them to self attrs?
self.args = args

self.outfile = args.outfile or config_dict.get("outfile")
self.plugin = args.plugin
self.userfile = args.userfile
self.passwordfile = args.passwordfile
self.userpassfile = args.userpassfile
self.useragentfile = args.useragentfile
self.trim = args.trim

self.thread_count = args.threads or config_dict.get("threads")
self.outfile = args.outfile

self.thread_count = args.threads
if self.thread_count == None:
self.thread_count = 1

self.region = args.region or config_dict.get("region")
self.jitter = args.jitter or config_dict.get("jitter")
self.jitter_min = args.jitter_min or config_dict.get("jitter_min")
self.delay = args.delay or config_dict.get("delay")
self.region = args.region
self.jitter = args.jitter
self.jitter_min = args.jitter_min
self.delay = args.delay

self.batch_size = args.batch_size or config_dict.get("batch_size")
self.batch_delay = args.batch_delay or config_dict.get("batch_delay")
self.batch_size = args.batch_size
self.batch_delay = args.batch_delay
if self.batch_size != None and self.batch_delay == None:
self.batch_delay = 1


self.passwordsperdelay = args.passwordsperdelay or config_dict.get("passwordsperdelay")
self.passwordsperdelay = args.passwordsperdelay
if self.passwordsperdelay == None:
self.passwordsperdelay = 1

self.randomize = args.randomize or config_dict.get("randomize")
self.header = args.header or config_dict.get("header")
self.xforwardedfor = args.xforwardedfor or config_dict.get("xforwardedfor")
self.weekdaywarrior = args.weekday_warrior or config_dict.get("weekday_warrior")
self.color = args.color or config_dict.get("color")
self.randomize = args.randomize
self.header = args.header
self.xforwardedfor = args.xforwardedfor
self.weekdaywarrior = args.weekday_warrior
self.color = args.color

self.notify_obj = {
"slack_webhook" : args.slack_webhook or config_dict.get("slack_webhook"),
"pushover_token" : args.pushover_token or config_dict.get("pushover_token"),
"pushover_user" : args.pushover_user or config_dict.get("pushover_user"),
"ntfy_topic" : args.ntfy_topic or config_dict.get("ntfy_topic"),
"ntfy_host" : args.ntfy_host or config_dict.get("ntfy_host"),
"ntfy_token" : args.ntfy_token or config_dict.get("ntfy_token"),
"discord_webhook" : args.discord_webhook or config_dict.get("discord_webhook"),
"keybase_webhook" : args.keybase_webhook or config_dict.get("keybase_webhook"),
"teams_webhook" : args.teams_webhook or config_dict.get("teams_webhook"),
"operator_id" : args.operator_id or config_dict.get("operator_id"),
"exclude_password" : args.exclude_password or config_dict.get("exclude_password")
"slack_webhook" : args.slack_webhook,
"pushover_token" : args.pushover_token,
"pushover_user" : args.pushover_user,
"ntfy_topic" : args.ntfy_topic,
"ntfy_host" : args.ntfy_host,
"ntfy_token" : args.ntfy_token,
"discord_webhook" : args.discord_webhook,
"keybase_webhook" : args.keybase_webhook,
"teams_webhook" : args.teams_webhook,
"operator_id" : args.operator_id,
"exclude_password" : args.exclude_password
}

self.access_key = args.access_key or config_dict.get("access_key")
self.secret_access_key = args.secret_access_key or config_dict.get("secret_access_key")
self.session_token = args.session_token or config_dict.get("session_token")
self.profile_name = args.profile_name or config_dict.get("profile_name")
self.access_key = args.access_key
self.secret_access_key = args.secret_access_key
self.session_token = args.session_token
self.profile_name = args.profile_name

# -----
# End self.parse_all_args()
# -----

self.do_input_error_handling()

# Utility handling, else run spray
if args.clean:
self.clear_all_apis()
elif args.api_destroy != None:
self.destroy_single_api(args.api_destroy)
elif args.api_list:
self.list_apis()
else:
self.Execute(args)


def do_input_error_handling(self):
Expand Down Expand Up @@ -765,5 +756,21 @@ def log_success(self, username, password):
fpu_args.add_argument('--api_list', default=False, action="store_true", help='List all fireprox APIs')

args,pluginargs = parser.parse_known_args()
if args.config is not None:
# This means we have a --config arg. This block loads it, sets the defaults, then re-parses.
# Doing things in this order removes a lot of the spaghetti code for conditional parsing from
# file, while preserving the "CLI > Config file > hard-coded defaults" precedance order.
if not os.path.exists(args.config):
print("Failed to load config. Are you sure it exists where you think it does?")
os.exit(11)
dat = None
with open(args.config, 'r') as f:
dat = {k: v for k,v in json.load(f).items() if v is not None}
if dat is None or len(dat) == 0:
print("Failed to load config. Are you sure it actually has config to use?")
os.exit(12)

parser.set_defaults(**dat)
args,pluginargs = parser.parse_known_args()

CredMaster(args, pluginargs)