diff --git a/forensics/sidechannel/pin_checker b/forensics/sidechannel/pin_checker new file mode 100755 index 0000000..28cf713 Binary files /dev/null and b/forensics/sidechannel/pin_checker differ diff --git a/forensics/sidechannel/solve.py b/forensics/sidechannel/solve.py new file mode 100755 index 0000000..f3fb430 --- /dev/null +++ b/forensics/sidechannel/solve.py @@ -0,0 +1,60 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i python3 -p "python3.withPackages (ppkgs: with ppkgs; [ pwntools ])" + +from datetime import datetime, timedelta + +from pwn import * + +def gen_pin(prefix: str, i: int) -> str: + return f"{prefix}{i}".ljust(8, '0') + +def try_pin(pin: str) -> (int, bool): + p = process("./pin_checker") + + p.recvuntil(b":\n") + + before = datetime.now() + p.sendline(pin.encode()) + assert((line := p.recvline().strip()) == '8', f"{line}") + assert((line := p.recvline().strip()) == 'Checking PIN...', f"{line}") + result = p.recvline().decode() + after = datetime.now() + duration = after - before + + if result.strip() == 'Access denied.': + return duration, False + # NOTE: found by strings | grep "Access" + elif result.startswith('Access granted'): + return duration, True + else: + print("Unexpected result:") + print(result) + return duration, False + +def main(): + current_prefix = "" + for i in range(8): + + max_time = timedelta.min + max_digit = None + + for d in range(10): + pin = gen_pin(current_prefix, d) + + time, result = try_pin(pin) + if max_time < time: + max_time = time + max_digit = d + + if result: + print(f'FOUND PIN: {pin}') + break + else: + print(f"{pin} -> {time}") + + current_prefix = current_prefix + str(max_digit) + print(current_prefix) + +if __name__ == '__main__': + main() +