cryptofreemedium

Protocol Analysis 8: Reflection

metactf

Task: analyze a certificate-based Alice/Bob protocol exposed over HTTP and recover Bob's flag. Solution: exploit a reflection and role-confusion flaw by feeding Bob's identity and nonce back through Alice, then relaying Alice's signature on Bob's own tuple to satisfy Bob.

$ ls tags/ techniques/
signature_relayreflection_attackrole_confusionidentity_reflectionnonce_reuse_abuse

Protocol Analysis 8: Reflection — metactf

Description

Bob and Alice are talking again, but this time they messed up and are both in the same roles of the protocol. Bob still has a flag though, can you get it?

English summary: the challenge provides a live Alice/Bob authentication protocol at https://protocols.live plus a PDF transcript. We need to drive both state machines, understand what each side actually signs, and make Bob accept a forged-looking but valid reflected authentication flow.

Analysis

The PDF excerpt says both Alice and Bob begin by sending their own public key, identity, and certificate:

Alice: send pubA, A, certA Bob: send pubB, B, certB

Then Bob expects:

pubX, X, certX, nX1

and responds with:

nA, {X, nX1, nA}priv

Later Alice expects a similar structure and signs another tuple, after which Bob checks the final message and releases the flag.

On the live service, the interaction details are:

  • POST /model/8 creates a fresh instance and returns conn_id.
  • POST /alice and POST /bob are stateful endpoints that must share that same conn_id.
  • Sending JSON {"conn_id": ..., "content": ""} triggers the participant's initial send.
  • Messages are pipe-delimited typed fields such as k:<hex>, n:<name>, d:<hex>, t:<text>.

Observed openers:

Alice: k:<pubA>|n:alice|d:<certA> Bob: k:<pubB>|n:bob|d:<certB>

If we send Bob Alice's opener plus our own chosen nonce n1:

k:<pubA>|n:alice|d:<certA>|d:<n1>

Bob replies with two data fields:

d:<nB>|d:<sigB>

At this point the obvious idea is to reflect Alice's identity back to Alice. That fails. The important implementation quirk came from testing /util/asym_verify: Alice's reflected signature is not accepted by Bob unless the signed literal text uses Bob's identity in the first field.

The winning message to Alice is therefore:

k:<pubB>|n:bob|d:<certB>|d:<nB>

Alice answers with:

...

🔒

Permission denied (requires auth)

Sign in to read this free writeup

This writeup is free — just sign in with GitHub to read it.

$ssh [email protected]