Last active
April 5, 2020 02:43
-
-
Save jrmdev/50a0d30ace3776a508334a33c1e45b82 to your computer and use it in GitHub Desktop.
Multicore / Multiprocess custom python bruteforcer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Multi-Core python custom bruteforcer | |
# To use, write a function that takes a plain-text candidate and returns the hash | |
# Implement any one-way hashing function. | |
# (See an example for md5sum at the end) | |
import multiprocessing | |
import itertools | |
class Bruteforcer: | |
def __init__(self, charset, min_len, max_len, processes=multiprocessing.cpu_count()): | |
self.charset = charset | |
self.min_len = min_len | |
self.max_len = max_len | |
self.processes = processes + 1 | |
self.candidates = sum(len(self.charset) ** i for i in range(self.min_len, self.max_len+1)) | |
print "[*] Total candidates: %d" % self.candidates | |
def run(self, params): | |
start, end, length = params | |
for candidate in itertools.islice(itertools.product(self.charset, repeat=length), start, end): | |
candidate = ''.join(candidate) | |
if self.user_fct(candidate) == self.to_find: | |
return candidate | |
return None | |
def fun(self, f, q_in, q_out): | |
while True: | |
try: | |
i, x = q_in.get() | |
if i is None or self.found: | |
break | |
res = f(x) | |
q_out.put((i, res)) | |
if res: | |
break | |
except KeyboardInterrupt: | |
break | |
def parmap(self, f, X): | |
q_in = multiprocessing.Queue(1) | |
q_out = multiprocessing.Queue() | |
proc = [multiprocessing.Process(target=self.fun, args=(f, q_in, q_out)) | |
for _ in range(self.processes)] | |
for p in proc: | |
p.daemon = True | |
p.start() | |
sent = [q_in.put((i, x)) for i, x in enumerate(X)] | |
[q_in.put((None, None)) for _ in range(self.processes)] | |
res = [q_out.get() for _ in range(len(sent))] | |
[p.join() for p in proc] | |
return [x for i, x in sorted(res)] | |
def brute(self, to_find, user_fct): | |
self.found = False | |
self.to_find = to_find | |
self.user_fct = user_fct | |
for length in range(self.min_len, self.max_len+1): | |
nb_candidates = len(self.charset) ** length | |
step = nb_candidates // self.processes | |
params = [(pos, pos+step, length) for pos in range(0, nb_candidates, step)] | |
print "[+] Bruteforcing candidates of length %d..." % length | |
for i in range(self.processes): | |
for res in self.parmap(self.run, params): | |
if res: | |
return res | |
return None | |
# Usage example: Bruteforce md5sum | |
import hashlib | |
def do_md5(candidate): | |
return hashlib.md5(candidate).digest().encode('hex') | |
# Set the charset, min_len, max_len. | |
bf = Bruteforcer('abcdefghijklmnopqrstuvwxyz', 5, 5) | |
# Bruteforce your hash with your custom function | |
res = bf.brute('d26b93ad37e9017465673eaaac260839', do_md5) | |
print "Found result:", res |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment