Skip to content

Commit d6a460c

Browse files
committed
added documentations; improved logging
1 parent 98816c7 commit d6a460c

File tree

1 file changed

+105
-68
lines changed

1 file changed

+105
-68
lines changed

orbitaldump/orbitaldump.py

Lines changed: 105 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Name: OrbitalDump
55
Author: K4YT3X
66
Date Created: June 6, 2021
7-
Last Modified: June 6, 2021
7+
Last Modified: July 5, 2021
88
99
A simple multi-threaded distributed SSH brute-forcing tool written in Python.
1010
"""
@@ -34,6 +34,13 @@ def __init__(
3434
valid_credentials: list,
3535
proxies: collections.deque = None,
3636
):
37+
"""
38+
SSH brute forcer initialization function
39+
40+
:param jobs queue.Queue: a queue object containing scanning jobs
41+
:param valid_credentials list: a list to contain valid credentials
42+
:param proxies collections.deque: a deque of proxies to use
43+
"""
3744
threading.Thread.__init__(self)
3845
self.jobs = jobs
3946
self.valid_credentials = valid_credentials
@@ -123,7 +130,12 @@ def stop(self):
123130
self.join()
124131

125132

126-
def parse_arguments():
133+
def parse_arguments() -> argparse.Namespace:
134+
"""
135+
parse command line arguments
136+
137+
:rtype argparse.Namespace: namespace storing the parsed arguments
138+
"""
127139

128140
parser = argparse.ArgumentParser(
129141
prog="orbitaldump",
@@ -155,6 +167,12 @@ def parse_arguments():
155167

156168

157169
def get_proxies() -> collections.deque:
170+
"""
171+
retrieve a list(deque) of usable SOCKS4 proxies from ProxyScrape
172+
the format looks something like deque(["1.1.1.1:1080", "2.2.2.2:1080"])
173+
174+
:rtype collections.deque: a deque of proxies
175+
"""
158176
logger.info("Retrieving SOCKS4 proxies from ProxyScrape")
159177
proxies_request = requests.get(
160178
"https://api.proxyscrape.com/v2/?request=getproxies&protocol=socks4&timeout=10000&country=all"
@@ -176,80 +194,99 @@ def main():
176194
# disable built-in logging so paramiko won't print tracebacks
177195
logging.basicConfig(level=logging.CRITICAL)
178196

179-
# parse command line arguments
180-
args = parse_arguments()
181-
182-
# verify argument validity
183-
assert args.threads >= 1, "number of threads must >= 1"
184-
assert args.username.is_file(), "username file does not exist"
185-
assert args.password.is_file(), "password file does not exist"
186-
assert args.port >= 0, "the port number must >= 0"
187-
assert args.timeout >= 0, "timeout must >= 0"
188-
189-
# initialize variables
190-
thread_pool = []
191-
jobs = queue.Queue()
192-
valid_credentials = []
193-
194-
# get proxies from ProxyScrape
195-
proxies = None
196-
if args.proxies:
197-
proxies = get_proxies()
198-
199-
# create threads
200-
logger.info(f"Launching {args.threads} brute-forcer threads")
201-
for thread_id in range(args.threads):
202-
thread = SshBruteForcer(jobs, valid_credentials, proxies)
203-
thread.name = str(thread_id)
204-
thread.start()
205-
thread_pool.append(thread)
206-
207-
# add username and password combinations to jobs queue
208-
logger.info("Loading usernames and passwords into queue")
209-
with args.username.open("r") as username_file:
210-
with args.password.open("r") as password_file:
211-
for username in username_file:
212-
for password in password_file:
213-
jobs.put(
214-
(
215-
args.hostname,
216-
username.strip(),
217-
password.strip(),
218-
args.port,
219-
args.timeout,
220-
)
221-
)
197+
# remove built-in logger sink
198+
logger.remove(0)
199+
200+
# add custom logger sink
201+
logger.add(
202+
sys.stderr,
203+
colorize=True,
204+
format="<fg 240>{time:HH:mm:ss.SSSSSS!UTC}</fg 240> | <level>{level: <8}</level> | <level>{message}</level>",
205+
)
222206

223207
try:
224-
while not jobs.empty():
225-
for thread in thread_pool:
226-
if not thread.is_alive():
227-
logger.error(
228-
f"Thread {thread.name} exited early with errors",
229-
file=sys.stderr,
230-
)
208+
# parse command line arguments
209+
args = parse_arguments()
210+
211+
# verify argument validity
212+
try:
213+
assert args.threads >= 1, "number of threads must >= 1"
214+
assert args.username.is_file(), "username file does not exist"
215+
assert args.password.is_file(), "password file does not exist"
216+
assert args.port >= 0, "the port number must >= 0"
217+
assert args.timeout >= 0, "timeout must >= 0"
218+
except AssertionError as e:
219+
logger.error(e)
220+
sys.exit(1)
221+
222+
# initialize variables
223+
thread_pool = []
224+
jobs = queue.Queue()
225+
valid_credentials = []
226+
227+
# get proxies from ProxyScrape
228+
proxies = None
229+
if args.proxies:
230+
proxies = get_proxies()
231+
232+
# create threads
233+
logger.info(f"Launching {args.threads} brute-forcer threads")
234+
for thread_id in range(args.threads):
235+
thread = SshBruteForcer(jobs, valid_credentials, proxies)
236+
thread.name = str(thread_id)
237+
thread.start()
238+
thread_pool.append(thread)
239+
240+
# add username and password combinations to jobs queue
241+
logger.info("Loading usernames and passwords into queue")
242+
with args.username.open("r") as username_file:
243+
with args.password.open("r") as password_file:
244+
for username in username_file:
245+
for password in password_file:
246+
jobs.put(
247+
(
248+
args.hostname,
249+
username.strip(),
250+
password.strip(),
251+
args.port,
252+
args.timeout,
253+
)
254+
)
231255

232-
for thread in thread_pool:
233-
if thread.is_alive():
256+
try:
257+
while not jobs.empty():
258+
for thread in thread_pool:
259+
if not thread.is_alive():
260+
logger.error(
261+
f"Thread {thread.name} exited early with errors",
262+
file=sys.stderr,
263+
)
264+
265+
for thread in thread_pool:
266+
if thread.is_alive():
267+
break
268+
else:
234269
break
235-
else:
236-
break
237270

238-
except (SystemExit, KeyboardInterrupt):
239-
logger.warning("Stop signal received, stopping threads")
271+
except (SystemExit, KeyboardInterrupt):
272+
logger.warning("Stop signal received, stopping threads")
240273

241-
finally:
242-
for thread in thread_pool:
243-
thread.stop()
274+
finally:
275+
for thread in thread_pool:
276+
thread.stop()
277+
278+
for thread in thread_pool:
279+
thread.join()
244280

245-
for thread in thread_pool:
246-
thread.join()
281+
logger.success(
282+
f"Brute-force completed, {len(valid_credentials)} valid credentials found"
283+
)
284+
for hostname, username, password, port, timeout in valid_credentials:
285+
print(f"{username}@{hostname}:{port}:{password}")
247286

248-
logger.success(
249-
f"Brute-force completed, {len(valid_credentials)} valid credentials found"
250-
)
251-
for hostname, username, password, port, timeout in valid_credentials:
252-
print(f"{username}@{hostname}:{port}:{password}")
287+
except Exception as e:
288+
logger.exception(e)
289+
sys.exit(1)
253290

254291

255292
# launch the main function if this file is ran directly

0 commit comments

Comments
 (0)