├── LICENSE ├── README.md ├── SeBruteGUI.py ├── __init__.py ├── common.py ├── config.json ├── imgs ├── background.gif ├── icon.ico ├── open.png ├── run.png └── selenium.jpg ├── processManyIp.py ├── processOneIp.py └── requirements.txt /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, kracer127 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

SeBruteGUI

2 | 3 |

登入框暴力破解

4 |

5 | SeBruteGUI 6 | SeBruteGUI 7 | SeBruteGUI 8 |

9 | 10 | 11 | ## 0x01 介绍 12 | 作者:kracer 13 | 14 | 定位:专注登入框暴力破解,无视复杂的前端js加密。 15 | 16 | 语言:python3开发 17 | 18 | 功能:使用selenium+chromedriver模拟浏览器点击登入,无视复杂的前端js加密。多线程快速破解,可批量IP检测弱口令。exe可执行文件加上GUI界面,简单操作,别再为分析js加密而头疼了。 19 | 20 | 21 | 22 | ## 0x02 安装使用 23 | 24 | 1、所需库安装 25 | 26 | ```python 27 | pip3 install -r requirements.txt 28 | ``` 29 | 30 | 2、使用 31 | 32 | ```python 33 | >>python3 SeBruteGUI.py 开启GUI界面,亦或直接打开exe可执行文件。 34 | ``` 35 | 36 | 3、说明 37 | 38 | ```python 39 | 文件夹:imgs文件夹 --- GUI的背景图片等。 40 | 文件:SeBruteGUI.py --- 主函数入口。 41 | 文件:commom.py --- 用户输入处理、网址存活检测及结果生成等。 42 | 文件:config.json --- 配置文件,chromedriver.exe路径、验证码识别模块的账号密码和ip代理池设置。 43 | 文件:processOneIp.py --- 单ip的爆破类。 44 | 文件:processManyIp.py --- 批量ip的爆破类。 45 | ``` 46 | 47 | 48 | 49 | ## 0x03 效果展示 50 | 51 | **1、程序打开:** 52 | 53 | operating 54 | 55 | **2、程序运行:** 56 | 57 | result 58 | 59 | 60 | 61 | ## 0x04 一些说明: 62 | 63 | 1、使用前提条件: 64 | 65 | ​ ① 安装好chrome浏览器,下载对应版本号的chromedriver.exe驱动。 66 | 67 | ​ chrome官网:https://www.google.cn/chrome/ 68 | 69 | ​ chromedriver驱动官网:https://chromedriver.chromium.org/downloads 70 | 71 | ​ ② 知道xpath路径怎么找:www.baidu.com 72 | 73 | 2、如何使用验证码识别模块: 74 | 75 | ​ ① 到[快识别]([图片识别-打码平台-打码网站-识别验证码-图鉴网络科技有限公司](http://www.kuaishibie.cn/))官网注册账号,并充值购买<10块够你用啦>。http://www.kuaishibie.cn/ 76 | 77 | ​ ② 到config.json文件中填入您的账号密码 --- "captcha": ["账号","密码"]。 78 | 79 | ​ ③ 注意:有的网站登入错误达到一定次数才会出现验证码,所以别粗心。 80 | 81 | 3、代理模块使用: 82 | 83 | ​ ① 将自己的代理ip池保存为txt文件,在config.json的 "proxy": ["把路径填在这里"] 中填写。 84 | 85 | ​ ② 或者在GUI界面中选择文件也可以,注意输入框只能填写单个代理ip。 86 | 87 | ​ ③ 代理ip最好检测下有效性,软件的代理ip有效性检测还待优化。 88 | 89 | 4、当前为第一版本,用户的非正常操作容易导致软件无法运行,使用过程有问题欢迎给我留言。 90 | 91 | 5、程序可优化的地方还挺多,后续有时间再弄了。真诚地邀请各位大佬加入后续开发,一起学习进步,唯一QQ:0x91b8bb99。 92 | 93 | 94 | 95 | **本项目仅供学习, 测试, 交流使用, 勿用于非法用途。** 96 | 97 | ​ **请使用者遵守《中华人民共和国网络安全法》,勿用于非授权测试,如作他用所承受的法律责任一概与** 98 | 99 | **作者无关,下载使用即代表使用者同意上述观点**。 100 | 101 | ​ **喜欢❤️请收藏给一个star吧👍** 102 | 103 | -------------------------------------------------------------------------------- /SeBruteGUI.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # Date: 2021-10-18 3 | # Author:kracer 4 | # Version: 1.0 5 | 6 | 7 | from tkinter import * 8 | import tkinter.messagebox # 消息弹出框 9 | import tkinter.filedialog # 文件选择框 10 | from PIL import Image, ImageTk 11 | from threading import Thread 12 | from common import * 13 | from processOneIp import processOneIp 14 | from processManyIp import processManyIp 15 | import os 16 | sys.setrecursionlimit(1500) 17 | 18 | 19 | 20 | class GUI: 21 | def __init__(self): 22 | self.root = Tk() 23 | self.root.title('登入框暴力破解v1.0 __by:kracer') 24 | self.root.iconbitmap(default=r'.//imgs//icon.ico') 25 | """ 添加背景图片 """ 26 | self.canvas = Canvas(self.root, width=1000, height=700, bd=0, highlightthickness=0) # 创建画布,bd(borderwidth)为文本框边框宽度, highlightthickness边框灰度 27 | self.backgroundImage = ImageTk.PhotoImage(Image.open('.//imgs//background.gif')) # 加载gif图片 28 | self.canvas.create_image(500, 400, image=self.backgroundImage) # 500, 400为偏移参数 29 | self.canvas.pack() 30 | """ 获得本地窗口的大小 """ 31 | left = (self.root.winfo_screenwidth()-1000)/2 # 向右偏移量 32 | top = (self.root.winfo_screenheight()-700)/2 # 向下偏移量 33 | self.root.geometry('%dx%d+%d+%d' % (1000, 650, left, top)) 34 | self.root.resizable(0, 0) # 强制窗口大小,不可缩放 35 | 36 | 37 | def setVal(self): 38 | """ 常量设置 """ 39 | self.startFlag = True # 开启爆破任务标志 40 | self.allUserInput = [] # 装载用户的所有输入 41 | self.modeValue = StringVar() # 爆破模式 1 , 2 42 | self.threadNum = IntVar() # 用户选择的线程数 43 | self.threadNumFile = [] # 线程数列表 44 | self.url = StringVar() # 爆破目标url 45 | self.urlFile = [] # 爆破目标文件批量url 46 | self.username = StringVar() # 爆破的用户名 47 | self.usernameFile = [] # 爆破的用户名(文件批量) 48 | self.password = StringVar() # 爆破的密码 49 | self.passwordFile = [] # 爆破的密码(文件批量) 50 | self.captchaUrl = StringVar() # 验证码url 51 | self.captchaFile = [] # 验证码列表 52 | self.usernameXpath = StringVar() # 用户名输入框的xpath 53 | self.passwordXpath = StringVar() # 密码输入框的xpath 54 | self.captchaXpath = StringVar() # 验证码输入框的xpath 55 | self.submitXpath = StringVar() # 提交按钮的xpath 56 | self.submitFile = [] # 提交按钮列表 57 | self.proxy = [] 58 | if proxy != [""]: 59 | self.proxyFile = proxy # 浏览器代理的ip地址池 60 | else: 61 | self.proxyFile = [] 62 | # 浏览器代理的ip地址池(文件批量) 63 | self.chromedriver = StringVar() # chromedriver.exe的路径 64 | if chromePath != [""]: 65 | self.chromedriverFile = chromePath 66 | else: 67 | self.chromedriverFile = [] # chromedriver.exe的路径(通过文件选择) 68 | 69 | 70 | def run(self): 71 | """ 添加其他组件或窗口 """ 72 | self.setVal() 73 | self.Frame1() 74 | self.Frame2() 75 | self.Frame3() 76 | self.Frame4() 77 | self.Frame5() 78 | self.Frame6() 79 | self.Frame7() 80 | self.root.mainloop() 81 | 82 | 83 | def Frame1(self): 84 | ''' 框架1:导航栏 ''' 85 | frame1 = Frame(self.root, bd=2) 86 | frame1.pack() 87 | self.canvas.create_window(0, 0, width=2000, height=55, window=frame1) # 在画布上嵌入 88 | """ 添加说明、关于按钮 """ 89 | buttonExplain = Button(self.root, text="说明", font=('微软雅黑', 12), fg='black', justify=CENTER, bd=3, bg='#CDCDCD', command=self.frameExplain) # 说明按钮 90 | buttonExplain.pack() 91 | self.canvas.create_window(32, 13, width=60, height=25, window=buttonExplain) # 在画布上嵌入 92 | buttonAbout = Button(self.root, text="关于", font=('微软雅黑', 12), fg='black', justify=CENTER, bd=3, bg='#CDCDCD', command=self.frameAbout) # 说明按钮 93 | buttonAbout.pack() 94 | self.canvas.create_window(94, 13, width=60, height=25, window=buttonAbout) # 在画布上嵌入 95 | 96 | 97 | def Frame2(self): 98 | '''框架2:爆破模式''' 99 | self.canvas.create_rectangle(15, 45, 260, 185) # 爆破模式的矩形边框 100 | textLable1 = Label(self.root, text="爆破模式", bg='red') 101 | textLable1.pack() 102 | self.canvas.create_window(55, 45, width=60, height=25, window=textLable1) # 在画布上嵌入 103 | """ 两个单选按钮 """ 104 | self.modeValue.set(' ') # 清除两个首次打开即默认选中的状态 105 | rdbOne = Radiobutton(self.root, text="单个IP爆破", font=("微软雅黑", 12), bg='#32CD32', fg='blue', variable=self.modeValue, value="mode1") 106 | rdbOne.pack() 107 | self.canvas.create_window(100, 90, width=160, height=25, window=rdbOne) # 在画布上嵌入 108 | rdbMany = Radiobutton(self.root, text="批量IP爆破", font=("微软雅黑", 12), bg='#32CD32', fg='blue', variable=self.modeValue, value="mode2") 109 | rdbMany.pack() 110 | self.canvas.create_window(100, 140, width=160, height=25, window=rdbMany) # 在画布上嵌入 111 | textLable11 = Label(self.root, text="必\n选\n项", font=("微软雅黑", 13), fg='red', bg='#ADDBE6') 112 | textLable11.pack() 113 | self.canvas.create_window(225, 117, width=30, height=85, window=textLable11) # 在画布上嵌入 114 | 115 | 116 | def Frame3(self): 117 | '''说明面板:简单提示 ''' 118 | self.canvas.create_rectangle(15, 340, 260, 205) # 爆破模式的矩形边框 119 | textLable12 = Label(self.root, text="Tips", bg='red') 120 | textLable12.pack() 121 | self.canvas.create_window(55, 205, width=60, height=25, window=textLable12) # 在画布上嵌入 122 | tipsText = Text(self.root, fg='green') # 文本 123 | tipsText.insert("insert", "①安装chrome浏览器,并下载版本对应的chromedriver.exe。\n\n" 124 | "②请先选择好爆破模式,再开始爆破任务。\n\n" 125 | "③线程建议6-20,电脑配置不高的高线程软件会卡死。") 126 | tipsText.pack() 127 | self.canvas.create_window(137, 278, width=243, height=120, window=tipsText) # 在画布上嵌入 128 | 129 | 130 | def Frame4(self): 131 | ''' 线程数选择和开始、清空按钮 ''' 132 | textLable13 = Label(self.root, text="线程数", bg='red', font=("微软雅黑, 13")) 133 | textLable13.pack() 134 | self.canvas.create_window(45, 375, width=70, height=40, window=textLable13) # 在画布上嵌入 135 | threadScale = Scale(self.root, bg='#ADD8E6', variable=self.threadNum, from_=1, to=30, length=450, width=16, orient=HORIZONTAL) 136 | threadScale.pack(anchor=CENTER) 137 | self.canvas.create_window(325, 375, width=450, height=40, window=threadScale) # 在画布上嵌入 138 | 139 | 140 | def Frame5(self): 141 | """ 输出面板 """ 142 | self.canvas.create_line(0, 435, 1000, 435, fill="red") # 输出的线条 143 | textLable14 = Label(self.root, text="结果输出:", bg='red') 144 | textLable14.pack() 145 | self.canvas.create_window(45, 425, width=100, height=20, window=textLable14) # 在画布上嵌入 146 | self.resultText = Text(self.root, bg='#778899', bd=4, font=("微软雅黑", 12)) # 文本 147 | scroll = Scrollbar(self.root) # 滚动条 148 | scroll.pack(side=RIGHT, fill=Y) 149 | self.resultText.pack(side=LEFT, fill=Y) 150 | scroll.config(command=self.resultText.yview) 151 | self.resultText.config(yscrollcommand=scroll.set) 152 | self.canvas.create_window(990, 585, width=20, height=290, window=scroll) # 在画布上嵌入 153 | self.canvas.create_window(500, 585, width=1000, height=300, window=self.resultText) # 在画布上嵌入 154 | 155 | 156 | def Frame6(self): 157 | """ 用户输入数据面板 """ 158 | global entryUrl, entryUserName, entryPassWord, entryCaptchaUrl, entryXpathUserName, entryXpathPassWord, entryXpathCaptcha, entryXpathSubmit, entryProxy, entryChromeDriver 159 | self.canvas.create_rectangle(280, 46, 988, 340, outline='red') # 爆破模式的矩形边框 160 | textLable15 = Label(self.root, text="用户输入", font=("微软雅黑", 10), bg='red') 161 | textLable15.pack() 162 | self.canvas.create_window(320, 47, width=60, height=25, window=textLable15) # 在画布上嵌入 163 | """ 输入:探测目标 """ 164 | LabelUrl = Label(self.root, text="目标URL:", font=("微软雅黑", 10), anchor="w", bg='red') 165 | LabelUrl.pack() 166 | self.canvas.create_window(380, 77, width=150, height=20, window=LabelUrl) # 在画布上嵌入 167 | entryUrl = Entry(self.root, fg="#1E90FF") 168 | entryUrl.pack() 169 | self.canvas.create_window(645, 77, width=300, height=20, window=entryUrl) # 在画布上嵌入 170 | buttonSeletFileUrl = Button(self.root, text="选择文件", font=("微软雅黑", 10), anchor="w", bg='white', command=lambda: self.commandSelectFile(entryUrl, self.urlFile)) 171 | buttonSeletFileUrl.pack() 172 | self.canvas.create_window(767, 77, width=60, height=20, window=buttonSeletFileUrl) # 在画布上嵌入 173 | """ 输入:用户名 """ 174 | LabelUserName = Label(self.root, text="用户名:", font=("微软雅黑", 10), anchor="w", bg='red') 175 | LabelUserName.pack() 176 | self.canvas.create_window(380, 105, width=150, height=20, window=LabelUserName) # 在画布上嵌入 177 | entryUserName = Entry(self.root, fg="#1E90FF") 178 | entryUserName.pack() 179 | self.canvas.create_window(645, 105, width=300, height=20, window=entryUserName) # 在画布上嵌入 180 | buttonSeletFileUserName = Button(self.root, text="选择文件", font=("微软雅黑", 10), anchor="w", bg='white', command=lambda: self.commandSelectFile(entryUserName, self.usernameFile)) 181 | self.canvas.create_window(767, 105, width=60, height=20, window=buttonSeletFileUserName) # 在画布上嵌入 182 | """ 输入:密码 """ 183 | LabelPassWord = Label(self.root, text="密码:", font=("微软雅黑", 10), anchor="w", bg='red') 184 | LabelPassWord.pack() 185 | self.canvas.create_window(380, 133, width=150, height=20, window=LabelPassWord) # 在画布上嵌入 186 | entryPassWord = Entry(self.root, fg="#1E90FF") 187 | entryPassWord.pack() 188 | self.canvas.create_window(645, 133, width=300, height=20, window=entryPassWord) # 在画布上嵌入 189 | buttonSeletFilePassWord = Button(self.root, text="选择文件", font=("微软雅黑", 10), anchor="w", bg='white', command=lambda: self.commandSelectFile(entryPassWord, self.passwordFile)) 190 | buttonSeletFilePassWord.pack() 191 | self.canvas.create_window(767, 133, width=60, height=20, window=buttonSeletFilePassWord) # 在画布上嵌入 192 | """ 输入:验证码url """ 193 | LabelCaptchaUrl = Label(self.root, text="验证码URL:", font=("微软雅黑", 10), anchor="w", bg='red') 194 | LabelCaptchaUrl.pack() 195 | self.canvas.create_window(380, 161, width=150, height=20, window=LabelCaptchaUrl) # 在画布上嵌入 196 | entryCaptchaUrl = Entry(self.root, fg="#1E90FF") 197 | entryCaptchaUrl.pack() 198 | self.canvas.create_window(645, 161, width=300, height=20, window=entryCaptchaUrl) # 在画布上嵌入 199 | """ 输入:用户名的xpath """ 200 | LabelXpathUserName = Label(self.root, text="用户名的xpath:", font=("微软雅黑", 10), anchor="w", bg='red') 201 | LabelXpathUserName.pack() 202 | self.canvas.create_window(380, 189, width=150, height=20, window=LabelXpathUserName) # 在画布上嵌入 203 | entryXpathUserName = Entry(self.root, fg="#1E90FF") 204 | entryXpathUserName.pack() 205 | self.canvas.create_window(645, 189, width=300, height=20, window=entryXpathUserName) # 在画布上嵌入 206 | """ 输入:密码的xpath """ 207 | LabelXpathPassWord = Label(self.root, text="密码的xpath:", font=("微软雅黑", 10), anchor="w", bg='red') 208 | LabelXpathPassWord.pack() 209 | self.canvas.create_window(380, 217, width=150, height=20, window=LabelXpathPassWord) # 在画布上嵌入 210 | entryXpathPassWord = Entry(self.root, fg="#1E90FF") 211 | entryXpathPassWord.pack() 212 | self.canvas.create_window(645, 217, width=300, height=20, window=entryXpathPassWord) # 在画布上嵌入 213 | """ 输入:验证码的xpath """ 214 | LabelXpathCaptcha = Label(self.root, text="验证码的xpath:", font=("微软雅黑", 10), anchor="w", bg='red') 215 | LabelXpathCaptcha.pack() 216 | self.canvas.create_window(380, 245, width=150, height=20, window=LabelXpathCaptcha) # 在画布上嵌入 217 | entryXpathCaptcha = Entry(self.root, fg="#1E90FF") 218 | entryXpathCaptcha.pack() 219 | self.canvas.create_window(645, 245, width=300, height=20, window=entryXpathCaptcha) # 在画布上嵌入 220 | """ 输入:提交按钮的xpath """ 221 | LabelXpathSubmit = Label(self.root, text="提交的xpath:", font=("微软雅黑", 10), anchor="w", bg='red') 222 | LabelXpathSubmit.pack() 223 | self.canvas.create_window(380, 272, width=150, height=20, window=LabelXpathSubmit) # 在画布上嵌入 224 | entryXpathSubmit = Entry(self.root, fg="#1E90FF") 225 | entryXpathSubmit.pack() 226 | self.canvas.create_window(645, 272, width=300, height=20, window=entryXpathSubmit) # 在画布上嵌入 227 | """ 输入:代理ip的选项 """ 228 | LabelProxy = Label(self.root, text="代理设置:", font=("微软雅黑", 10), anchor="w", bg='red') 229 | LabelProxy.pack() 230 | self.canvas.create_window(380, 300, width=150, height=20, window=LabelProxy) # 在画布上嵌入 231 | entryProxy = Entry(self.root, fg="#1E90FF") 232 | entryProxy.pack() 233 | self.canvas.create_window(645, 300, width=300, height=20, window=entryProxy) # 在画布上嵌入 234 | buttonSeletFileProxy = Button(self.root, text="选择文件", font=("微软雅黑", 10), anchor="w", bg='white', command=lambda: self.commandSelectFile(entryProxy, self.proxyFile)) 235 | buttonSeletFileProxy.pack() 236 | self.canvas.create_window(767, 300, width=60, height=20, window=buttonSeletFileProxy) # 在画布上嵌入 237 | """ 输入:chromedriver设置 """ 238 | LabelChromeDriver = Label(self.root, text="chromedriver路径:", font=("微软雅黑", 10), anchor="w", bg='red') 239 | LabelChromeDriver.pack() 240 | self.canvas.create_window(380, 328, width=150, height=20, window=LabelChromeDriver) # 在画布上嵌入 241 | entryChromeDriver = Entry(self.root, fg="#1E90FF") 242 | entryChromeDriver.pack() 243 | self.canvas.create_window(645, 328, width=300, height=20, window=entryChromeDriver) # 在画布上嵌入 244 | buttonSeletFileChromedriver = Button(self.root, text="选择文件", font=("微软雅黑", 10), anchor="w", bg='white', command=lambda: self.commandSelectFile(entryChromeDriver, self.chromedriverFile)) 245 | buttonSeletFileChromedriver.pack() 246 | self.canvas.create_window(767, 328, width=60, height=20, window=buttonSeletFileChromedriver) # 在画布上嵌入 247 | 248 | 249 | def Frame7(self): 250 | """ 开始按钮、清空按钮 """ 251 | buttonStart = Button(self.root, text="开始", font=("微软雅黑", 15), bg='green', command=self.commandButtonStart) 252 | buttonStart.pack() 253 | self.canvas.create_window(680, 380, width=80, height=55, window=buttonStart) # 在画布上嵌入 254 | buttonCancel = Button(self.root, text="停止", font=("微软雅黑", 15), bg='green', command=self.commandButtonCancel) 255 | buttonCancel.pack() 256 | self.canvas.create_window(790, 380, width=80, height=55, window=buttonCancel) # 在画布上嵌入 257 | buttonClear = Button(self.root, text="清空", font=("微软雅黑", 15), bg='green', command=self.commandButtonClear) 258 | buttonClear.pack() 259 | self.canvas.create_window(900, 380, width=80, height=55, window=buttonClear) # 在画布上嵌入 260 | 261 | 262 | def frameExplain(self): 263 | """ 说明菜单栏设置 """ 264 | top = Toplevel() 265 | top.title('说明') 266 | text = Text(top, width=70, height=20, fg='red', font=("微软雅黑", 12)) 267 | text.insert("insert", "\n1、只支持chrome浏览器,官网下载:https://www.google.cn/chrome/。\n同时需要下载" 268 | "chromedrover.exe驱动,官网地址:https://chromedriver.chromium.org/downloads (注意下载相对应版本,否则工具无法运行。)\n\n" 269 | "2、遇到需有验证码登入框爆破,需要提前在config.json填好<快识别>账号密码,官网注册:http://www.kuaishibie.cn/。\n来一波推荐" 270 | "码哈哈:084a0c65a86c4cd3a812bf8f1c139aec\n\n" 271 | "3、爆破之前,先尝试登入错误5左右,观察是否会出现验证码。有的网站只有登入错误达到一定次数才会出现验证码,所以记得好好查看" 272 | "是否存在,别爆破了个寂寞。\n\n" 273 | "4、对于登入错误达到次数封ip情况,本工具支持配置自己的代理ip池进行爆破。\n\n" 274 | "5、爆破的结果保存在result.txt里。\n\n" 275 | "6、对于批量ip爆破情况,本工具自带存活检测。") 276 | text.pack() 277 | 278 | 279 | def frameAbout(self): 280 | """ 说明菜单栏设置 """ 281 | top = Toplevel() 282 | top.title('关于') 283 | text = Text(top, width=50, height=20, fg='red', font=("微软雅黑", 12)) 284 | text.insert("insert", "\n1、开发本工具是因为在渗透测试的弱口令检测阶段,遇到复杂的前端js加密情况," 285 | "分析加密过程耗时耗力,心想不如直接来个多线程的模拟登入,简单又省力,于是诞生了此工具。\n\n" 286 | "2、python语言开发,使用的selenium库, 借助chromedriver.exe模拟鼠标点击登入,无视前端的js加密,多线程" 287 | "爆破速度毫不逊色。" 288 | "\n\n3、本工具为第一版,后续版本地址:https://github.com/kracer127/seBruteGUI\n\n" 289 | "3、工具问题或有好的建议,唯一QQ:0x91b8bb99") 290 | text.pack() 291 | 292 | 293 | def commandSelectFile(self, entry, List): 294 | """ 爆破模式的选择响应事件 """ 295 | filename = tkinter.filedialog.askopenfilename() 296 | if filename != '': 297 | entry.delete(0, END) 298 | List.append(filename) 299 | entry.insert("insert", filename) 300 | else: 301 | entry.insert("insert", "") 302 | 303 | 304 | def informationProcess(self): 305 | """ 对用户的输入进行处理 """ 306 | if self.modeValue.get() != ' ': 307 | self.startFlag = True 308 | if self.threadNum.get() != None: 309 | self.threadNumFile.append(self.threadNum.get()) 310 | self.allUserInput.append(self.threadNumFile) 311 | if self.urlFile == []: 312 | if entryUrl.get() != '': 313 | self.url = entryUrl.get() 314 | self.urlFile.append(self.url.strip()) 315 | else: 316 | self.startFlag = False 317 | self.resultText.insert(END, "[-] 没有检测到<目标url>, 请重新输入后再使用!\n") 318 | tkinter.messagebox.showerror('错误', "请输入目标url !") 319 | if self.usernameFile == []: 320 | if entryUserName.get() != '': 321 | self.username = entryUserName.get() 322 | self.usernameFile.append(self.username.strip()) 323 | else: 324 | self.startFlag = False 325 | self.resultText.insert(END, "[-] 没有检测到<用户名>, 请重新输入后再使用!\n") 326 | tkinter.messagebox.showerror('错误', "请输入用户名 !") 327 | if self.passwordFile == []: 328 | if entryPassWord.get() != '': 329 | self.password = entryPassWord.get() 330 | self.passwordFile.append(self.password.strip()) 331 | else: 332 | self.startFlag = False 333 | self.resultText.insert(END, "[-] 没有检测到<密码>, 请重新输入后再使用!\n") 334 | tkinter.messagebox.showerror('错误', "请输入密码 !") 335 | if entryCaptchaUrl.get() != '': 336 | if entryXpathCaptcha.get() != '': 337 | self.captchaUrl = entryCaptchaUrl.get() 338 | self.captchaXpath = entryXpathCaptcha.get() 339 | self.captchaFile.append(self.captchaUrl.strip()) 340 | self.captchaFile.append(self.captchaXpath.strip()) 341 | else: 342 | self.startFlag = False 343 | self.resultText.insert(END, "[-] 没有检测到<验证码的xpath>, 请重新输入后再使用!\n") 344 | tkinter.messagebox.showerror('错误', "请输入验证码的xpath !") 345 | if entryXpathUserName.get() == '': 346 | self.startFlag = False 347 | self.resultText.insert(END, "[-] 没有检测到<用户名的xpath>, 请重新输入后再使用!\n") 348 | tkinter.messagebox.showerror('错误', "请输入用户名的xpath !") 349 | else: 350 | self.usernameXpath = entryXpathUserName.get() 351 | self.usernameFile.append(self.usernameXpath.strip()) 352 | if entryXpathPassWord.get() == '': 353 | self.startFlag = False 354 | self.resultText.insert(END, "[-] 没有检测到<密码的xpath>, 请重新输入后再使用!\n") 355 | tkinter.messagebox.showerror('错误', "请输入密码的xpath !") 356 | else: 357 | self.passwordXpath = entryXpathPassWord.get() 358 | self.passwordFile.append(self.passwordXpath.strip()) 359 | if entryXpathSubmit.get() == '': 360 | self.startFlag = False 361 | self.resultText.insert(END, "[-] 没有检测到<提交按钮的xpath>, 请重新输入后再使用!\n") 362 | tkinter.messagebox.showerror('错误', "请输入提交按钮的xpath !") 363 | else: 364 | self.submitXpath = entryXpathSubmit.get() 365 | self.submitFile.append(self.submitXpath.strip()) 366 | if self.proxyFile == []: 367 | if entryProxy.get() != '': 368 | self.proxy = entryProxy.get() 369 | self.proxyFile.append(self.proxy.strip()) 370 | if self.chromedriverFile == []: 371 | if entryChromeDriver.get() != '': 372 | self.chromedriver = entryChromeDriver.get() 373 | self.chromedriverFile.append(self.chromedriver) 374 | else: 375 | self.startFlag = False 376 | self.resultText.insert(END, "[-] 没有检测到, 请重新输入后再使用!\n") 377 | tkinter.messagebox.showerror('错误', "请配置chromedrover.exe路径 !") 378 | else: 379 | self.startFlag = False 380 | tkinter.messagebox.showerror('错误', "请选择爆破模式!") 381 | 382 | 383 | def informationResult(self): 384 | """ 用户输入的最终处理结果 """ 385 | try: 386 | self.allUserInput.append(self.urlFile) 387 | self.allUserInput.append(self.usernameFile) 388 | self.allUserInput.append(self.passwordFile) 389 | self.allUserInput.append(self.captchaFile) 390 | self.allUserInput.append(self.submitFile) 391 | self.allUserInput.append(self.proxyFile) 392 | self.allUserInput.append(self.chromedriverFile) 393 | except Exception as e: 394 | self.resultText.insert(END, "\033[1;31m[-] 处理用户的输入过程出错, 建议重启软件!\033[0m\n") 395 | 396 | 397 | def commandButtonStart(self): 398 | """ 按下开始按钮后的响应事件 """ 399 | global threadStopFlag 400 | self.informationProcess() # 提前判断用户的输入 401 | if self.startFlag == True: 402 | self.informationResult() 403 | choiceMode = self.modeValue.get() 404 | tkinter.messagebox.showinfo('提示', "初始化成功,爆破任务开启!") 405 | self.resultText.delete(0.0, END) 406 | threadStopFlag = False 407 | if choiceMode == 'mode1': 408 | """ 如果是爆破模式一 """ 409 | sunpro1 = Thread(target=processOneIp(self.resultText, self.allUserInput).startMoreThread()) 410 | sunpro1.setDaemon(True) 411 | sunpro1.start() 412 | else: 413 | """ 如果是爆破模式二 """ 414 | sunpro2 = Thread(target=processManyIp(self.resultText, self.allUserInput).startMoreThread()) 415 | sunpro2.setDaemon(True) 416 | sunpro2.start() 417 | """ 清空数据列表,方便下一次的重载 """ 418 | self.threadNumFile.clear() 419 | self.urlFile.clear() 420 | self.usernameFile.clear() 421 | self.passwordFile.clear() 422 | self.captchaFile.clear() 423 | self.submitFile.clear() 424 | self.proxyFile.clear() 425 | self.chromedriverFile.clear() 426 | self.allUserInput.clear() 427 | else: 428 | self.threadNumFile.clear() 429 | self.urlFile.clear() 430 | self.usernameFile.clear() 431 | self.passwordFile.clear() 432 | self.captchaFile.clear() 433 | self.submitFile.clear() 434 | self.proxyFile.clear() 435 | self.chromedriverFile.clear() 436 | self.allUserInput.clear() 437 | 438 | 439 | def commandButtonCancel(self): 440 | global threadStopFlag 441 | try: 442 | threadStopFlag = True 443 | tkinter.messagebox.showinfo('提示', "正在停止爆破任务!") 444 | """ 清空所有数据 """ 445 | self.threadNumFile.clear() 446 | self.urlFile.clear() 447 | self.usernameFile.clear() 448 | self.passwordFile.clear() 449 | self.captchaFile.clear() 450 | self.submitFile.clear() 451 | self.proxyFile.clear() 452 | self.chromedriverFile.clear() 453 | self.allUserInput.clear() 454 | except Exception as e: 455 | self.startFlag = False 456 | self.resultText.insert(END, "[-] 停止任务出错,建议重启后再使用!\n") 457 | tkinter.messagebox.showerror('错误', "停止任务出错!") 458 | 459 | 460 | def commandButtonClear(self): 461 | try: 462 | entryUrl.delete(0, END) 463 | entryUserName.delete(0, END) 464 | entryPassWord.delete(0, END) 465 | entryCaptchaUrl.delete(0, END) 466 | entryXpathUserName.delete(0, END) 467 | entryXpathPassWord.delete(0, END) 468 | entryXpathCaptcha.delete(0, END) 469 | entryXpathSubmit.delete(0, END) 470 | except Exception as e: 471 | self.startFlag = False 472 | self.resultText.insert(END, "[-] 清空输入数据出错,建议重启后再使用!\n") 473 | tkinter.messagebox.showerror('提示', "清空输入数据出错!") 474 | 475 | 476 | GUI().run() 477 | 478 | 479 | if not os.path.exists("result.txt"): 480 | with open("result.txt", 'a+', encoding='utf-8') as f1: 481 | text = '很遗憾,没有一个爆破成功!' 482 | f1.write(text) -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /common.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # Date: 2021-11-14 3 | # Author:kracer 4 | # Version: 1.0 5 | 6 | 7 | import base64 8 | import json 9 | import ctypes 10 | import inspect 11 | import os, time 12 | from queue import Queue 13 | from concurrent.futures import ThreadPoolExecutor 14 | import requests 15 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 16 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 17 | 18 | 19 | 20 | """ 变量部分 """ 21 | successList = [] 22 | captcha = [] 23 | proxy = [] 24 | chromePath = [] 25 | threadStopFlag = False 26 | 27 | 28 | if os.path.exists("config.json"): 29 | with open('config.json', 'r') as f: 30 | data = json.loads(f.read()) 31 | captcha += data['captcha'] 32 | proxy += data['proxy'] 33 | chromePath += data["chromePath"] 34 | 35 | 36 | def processUrl(url0): 37 | """ 对url的预处理 """ 38 | if 'http' not in url0: 39 | url = 'http://'+url0 40 | else: 41 | url = url0 42 | return url 43 | 44 | 45 | def getFileDatas(filepath): 46 | """ 从文件中读取数据 """ 47 | dataList = [] 48 | try: 49 | with open(filepath, 'r', encoding='utf-8') as f: 50 | datas = f.readlines() 51 | for i in datas: 52 | dataList.append(i.strip()) 53 | return dataList 54 | except Exception as e: 55 | return [] 56 | 57 | 58 | def isManyAlive(result, ipList): 59 | """ 检测是否ip存活 """ 60 | isAlivePool = ThreadPoolExecutor(max_workers=50, thread_name_prefix="browser") 61 | ipQueue = Queue() 62 | sumIp = len(ipList) 63 | for u in ipList: 64 | ipQueue.put_nowait(u) 65 | """ 输出 """ 66 | msg ='[+] IP存活检测,ALL: {0} | Thread: 50 | Schedule: 1min......'.format(sumIp) 67 | result.insert("end", str(msg)+'\n') 68 | """ 通过request请求的反应来判断ip是否存活 """ 69 | def request(url): 70 | try: 71 | res = requests.get(url=url, timeout=10, allow_redirects=True, verify=False) 72 | except Exception as e: 73 | ipList.remove(url) 74 | """ 多线程判断ip存活情况 """ 75 | while not ipQueue.empty(): 76 | url = ipQueue.get_nowait() 77 | isAlivePool.submit(request, url) 78 | isAlivePool.shutdown(wait=True) # 等待所有检测完毕才进行下一步 79 | return ipList 80 | 81 | 82 | def codeShiBie(url, result): 83 | '''函数:验证码识别''' 84 | if captcha[0] != '': 85 | user = captcha[0] 86 | passwd = captcha[1] 87 | try: 88 | getImgBytes = requests.get(url=url, timeout=6, allow_redirects=True, verify=False) # 请求获取验证码二进制数据 89 | base64Data = base64.b64encode(getImgBytes.content) 90 | b64 = base64Data.decode() 91 | data = {"username": user, "password": passwd, "typeid": 3, "image": b64} 92 | result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text) 93 | if result['success']: 94 | code = result["data"]["result"] # 获取识别后的验证码 95 | if (len(code) == 4) or (len(code) == 6): # 进一步提升识别率,限制识别出的字符在4个以内 96 | return code 97 | else: 98 | codeShiBie(url, result) 99 | else: 100 | codeShiBie(url, result) 101 | except Exception as f: 102 | result.config(fg='red') 103 | result.insert("end", "\033[1;31m[-] 验证码识别模块失败,请检查配置文件!\033[0m\n") 104 | return '' 105 | else: 106 | result.config(fg='red') 107 | result.insert("end", "\033[1;31m[-] 验证码识别模块失败,请检查配置文件!\033[0m\n") 108 | return '' 109 | 110 | 111 | def resultOutput(result): 112 | """ 生成结果文件 """ 113 | with open('result.txt', 'a+', encoding="utf-8") as f: 114 | if len(result) != 0: 115 | f.write(result+"\n") 116 | else: 117 | msg = "很遗憾,没有一个爆破成功!" 118 | f.write(msg) 119 | 120 | 121 | def _async_raise(tid, exctype): 122 | if not inspect.isclass(exctype): 123 | raise TypeError("Only types can be raised (not instances)") 124 | res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype)) 125 | if res == 0: 126 | raise ValueError("invalid thread id") 127 | elif res != 1: 128 | ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None) 129 | raise SystemError("PyThreadState_SetAsyncExc failed") 130 | 131 | 132 | def stop_thread(thread): 133 | _async_raise(thread.ident, SystemExit) 134 | 135 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "captcha": ["",""], 3 | "proxy": [""], 4 | "chromePath": [""] 5 | } -------------------------------------------------------------------------------- /imgs/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kracer127/SeBruteGUI/bc7eff3cb57fe33a7bc960b9b90463145c45b8c7/imgs/background.gif -------------------------------------------------------------------------------- /imgs/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kracer127/SeBruteGUI/bc7eff3cb57fe33a7bc960b9b90463145c45b8c7/imgs/icon.ico -------------------------------------------------------------------------------- /imgs/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kracer127/SeBruteGUI/bc7eff3cb57fe33a7bc960b9b90463145c45b8c7/imgs/open.png -------------------------------------------------------------------------------- /imgs/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kracer127/SeBruteGUI/bc7eff3cb57fe33a7bc960b9b90463145c45b8c7/imgs/run.png -------------------------------------------------------------------------------- /imgs/selenium.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kracer127/SeBruteGUI/bc7eff3cb57fe33a7bc960b9b90463145c45b8c7/imgs/selenium.jpg -------------------------------------------------------------------------------- /processManyIp.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # Date: 2021-11-15 3 | # Author:kracer 4 | # Version: 1.0 5 | 6 | # -*- coding:utf-8 -*- 7 | # Date: 2021-11-14 8 | # Author:kracer 9 | # Version: 1.0 10 | 11 | import time 12 | import os 13 | from selenium import webdriver 14 | from queue import Queue 15 | import threading as th 16 | from common import * 17 | from selenium.webdriver.common.by import By 18 | from selenium.webdriver.support.ui import WebDriverWait 19 | from selenium.webdriver.support import expected_conditions as EC 20 | from concurrent.futures import ThreadPoolExecutor 21 | 22 | 23 | class processManyIp: 24 | def __init__(self, result, userInputList): 25 | self.result = result # 输出变量 26 | self.proxyList = [] 27 | self.success = {} 28 | self.processList(userInputList) 29 | self.proxyFlag = True 30 | self.startBruteFlag = True 31 | self.tryTimes = 3 32 | self.captcha = '' 33 | self.ipQueue = Queue() 34 | self.userQueue = Queue() 35 | self.passQueue = Queue() 36 | self.proxyQueue = Queue() 37 | self.chromeQueue = Queue() 38 | 39 | 40 | def processList(self, List): 41 | """ 对给的数据列表进行预处理 """ 42 | self.threadNum = List[0][0] # 获取线程数 43 | if os.path.isfile(List[1][0]): # 如果输入的是文件 44 | ipList = [] 45 | tmpUserList = getFileDatas(List[1][0]) 46 | for u in tmpUserList: 47 | ipList.append(processUrl(u)) 48 | self.ipList = isManyAlive(self.result, ipList) 49 | else: 50 | self.ipList = [List[1][0]] 51 | if ":" in List[2][0]: # 如果输入的是文件 52 | self.userList = getFileDatas(List[2][0]) 53 | self.xpathUser = List[2][1] 54 | else: 55 | self.userList = [List[2][0]] 56 | self.xpathUser = List[2][1] 57 | if ":" in List[3][0]: # 如果输入的是文件 58 | self.passList = getFileDatas(List[3][0]) 59 | self.xpathPass = List[3][1] 60 | else: 61 | self.passList = [List[3][0]] 62 | self.xpathPass = List[3][1] 63 | if List[4] != []: 64 | if ":" in List[4][0]: 65 | self.captchaUrl = processUrl(List[4][0]) 66 | self.xpathCaptcha = List[4][1] 67 | else: 68 | self.captchaUrl = '' 69 | if List[5] != []: 70 | self.xpathSubmit = List[5][0] 71 | if List[6] != []: 72 | if os.path.isfile(List[6][0]): # 如果输入的是文件 73 | tmpProxy = getFileDatas(List[6][0]) 74 | for p in tmpProxy: 75 | self.proxyList.append(processUrl(p)) 76 | else: 77 | self.proxyList = [List[6][0]] 78 | if List[7] != []: 79 | self.chromePath = List[7][0] 80 | 81 | 82 | def init(self, proxy): 83 | """ 对chromedriver的初始化设置 """ 84 | options = webdriver.ChromeOptions() 85 | options.add_argument('lang=zh_CN.UTF-8') # 设置中文 86 | options.add_argument('user-agent="Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20"') # 更换头部 87 | options.add_argument('--ignore-certificate-errors') # 解决https安全问题,忽视并继续操作 88 | options.add_argument('--blink-settings=imagesEnabled=false') # 不加载图片, 提升速度 89 | options.add_argument('--headless') # 浏览器不提供可视化页面 90 | options.add_argument('--disable-gpu') # 加上这个属性来规避bug 91 | options.add_experimental_option('excludeSwitches', ['enable-automation']) # 模拟正常浏览器,反爬虫 92 | if proxy != ' ': 93 | options.add_argument('--proxy-server=%s' % proxy) 94 | browser = webdriver.Chrome(self.chromePath, chrome_options=options) 95 | return browser 96 | 97 | 98 | def addQueue(self, List, Queue): 99 | """ 给队列添加数据 """ 100 | try: 101 | for i in List: 102 | Queue.put_nowait(i) 103 | except Exception as e: 104 | print(e) 105 | 106 | 107 | def addChromeQueue(self, num, Queue): 108 | """ 添加chrome队列数值 """ 109 | for i in range(num): 110 | if not self.proxyQueue.empty(): 111 | Queue.put_nowait(self.init(self.proxyQueue.get_nowait())) 112 | else: 113 | self.proxyFlag = False 114 | proxy = ' ' 115 | Queue.put_nowait(self.init(proxy)) 116 | 117 | 118 | def quitChrome(self): 119 | """ 停掉所有的chrome """ 120 | while not self.chromeQueue.empty(): 121 | chrome = self.chromeQueue.get_nowait() 122 | chrome.quit() 123 | 124 | 125 | def startMoreThread(self): 126 | self.addQueue(self.ipList, self.ipQueue) 127 | if self.proxyList != []: 128 | self.addQueue(self.proxyList, self.proxyQueue) 129 | self.addChromeQueue(self.threadNum, self.chromeQueue) 130 | """ 开启多线程 """ 131 | threadPool = ThreadPoolExecutor(max_workers=self.threadNum, thread_name_prefix="browser") 132 | self.result.insert("end", "[+] 初始化成功,努力打开网页中,给我点时间......\n") 133 | self.result.see("end") 134 | while not self.ipQueue.empty(): 135 | url = self.ipQueue.get_nowait() 136 | for userName in self.userList: 137 | for passWord in self.passList: 138 | self.success.setdefault(userName, False) 139 | threadPool.submit(self.run, url, userName, passWord) 140 | 141 | 142 | def run(self, url, userName, passWord): 143 | """ 开始提交表单进行爆破 """ 144 | if threadStopFlag == False: 145 | if self.success[userName] == False: 146 | browser = self.chromeQueue.get_nowait() 147 | try: 148 | browser.get(url) 149 | self.startBruteFlag = True 150 | except Exception as e: 151 | if "ERR_PROXY_CONNECTION_FAILED" in str(e): 152 | self.startBruteFlag = False 153 | browser.close() 154 | browser.quit() 155 | self.result.insert("end", "[-] {0} 当前代理无法建立连接, 正在尝试更换代理!\n".format(th.current_thread().name)) 156 | self.result.see("end") 157 | self.addChromeQueue(1, self.chromeQueue) 158 | self.run(url, userName, passWord) 159 | else: 160 | self.startBruteFlag = False 161 | self.chromeQueue.put_nowait(browser) 162 | if self.startBruteFlag: 163 | try: 164 | ''' 等待chrome浏览器的加载完成 ''' 165 | element = WebDriverWait(browser, 8).until(EC.presence_of_element_located((By.XPATH, self.xpathSubmit))) 166 | # 获取未登入成功前的url地址 167 | noLoginUrl = browser.current_url 168 | # 移除用户名和密码前后的空格和换行符!!!(必要操作) 169 | putUser = userName.strip() 170 | putPasswd = passWord.strip() 171 | # 先清空输入栏已存在的用户名和密码 172 | browser.find_element_by_xpath(self.xpathUser).clear() 173 | browser.find_element_by_xpath(self.xpathPass).clear() 174 | # 自动输入用户名密码 175 | browser.find_element_by_xpath(self.xpathUser).send_keys(putUser) 176 | browser.find_element_by_xpath(self.xpathPass).send_keys(putPasswd) 177 | if self.captchaUrl != '': 178 | self.captcha = codeShiBie(self.captchaUrl, self.result) 179 | try: 180 | """ 解决登入错误达到一定次数后才出现验证码的情况 """ 181 | browser.find_element_by_xpath(self.xpathCaptcha).send_keys(self.captcha) 182 | except Exception as e3: 183 | pass 184 | # 自动点击登录按钮 185 | browser.find_element_by_xpath(self.xpathSubmit).click() 186 | time.sleep(2) 187 | self.result.insert("end", '[+] 线程{0}, 目前爆破进度到:{1} -- {2}:{3}\n'.format(th.current_thread().name, url, putUser, putPasswd)) 188 | self.result.see("end") 189 | # 获取点击登入后的url地址,判断是否登入成功 190 | loginUrl = browser.current_url 191 | if noLoginUrl != loginUrl: 192 | self.success[userName] = True 193 | result = "{0} 爆破成功: 用户名:{1} --- 密码:{2}".format(url, putUser, putPasswd) 194 | self.result.insert("end", "[+] {0}\n".format(result)) 195 | self.result.see("end") 196 | successList.append(result) 197 | """ 生成结果文件 """ 198 | resultOutput(result) 199 | browser.execute_script("location.reload()") 200 | self.chromeQueue.put_nowait(browser) 201 | except Exception as e2: 202 | self.chromeQueue.put_nowait(browser) 203 | if self.tryTimes > 0: 204 | self.result.insert("end", '[-] {0} 未检测到xpath元素, 检测输入的xpath路径是否正确!\n'.format(url)) 205 | self.result.see("end") 206 | self.tryTimes -= 1 207 | self.run(url, userName, passWord) 208 | else: 209 | stop_thread(th.current_thread()) 210 | else: 211 | stop_thread(th.current_thread()) 212 | else: 213 | self.quitChrome() 214 | stop_thread(th.current_thread()) 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /processOneIp.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # Date: 2021-11-14 3 | # Author:kracer 4 | # Version: 1.0 5 | 6 | import time 7 | from selenium import webdriver 8 | from queue import Queue 9 | import threading as th 10 | from common import * 11 | from selenium.webdriver.common.by import By 12 | from selenium.webdriver.support.ui import WebDriverWait 13 | from selenium.webdriver.support import expected_conditions as EC 14 | from concurrent.futures import ThreadPoolExecutor 15 | 16 | class processOneIp: 17 | def __init__(self, result, userInputList): 18 | self.result = result # 输出变量 19 | self.success = {} 20 | self.successList = [] 21 | self.proxyList = [] 22 | self.tryTimes = 3 # 打开ip失败次数 23 | self.tryTimes1 = 3 # 未检测到xpath失败次数 24 | self.processList(userInputList) 25 | self.proxyFlag = True 26 | self.startBruteFlag = True 27 | self.captcha = '' 28 | self.ipQueue = Queue() 29 | self.userQueue = Queue() 30 | self.passQueue = Queue() 31 | self.proxyQueue = Queue() 32 | self.chromeQueue = Queue() 33 | 34 | 35 | def processList(self, List): 36 | """ 对给的数据列表进行预处理 """ 37 | self.threadNum = List[0][0] # 获取线程数 38 | self.ip = processUrl(List[1][0]) 39 | if ":" in List[2][0]: # 如果输入的是文件 40 | self.userList = getFileDatas(List[2][0]) 41 | self.xpathUser = List[2][1] 42 | else: 43 | self.userList = [List[2][0]] 44 | self.xpathUser = List[2][1] 45 | if ":" in List[3][0]: # 如果输入的是文件 46 | self.passList = getFileDatas(List[3][0]) 47 | self.xpathPass = List[3][1] 48 | else: 49 | self.passList = [List[3][0]] 50 | self.xpathPass = List[3][1] 51 | if List[4] != []: 52 | if ":" in List[4][0]: 53 | self.captchaUrl = List[4][0] 54 | self.xpathCaptcha = List[4][1] 55 | else: 56 | self.captchaUrl = '' 57 | if List[5] != []: 58 | self.xpathSubmit = List[5][0] 59 | if List[6] != []: 60 | if os.path.isfile(List[6][0]): # 如果输入的是文件 61 | tmpProxy = getFileDatas(List[6][0]) 62 | for p in tmpProxy: 63 | self.proxyList.append(processUrl(p)) 64 | else: 65 | self.proxyList = [List[6][0]] 66 | else: 67 | self.proxyList = [] 68 | if List[7] != []: 69 | self.chromePath = List[7][0] 70 | 71 | 72 | def init(self, proxy): 73 | """ 对chromedriver的初始化设置 """ 74 | options = webdriver.ChromeOptions() 75 | options.add_argument('lang=zh_CN.UTF-8') # 设置中文 76 | options.add_argument('user-agent="Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20"') # 更换头部 77 | options.add_argument('--ignore-certificate-errors') # 解决https安全问题,忽视并继续操作 78 | options.add_argument('--blink-settings=imagesEnabled=false') # 不加载图片, 提升速度 79 | options.add_argument('--headless') # 浏览器不提供可视化页面 80 | options.add_argument('--disable-gpu') # 加上这个属性来规避bug 81 | options.add_experimental_option('excludeSwitches', ['enable-automation']) # 模拟正常浏览器,反爬虫 82 | if proxy != '': 83 | options.add_argument('--proxy-server=%s' % proxy) 84 | browser = webdriver.Chrome(self.chromePath, chrome_options=options) 85 | return browser 86 | 87 | 88 | def addQueue(self, List, Queue): 89 | """ 给队列添加数据 """ 90 | try: 91 | for i in List: 92 | Queue.put_nowait(i) 93 | except Exception as e: 94 | pass 95 | 96 | 97 | def addChromeQueue(self, num, Queue): 98 | """ 添加chrome队列数值 """ 99 | for i in range(num): 100 | if not self.proxyQueue.empty(): 101 | Queue.put_nowait(self.init(self.proxyQueue.get_nowait())) 102 | else: 103 | self.proxyFlag = False 104 | proxy = '' 105 | Queue.put_nowait(self.init(proxy)) 106 | 107 | 108 | def quitChrome(self): 109 | """ 退出所用chrome """ 110 | while not self.chromeQueue.empty(): 111 | chrome = self.chromeQueue.get_nowait() 112 | chrome.quit() 113 | 114 | 115 | def startMoreThread(self): 116 | self.addQueue(self.userList, self.userQueue) 117 | if self.proxyList != []: 118 | self.addQueue(self.proxyList, self.proxyQueue) 119 | self.addChromeQueue(self.threadNum, self.chromeQueue) 120 | """ 开启多线程 """ 121 | threadPool = ThreadPoolExecutor(max_workers=self.threadNum, thread_name_prefix="browser") 122 | self.result.insert("end", "[*] 初始化成功,努力打开网页中,给我点时间......\n") 123 | self.result.see("end") 124 | while not self.userQueue.empty(): 125 | userName = self.userQueue.get_nowait() 126 | for passWord in self.passList: 127 | self.success.setdefault(userName, False) 128 | threadPool.submit(self.run, userName, passWord) 129 | 130 | 131 | def run(self, userName, passWord): 132 | """ 开始提交表单进行爆破 """ 133 | if threadStopFlag == False: 134 | if self.success[userName] == False: 135 | browser = self.chromeQueue.get_nowait() 136 | try: 137 | browser.get(self.ip) 138 | self.startBruteFlag = True 139 | except Exception as e: 140 | self.startBruteFlag = False 141 | browser.quit() 142 | if self.tryTimes > 0: 143 | self.tryTimes -= 1 144 | self.result.insert("end", "[-] {0} 当前代理无法建立连接, 正在尝试更换代理!\n".format(th.current_thread().name)) 145 | self.result.see("end") 146 | self.addChromeQueue(1, self.chromeQueue) 147 | self.run(userName, passWord) 148 | else: 149 | stop_thread(th.current_thread()) 150 | if self.startBruteFlag: 151 | try: 152 | ''' 等待chrome浏览器的加载完成 ''' 153 | element = WebDriverWait(browser, 8).until(EC.presence_of_element_located((By.XPATH, self.xpathSubmit))) 154 | # 获取未登入成功前的url地址 155 | noLoginUrl = browser.current_url 156 | # 移除用户名和密码前后的空格和换行符!!!(必要操作) 157 | putUser = userName.strip() 158 | putPasswd = passWord.strip() 159 | # 先清空输入栏已存在的用户名和密码 160 | browser.find_element_by_xpath(self.xpathUser).clear() 161 | browser.find_element_by_xpath(self.xpathPass).clear() 162 | # 自动输入用户名密码 163 | browser.find_element_by_xpath(self.xpathUser).send_keys(putUser) 164 | browser.find_element_by_xpath(self.xpathPass).send_keys(putPasswd) 165 | if self.captchaUrl != '': 166 | self.captcha = codeShiBie(self.captchaUrl, self.result) 167 | try: 168 | """ 解决登入错误达到一定次数后才出现验证码的情况 """ 169 | browser.find_element_by_xpath(self.xpathCaptcha).send_keys(self.captcha) 170 | except Exception as e3: 171 | pass 172 | # 自动点击登录按钮 173 | browser.find_element_by_xpath(self.xpathSubmit).click() 174 | time.sleep(2) 175 | self.result.insert("end", '[+] 线程{0}, 目前爆破进度到:{1} -- {2}:{3}\n'.format(th.current_thread().name, self.ip, putUser, putPasswd)) 176 | self.result.see("end") 177 | # 获取点击登入后的url地址,判断是否登入成功 178 | loginUrl = browser.current_url 179 | if noLoginUrl != loginUrl: 180 | result = "{0} 爆破成功: 用户名:{1} --- 密码:{2}".format(self.ip, putUser, putPasswd) 181 | self.result.insert("end", "[+] {0}\n".format(result)) 182 | self.result.see("end") 183 | self.successList.append(result) 184 | """ 生成结果文件 """ 185 | resultOutput(result) 186 | browser.execute_script("location.reload()") 187 | self.chromeQueue.put_nowait(browser) 188 | except Exception as e1: 189 | self.chromeQueue.put_nowait(browser) 190 | if self.tryTimes1 > 0: 191 | self.tryTimes1 -= 1 192 | self.result.insert("end", '[-] {0} 未检测到xpath元素, 请检查输入的xpath路径是否正确!\n'.format(th.current_thread().name)) 193 | self.result.see("end") 194 | self.run(userName, passWord) 195 | else: 196 | stop_thread(th.current_thread()) 197 | else: 198 | stop_thread(th.current_thread()) 199 | else: 200 | self.quitChrome() 201 | stop_thread(th.current_thread()) 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | gevent 3 | selenium 4 | 5 | 6 | --------------------------------------------------------------------------------