add multithreaded remote sample gathering

This commit is contained in:
2019-07-01 15:52:11 +02:00
parent 0c9768e065
commit 17e0ff2d16

View File

@@ -4,6 +4,7 @@ from pwn import *
import random import random
import string import string
import math import math
import threading
#context.log_level = "debug" #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 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") progress = log.progress("Gathering measurements")
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): for i in range(amount):
if i & 0xFF == 0:
progress.status("{}/{}".format(i, amount))
r.send(b"profiler_reset\n") r.send(b"profiler_reset\n")
r.recvuntil(b"> ") r.recvuntil(b"> ")
password = ''.join(random.choices(allowed_chars, k=16)).encode("ascii") password = ''.join(random.choices(allowed_chars, k=16)).encode("ascii")
@@ -51,10 +64,12 @@ def gather_measurements(r, amount):
name = line[0] name = line[0]
no_invocations = int(line[-1]) no_invocations = int(line[-1])
if name == "gf_reduce": if name == "gf_reduce":
lock.acquire()
measurements[password] = no_invocations measurements[password] = no_invocations
progress.status("{}/{}".format(len(measurements), total_amount))
lock.release()
break break
progress.success("{amount}/{amount}".format(amount=amount))
return measurements
def mean(data): def mean(data):
return sum(data) / len(data) return sum(data) / len(data)
@@ -72,8 +87,13 @@ def t_test(group_big, group_small):
variance_small = variance(group_small, mean_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)) 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"))
for r in remotes:
r.recvuntil(b"> ") r.recvuntil(b"> ")
measurements = {} measurements = {}
@@ -82,7 +102,7 @@ key = []
# We keep gathering measurements until we are certain enoguh which key the correct one is # We keep gathering measurements until we are certain enoguh which key the correct one is
while len(key) < 16: 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))) log.info("Total number of unique measurements gathered: {}".format(len(measurements)))
# This attack allows us to test each aes key byte independently # This attack allows us to test each aes key byte independently
@@ -122,4 +142,7 @@ while len(key) < 16:
else: else:
break break
for r in remotes:
r.close()
print("Key:", " ".join(["{:02X}".format(k) for k in key])) print("Key:", " ".join(["{:02X}".format(k) for k in key]))