def json2proto(point): out = challenge_pb2.EcdhKey() out.curve = challenge_pb2.EcdhKey.CurveID.SECP256R1 x, y = point['gx'], point['gy'] out.public.x = x.to_bytes((x.bit_length() + 7) // 8, 'big') out.public.y = y.to_bytes((y.bit_length() + 7) // 8, 'big') return out
def key2proto(key): assert (isinstance(key, ec.EllipticCurvePublicKey)) out = challenge_pb2.EcdhKey() out.curve = curve2proto(key.curve) x, y = key.public_numbers().x, key.public_numbers().y out.public.x = x.to_bytes((x.bit_length() + 7) // 8, 'big') out.public.y = y.to_bytes((y.bit_length() + 7) // 8, 'big') return out
def run_session(x, y, b, guess_d, mod): tube = remote.remote('tiramisu.2021.ctfcompetition.com', 1337) # tube = pwnlib.tubes.remote.remote('127.0.0.1', port) # print(tube.recvuntil('== proof-of-work: ')) if tube.recvline().startswith(b'enabled'): handle_pow() server_hello = read_message(tube, challenge_pb2.ServerHello) server_key = proto2key(server_hello.key) # print(server_hello) # private_key = ec.generate_private_key(ec.SECP224R1()) out = challenge_pb2.EcdhKey() out.curve = challenge_pb2.EcdhKey.CurveID.SECP256R1 out.public.x = x.to_bytes((x.bit_length() + 7) // 8, 'big') out.public.y = y.to_bytes((y.bit_length() + 7) // 8, 'big') client_hello = challenge_pb2.ClientHello() client_hello.key.CopyFrom(out) # print(client_hello) write_message(tube, client_hello) c = curve.P224 c.b = b p = c.p try: guessed_shared_x = (guess_d * Point(x % p, y % p, curve=curve.P224)).x except ValueError: return False shared_key = guessed_shared_x.to_bytes(224 // 8, "big") # shared_key = private_key.exchange(ec.ECDH(), server_key) # print(shared_key) channel = AuthCipher(shared_key, CHANNEL_CIPHER_KDF_INFO, CHANNEL_MAC_KDF_INFO) msg = challenge_pb2.SessionMessage() msg.encrypted_data.CopyFrom(channel.encrypt(IV, b'hello')) write_message(tube, msg) # print('msg:', msg) reply = read_message(tube, challenge_pb2.SessionMessage) # print("d: {}, mod: {}".format(guess_d, mod)) # print('reply:', repr(reply)) # import code # code.interact(local=locals()) tube.close() if len(repr(reply)): return True return False
def num2proto(x, y, curvename): out = challenge_pb2.EcdhKey() out.curve = name2proto(curvename) out.public.x = x.to_bytes((x.bit_length() + 7) // 8, 'big') out.public.y = y.to_bytes((y.bit_length() + 7) // 8, 'big') return out