From 17e0ff2d1699e68ce500a0d80c97ebcb7c822913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Mon, 1 Jul 2019 15:52:11 +0200 Subject: [PATCH] add multithreaded remote sample gathering --- break_script/automated_attack.py | 39 +++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/break_script/automated_attack.py b/break_script/automated_attack.py index 41d23c9..bbb7934 100755 --- a/break_script/automated_attack.py +++ b/break_script/automated_attack.py @@ -4,6 +4,7 @@ from pwn import * import random import string import math +import threading #context.log_level = "debug" @@ -28,12 +29,24 @@ sbox = ( 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 ) -def gather_measurements(r, amount): +def gather_measurements(remotes, amount): progress = log.progress("Gathering measurements") measurements = {} + threads = [] + lock = threading.Lock() + for r in remotes: + thread = threading.Thread(target=gather_measurements_, args=(r, amount // len(remotes), amount, measurements, progress, lock)) + thread.start() + threads.append(thread) + + for thread in threads: + thread.join() + + progress.success("{amount}/{amount}".format(amount=amount)) + return measurements + +def gather_measurements_(r, amount, total_amount, measurements, progress, lock): for i in range(amount): - if i & 0xFF == 0: - progress.status("{}/{}".format(i, amount)) r.send(b"profiler_reset\n") r.recvuntil(b"> ") password = ''.join(random.choices(allowed_chars, k=16)).encode("ascii") @@ -51,10 +64,12 @@ def gather_measurements(r, amount): name = line[0] no_invocations = int(line[-1]) if name == "gf_reduce": + lock.acquire() measurements[password] = no_invocations + progress.status("{}/{}".format(len(measurements), total_amount)) + lock.release() break - progress.success("{amount}/{amount}".format(amount=amount)) - return measurements + def mean(data): return sum(data) / len(data) @@ -72,9 +87,14 @@ def t_test(group_big, group_small): variance_small = variance(group_small, mean_small) return (mean_big - mean_small) / math.sqrt(variance_big / len(group_big) + variance_small / len(group_small)) -r = process("/home/manuel/wolke/Projects/secutech_authenticator/build/default/secutech") +#remotes = [process("/home/manuel/wolke/Projects/secutech_authenticator/build/default/secutech")] +remotes = [] +no_threads = 50 +for i in range(no_threads): + remotes.append(remote("ccn.li", "5555")) -r.recvuntil(b"> ") +for r in remotes: + r.recvuntil(b"> ") measurements = {} @@ -82,7 +102,7 @@ key = [] # We keep gathering measurements until we are certain enoguh which key the correct one is while len(key) < 16: - measurements.update(gather_measurements(r, 1000)) + measurements.update(gather_measurements(remotes, 1000)) log.info("Total number of unique measurements gathered: {}".format(len(measurements))) # This attack allows us to test each aes key byte independently @@ -122,4 +142,7 @@ while len(key) < 16: else: break +for r in remotes: + r.close() + print("Key:", " ".join(["{:02X}".format(k) for k in key]))