Pocket CTF Reference · Device home

Chained Forgery

A service applies plain CBC-MAC to messages of different lengths without binding the length or domain. Use known one-block states to construct an accepted two-block message.

Objective

Before you begin

Open /challenge/insane/cbc-mac, fetch the public vectors, and review hexadecimal.

Concepts

With a zero IV, a one-block tag is the chaining state after that block. A carefully chosen next block can cancel the first state and make encryption begin from another known one-block input.

With a fixed initial state, CBC-MAC combines each message block with the prior chaining state and encrypts it. The final state becomes the tag; variable-length messages require a suitable MAC construction.

Plain CBC-MAC starts from a fixed initial state and repeatedly combines a message block with the previous state before block encryption. The final state is the tag. Security for fixed-length messages does not automatically carry over to variable-length inputs. Use a standard construction such as CMAC or HMAC for variable-length messages, with all relevant context authenticated.

Suggested tools

Tool practice

Rehearse the worked tool exercise before using challenge data.

Decode each vector with bytes.fromhex and check its length before XOR. XOR pairs byte positions; concatenation appends blocks. The known one-block message is the required first block of the submitted message. Keep a table of block input, incoming state, and outgoing state.

Investigation

Rehearse XOR and block lengths locally

left = bytes.fromhex("1020")
right = bytes.fromhex("0102")
assert len(left) == len(right)
mixed = bytes(a ^ b for a, b in zip(left, right))
print(mixed.hex(), len(mixed))          # 1122 2
print((left + right).hex())             # 10200102

XOR combines corresponding bytes; + concatenates them. zip silently stops at the shorter input, so check equal lengths first. The two-byte practice inputs are unrelated to the game's block size.

Trace CBC-MAC with S0 = 0 and Si = E_K(Mi XOR S(i-1)). A one-block tag is S1; a two-block tag is S2. The same deterministic block operation maps the same input to the same output. Mark the input after XOR in each row before reasoning about the next block. This exercise uses a toy block operation; the lesson transfers to CBC-MAC chaining, not to breaking a production cipher.

Observe

Record both known messages, their tags, the required 32-byte length, and the required first block.

Form a hypothesis

Can the chaining state after one known message be used to connect to another known message without knowing the MAC key?

Test carefully

Construct exactly two blocks beginning with the required message. Submit its hex plus the known target tag once.

Progressive hints

Hint 1

Track the state entering each block-encryption step.

Hint 2

Ask what block would make a known incoming state reach another known input.

Hint 3

Check the required prefix and exact byte length before one submission.

Troubleshooting and reset

Check that every decoded value is 16 bytes and the forged message is 32 bytes. Hex output should have no 0x, spaces, or separators.