├── 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 |
6 |
7 |
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 |
54 |
55 | **2、程序运行:**
56 |
57 |
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 |
--------------------------------------------------------------------------------