1+ #!/usr/bin/env python3
2+ from tkinter import Tk ,Entry ,Label ,StringVar ,Frame ,Checkbutton ,Button ,IntVar
3+ from string import punctuation ,digits ,ascii_lowercase ,ascii_uppercase
4+ from tkinter .messagebox import showwarning ,showinfo
5+ from tkinter .filedialog import askopenfilename
6+ from hashlib import algorithms_available ,new
7+ from tkinter .ttk import Progressbar ,Combobox
8+ from os .path import exists
9+ from itertools import product
10+ from threading import Thread
11+ from time import sleep
12+ from sys import exit
13+ __author__ = "Vahab Programmer https://github.com/Vahab-Programmer"
14+ __version__ = "0.0.1"
15+ class GHBruter :
16+ __alive = True
17+ __talive = True
18+ __hashedt = ""
19+ __currentt = ""
20+ __hashedc = 0
21+ __counter = 0
22+ __total = 0
23+ __tcount = None
24+ __progack = False
25+ def __init__ (self ):
26+ root = Tk ()
27+ self .__root = root
28+ root .title ("GHB" )
29+ #root.resizable(False,False)
30+ root .minsize (217 ,207 )
31+ root .rowconfigure (list (range (5 )),weight = 1 )
32+ root .columnconfigure (list (range (2 )),weight = 1 )
33+ self .__center (root )
34+ self .__wordlist = StringVar ()
35+ Label (root ,text = "Target Hash*" ,relief = "raised" ).grid (column = 0 ,row = 0 ,sticky = "NSEW" )
36+ Label (root ,text = "Hash Type*" ,relief = "raised" ).grid (column = 0 ,row = 1 ,sticky = "NSEW" )
37+ thash = Combobox (root ,values = sorted (algorithms_available ),state = "readonly" )
38+ self .__thash = thash
39+ self .__hash = StringVar ()
40+ thash .set ("Select Target Hash" )
41+ Entry (root ,textvariable = self .__hash ).grid (column = 1 ,row = 0 ,sticky = "NSEW" )
42+ Entry (root ,textvariable = self .__wordlist ).grid (column = 1 ,row = 2 ,sticky = "NSEW" )
43+ Button (root , text = "Wordlist" ,command = lambda :self .__wordlist .set (askopenfilename (title = "Select Wordlist or Dictionary" ))).grid (column = 0 , row = 2 , sticky = "NSEW" )
44+ frame = Frame (root )
45+ frame .rowconfigure (list (range (2 )),weight = 1 )
46+ frame .columnconfigure (list (range (2 )),weight = 1 )
47+ self .__min = IntVar (frame )
48+ self .__max = IntVar (frame )
49+ self .__upper = IntVar (frame )
50+ self .__lower = IntVar (frame )
51+ self .__symbol = IntVar (frame )
52+ self .__digit = IntVar (frame )
53+ Checkbutton (frame ,text = "UpperCase" ,variable = self .__upper ,offvalue = 0 ,onvalue = 1 ).grid (column = 0 ,row = 0 ,sticky = "NSEW" )
54+ Checkbutton (frame ,text = "LowerCase" ,variable = self .__lower ,offvalue = 0 ,onvalue = 1 ).grid (column = 1 ,row = 0 ,sticky = "NSEW" )
55+ Checkbutton (frame ,text = "Symbol's" ,variable = self .__symbol ,offvalue = 0 ,onvalue = 1 ).grid (column = 0 ,row = 1 ,sticky = "NSEW" )
56+ Checkbutton (frame ,text = "Digit's" ,variable = self .__digit ,offvalue = 0 ,onvalue = 1 ).grid (column = 1 ,row = 1 ,sticky = "NSEW" )
57+ Label (frame ,text = "Min Length*" ,relief = "raised" ).grid (column = 0 ,row = 3 ,sticky = "NSEW" )
58+ Label (frame ,text = "Max Length*" ,relief = "raised" ).grid (column = 0 ,row = 4 ,sticky = "NSEW" )
59+ Entry (frame ,textvariable = self .__min ).grid (column = 1 ,row = 3 ,sticky = "NSEW" )
60+ Entry (frame ,textvariable = self .__max ).grid (column = 1 ,row = 4 ,sticky = "NSEW" )
61+ thash .grid (column = 1 ,row = 1 ,sticky = "NSEW" )
62+ frame .grid (column = 0 ,row = 3 ,columnspan = 2 ,sticky = "NSEW" )
63+ Button (root ,text = "Crack The Hash" ,command = self .__start ).grid (column = 0 ,row = 4 ,sticky = "NSEW" ,columnspan = 2 )
64+ Label (root ,text = "* Starred Field's Are Required!" ,relief = "raised" ).grid (column = 0 ,row = 5 ,sticky = "NSEW" ,columnspan = 2 )
65+ root .mainloop ()
66+ def __destroy (self )-> None :
67+ self .__alive = False
68+ self .__talive = False
69+ self .__tlog .join ()
70+ if self .__tcount :self .__tcount .join ()
71+ if self .__progack :
72+ self .__progack = False
73+ self .__progbar .stop ()
74+ self .__iroot .destroy ()
75+ self .__root .deiconify ()
76+ def __start (self )-> None :
77+ if not self .__hash .get ():showwarning ("Warning" ,"Hash Field is Required!" );return
78+ if self .__thash .get () == "Select Target Hash" :showwarning ("Warning" ,"You Need To Select The Hash Type!" );return
79+ if not self .__upper .get () and not self .__lower .get () and not self .__symbol .get () and not self .__digit .get () and not self .__wordlist .get ():showwarning ("Warning" ,"At Least You Have To Enable A Check Button or Select a Wordlist" );return
80+ if self .__min .get () < 1 and not exists (self .__wordlist .get ()):showwarning ("Warning" ,"min Field Cannot Be Under 1" );return
81+ if self .__max .get () < 1 and not exists (self .__wordlist .get ()):showwarning ("Warning" ,"max Field Cannot Be Under 1" );return
82+ if self .__max .get () < self .__min .get () and not exists (self .__wordlist .get ()):showwarning ("Warning" ,"min field cannot Be Bigger Than max field" );return
83+ if self .__max .get ()== self .__min .get () and not exists (self .__wordlist .get ()):showwarning ("Warning" ,"min and max field cannot be The Same" );return
84+ self .__hashlen = len (self .__hash .get ())
85+ data = ""
86+ if self .__upper .get ():data += ascii_uppercase
87+ if self .__lower .get ():data += ascii_lowercase
88+ if self .__digit .get ():data += digits
89+ if self .__symbol .get ():data += punctuation
90+ self .__hashname = self .__thash .get ()
91+ if self .__hashname == "shake_128" or self .__hashname == "shake_256" :self .__hashfunc = self .__hwl
92+ else :self .__hashfunc = self .__hwol
93+ self .__total = 0
94+ if self .__max .get ()> self .__min .get ():self .__total += self .__apc (data )
95+ self .__data = data
96+ self .__root .withdraw ()
97+ root = Tk ()
98+ self .__iroot = root
99+ root .wm_protocol ("WM_DELETE_WINDOW" ,self .__destroy )
100+ self .__center (root )
101+ root .title ("Info" )
102+ root .rowconfigure (list (range (6 )),weight = 1 )
103+ root .columnconfigure (list (range (2 )),weight = 1 )
104+ self .__tot = IntVar (root ,value = self .__total )
105+ self .__generated = IntVar (root )
106+ self .__remaining = IntVar (root )
107+ self .__current = StringVar (root )
108+ self .__hashed = StringVar (root )
109+ self .__speed = StringVar (root )
110+ Label (root ,text = "Total" ,relief = "raised" ).grid (column = 0 ,row = 0 ,sticky = "NSEW" )
111+ Entry (root ,textvariable = self .__tot ,state = "readonly" ).grid (column = 1 ,row = 0 ,sticky = "NSEW" )
112+ Label (root ,text = "Generated" ,relief = "raised" ).grid (column = 0 ,row = 1 ,sticky = "NSEW" )
113+ Entry (root ,textvariable = self .__generated ,state = "readonly" ).grid (column = 1 ,row = 1 ,sticky = "NSEW" )
114+ Label (root ,text = "Remaining" ,relief = "raised" ).grid (column = 0 ,row = 2 ,sticky = "NSEW" )
115+ Entry (root ,textvariable = self .__remaining ,state = "readonly" ).grid (column = 1 ,row = 2 ,sticky = "NSEW" )
116+ Label (root ,text = "Current" ,relief = "raised" ).grid (column = 0 ,row = 3 ,sticky = "NSEW" )
117+ Entry (root ,textvariable = self .__current ,state = "readonly" ).grid (column = 1 ,row = 3 ,sticky = "NSEW" )
118+ Label (root ,text = "Hashed" ,relief = "raised" ).grid (column = 0 ,row = 4 ,sticky = "NSEW" )
119+ Entry (root ,textvariable = self .__hashed ,state = "readonly" ).grid (column = 1 ,row = 4 ,sticky = "NSEW" )
120+ Label (root ,text = "Speed" ,relief = "raised" ).grid (column = 0 ,row = 5 ,sticky = "NSEW" )
121+ Entry (root ,textvariable = self .__speed ,state = "readonly" ).grid (column = 1 ,row = 5 ,sticky = "NSEW" )
122+ self .__progbar = Progressbar (root )
123+ self .__progbar .grid (column = 0 ,row = 6 ,columnspan = 2 ,sticky = "EW" )
124+ self .__tcrack = Thread (target = self .__cracker )
125+ self .__tcrack .start ()
126+ root .mainloop ()
127+ @staticmethod
128+ def __center (win :Tk )-> None :win .update ();win .geometry ("+{}+{}" .format ((win .winfo_screenwidth ()// 2 )- (win .winfo_width ()// 2 ),(win .winfo_screenheight ()// 2 )- (win .winfo_height ()// 2 )))
129+ @staticmethod
130+ def __hwol (hname :str ,data :bytes )-> str :return new (hname ,data ).hexdigest ()
131+ def __hwl (self ,hname :str ,data :bytes )-> str :return new (hname ,data ).hexdigest (self .__hashlen )
132+ def __apc (self ,data :str )-> int :
133+ count = 0
134+ for length in range (self .__min .get (),self .__max .get ()+ 1 ):
135+ count += len (data )** length
136+ return count
137+ @staticmethod
138+ def __divider (num :int )-> str :
139+ if num < 1000 :return "{} H/s" .format (num )
140+ if 1000 < num < 1000000 :return "{} Kh/s" .format (num / 1000 )
141+ if 1000000 < num < 1000000000 :return "{} Mh/s" .format (num / 1000000 )
142+ return "{} Gh/s" .format (num / 1000000000 )
143+ def __logger (self )-> None :
144+ self .__alive = True
145+ self .__progbar .start ()
146+ self .__progack = True
147+ while self .__alive :
148+ self .__progbar ["maximum" ]= self .__total
149+ self .__progbar ["value" ]= self .__hashedc
150+ self .__tot .set (self .__total )
151+ self .__generated .set (self .__hashedc )
152+ self .__remaining .set (self .__total - self .__hashedc )
153+ self .__current .set (self .__currentt )
154+ self .__hashed .set (self .__hashedt )
155+ self .__speed .set (self .__divider (self .__counter ))
156+ self .__counter = 0
157+ self .__iroot .update_idletasks ()
158+ sleep (1 )
159+ def __cracker (self )-> None :
160+ hashed = None
161+ self .__hashedc = 0
162+ self .__counter = 0
163+ self .__hashedt = ""
164+ self .__currentt = ""
165+ thash = self .__hash .get ()
166+ if exists (self .__wordlist .get ()):
167+ self .__tcount = Thread (target = self .__countw ,daemon = True )
168+ self .__tcount .start ()
169+ self .__tlog = Thread (target = self .__logger ,daemon = True )
170+ self .__tlog .start ()
171+ if self .__data :
172+ gene = iter (self .__generate (self .__min .get (),self .__max .get (),self .__data ))
173+ try :
174+ i = next (gene )
175+ while i and self .__alive :
176+ hashed = self .__hashfunc (self .__hashname ,i .encode ("raw_unicode_escape" ))
177+ self .__hashedt = hashed
178+ self .__currentt = i
179+ self .__counter += 1
180+ self .__hashedc += 1
181+ if thash == hashed :
182+ self .__alive = False
183+ showinfo ("Info" ,"Hash Found!\n {} = {}" .format (thash ,i ))
184+ self .__current .set (i )
185+ self .__hashed .set (hashed )
186+ self .__generated .set (self .__hashedc )
187+ self .__remaining .set (self .__total - self .__hashedc )
188+ self .__progbar ["value" ]= self .__hashedc
189+ self .__iroot .update_idletasks ()
190+ i = next (gene )
191+ except StopIteration :pass
192+ if exists (self .__wordlist .get ()):
193+ if self .__progack :
194+ self .__progack = False
195+ self .__progbar .stop ()
196+ while self .__talive :sleep (0.1 )
197+ with open (self .__wordlist .get (),"rb" ) as file :
198+ i = file .readline ()
199+ while i and self .__alive :
200+ hashed = self .__hashfunc (self .__hashname ,b"" .join (i .split (b"\n " )))
201+ self .__hashedt = hashed
202+ self .__currentt = i .decode ("raw_unicode_escape" )
203+ self .__counter += 1
204+ self .__hashedc += 1
205+ if thash == hashed :
206+ self .__alive = False
207+ self .__tlog .join ()
208+ showinfo ("Info" , "Hash Found!\n {} = {}" .format (thash , i .decode ("raw_unicode_escape" )))
209+ self .__current .set (i .decode ("raw_unicode_escape" ))
210+ self .__hashed .set (hashed )
211+ self .__generated .set (self .__hashedc )
212+ self .__remaining .set (self .__total - self .__hashedc )
213+ self .__progbar ["value" ]= self .__hashedc
214+ self .__iroot .update_idletasks ()
215+ i = file .readline ()
216+ self .__alive = False
217+ self .__tlog .join ()
218+ if hashed != thash :
219+ showinfo ("Info" ,"Sorry The Hash Not Founded!" )
220+ if self .__progack :
221+ self .__progack = False
222+ self .__progbar .stop ()
223+ self .__iroot .update_idletasks ()
224+ @staticmethod
225+ def __generate (mini :int ,maxi :int ,data :str )-> str :
226+ for length in range (mini ,maxi + 1 ):
227+ for i in product (data ,repeat = length ):
228+ yield "" .join (i )
229+ def __countw (self )-> None :
230+ self .__talive = True
231+ count = 0
232+ with open (self .__wordlist .get (),"rb" ) as file :
233+ i = file .readline ()
234+ while i and self .__talive :
235+ count += 1
236+ i = file .readline ()
237+ if self .__talive :
238+ self .__total += count
239+ self .__progbar ["maximum" ]= self .__total
240+ self .__iroot .update_idletasks ()
241+ self .__talive = False
242+ try :GHBruter ()
243+ except KeyboardInterrupt :exit (0 )
0 commit comments