|
a |
|
b/python/key_solver_bruteforce.py |
|
|
1 |
import itertools |
|
|
2 |
import multiprocessing |
|
|
3 |
import os |
|
|
4 |
import sys |
|
|
5 |
import time |
|
|
6 |
from datetime import datetime, timedelta |
|
|
7 |
|
|
|
8 |
from Crypto.Cipher import AES |
|
|
9 |
|
|
|
10 |
filename = 'emotiv_encrypted_data_UD20160103001874_2017-04-05.17-21-32.384061.txt' |
|
|
11 |
# filename = 'emotiv_encrypted_data_UD20160103001874_2017-04-05.17-42-23.292665.txt' |
|
|
12 |
serial_number = 'UD20160103001874' |
|
|
13 |
iv = os.urandom(AES.block_size) |
|
|
14 |
|
|
|
15 |
# Probably need to expand this and probably use a serial brute force like approach, but meh |
|
|
16 |
# Lets just see if it works. |
|
|
17 |
charset = [char for char in serial_number[-4:]] |
|
|
18 |
charset.extend(['\x00', '\x10', 'H', 'T', 'B', 'P']) |
|
|
19 |
possible_combinations = len(charset) * 16 * 16 |
|
|
20 |
|
|
|
21 |
|
|
|
22 |
# Credit http://stackoverflow.com/questions/11747254/python-brute-force-algorithm |
|
|
23 |
def next_value(): |
|
|
24 |
return (''.join(candidate) |
|
|
25 |
for candidate in itertools.chain.from_iterable(itertools.product(charset, repeat=i) |
|
|
26 |
for i in range(16, 16 + 1))) |
|
|
27 |
|
|
|
28 |
|
|
|
29 |
def counter_check(file_data, cipher, swap_data=False): |
|
|
30 |
counter_misses = 0 |
|
|
31 |
counter_checks = 0 |
|
|
32 |
last_counter = 0 |
|
|
33 |
for line in file_data: |
|
|
34 |
data = line.split(',')[1:] |
|
|
35 |
data = [int(value, 2) for value in data] |
|
|
36 |
data = ''.join(map(chr, data)) |
|
|
37 |
if not swap_data: |
|
|
38 |
decrypted = cipher.decrypt(data[:16]) + cipher.decrypt(data[16:]) |
|
|
39 |
else: |
|
|
40 |
decrypted = cipher.decrypt(data[16:]) + cipher.decrypt(data[:16]) |
|
|
41 |
counter = ord(decrypted[0]) |
|
|
42 |
# Uncomment this |
|
|
43 |
# print(counter) |
|
|
44 |
if counter <= 127: |
|
|
45 |
if counter != last_counter + 1: |
|
|
46 |
counter_misses += 1 |
|
|
47 |
elif not (counter == 0 and last_counter > 127): |
|
|
48 |
counter_misses += 1 |
|
|
49 |
if counter_misses > 2 and counter_checks > 16: |
|
|
50 |
return False |
|
|
51 |
if counter_checks > 16 and counter_misses < 2: |
|
|
52 |
return True |
|
|
53 |
counter_checks += 1 |
|
|
54 |
last_counter = counter |
|
|
55 |
|
|
|
56 |
|
|
|
57 |
with open('{}'.format(filename), 'r') as encrypted_data: |
|
|
58 |
file_data = encrypted_data.readlines() |
|
|
59 |
|
|
|
60 |
|
|
|
61 |
def check_key(next_check): |
|
|
62 |
new_cipher = AES.new(''.join(next_check), AES.MODE_ECB, iv) |
|
|
63 |
if counter_check(file_data, new_cipher): |
|
|
64 |
print("Correct Key Found! {}".format(next_check)) |
|
|
65 |
sys.exit() |
|
|
66 |
|
|
|
67 |
|
|
|
68 |
pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1) |
|
|
69 |
|
|
|
70 |
i = 0 |
|
|
71 |
last_i = 1 |
|
|
72 |
then = datetime.now() |
|
|
73 |
for key in next_value(): |
|
|
74 |
pool.apply_async(check_key, args=(key,)) |
|
|
75 |
i += 1 |
|
|
76 |
|
|
|
77 |
now = datetime.now() |
|
|
78 |
if now - then > timedelta(minutes=1): |
|
|
79 |
print("{} keys per second, last key {}".format((i - last_i) / 60, key)) |
|
|
80 |
last_i = i |
|
|
81 |
then = now |
|
|
82 |
time.sleep(0.00001) |
|
|
83 |
|
|
|
84 |
print("No good.") |