Pocket CTF Reference · Device home

Quiet Oracle

The admin archive provides an IV and one ciphertext block. A vault reveals no plaintext, but two status codes disclose whether modified plaintext has valid PKCS#7 padding.

Objective

Before you begin

Complete False Identity and retain its vault blob and block size. Run requests sequentially to protect the classroom device.

Concepts

In CBC decryption, changing an IV byte changes the corresponding plaintext byte. An oracle that distinguishes valid padding lets a script solve bytes from the end of a block toward the beginning.

Fixed ciphertext C is decrypted to intermediate bytes I. The observer changes only the IV, so plaintext P equals I XOR IV. Padding handling returns a valid or invalid signal that guides the next IV trial.

Hold ciphertext C fixed so the decrypted intermediate bytes I stay fixed. Changing the IV changes P = I XOR IV. Padding handling tests the end of P and returns an observable valid/invalid signal; the observer uses that signal to choose another IV trial. The intermediate bytes are not the original plaintext. Authenticate ciphertext before releasing plaintext or exposing padding-dependent behavior.

Suggested tools

Tool practice

Rehearse the worked tool exercise before using challenge data.

Decode the blob from hex before slicing it into equal IV and ciphertext blocks. Print lengths, not secrets, while debugging. Use a bytearray for the trial IV and bytes for the unchanged ciphertext. Log trial position, padding length, candidate byte, and status; never treat a timeout as a padding response.

Investigation

Rehearse the byte operations locally

For one block, write I = D_K(C) for the intermediate decrypted bytes and P = I XOR IV for the padded plaintext. Holding C fixed holds I fixed; changing the IV changes only the XOR input. The classroom uses a toy block operation to teach this relationship; it is not an AES implementation.

Run this unrelated one-byte example in Python:

intermediate = 0x52
original_iv = 0x33
print(hex(intermediate ^ original_iv))  # 0x61
trial_iv = 0x50
print(hex(intermediate ^ trial_iv))     # 0x2

Here ^ is XOR. The second result is a candidate padding byte, not the original plaintext byte. Use the original IV when relating an intermediate value back to the original message. Keep original and trial values separately.

PKCS#7 padding appends n copies of byte n: with a four-byte teaching block, b"ab" becomes b"ab\x02\x02". An aligned four-byte message needs a whole extra padding block. A suffix \x03\x02 is invalid because its final value requires two \x02 bytes. Do not strip an arbitrary number of final bytes without checking them.

For the board's oracle, 204 means valid padding and 403 means invalid padding. 400 means malformed input and supplies no padding evidence. Stop on connection errors or unexpected statuses. Use a finite loop over 256 candidates per byte, sequential requests, and a log; recheck unexpected multiple matches rather than accepting the first response blindly. When testing a one-byte padding candidate, changing the preceding byte distinguishes a true one-byte suffix from an accidentally preserved longer padding suffix.

Observe

Split the blob into its IV and ciphertext block. Confirm the oracle's response to the original blob and one controlled modification.

Form a hypothesis

For each padding length, which IV byte values make all solved positions decrypt to that padding?

Test carefully

Change only the preceding block or IV, send requests sequentially, and verify ambiguous observations before trusting them.

Progressive hints

Hint 1

Valid PKCS#7 padding constrains the end of a plaintext block.

Hint 2

Use the documented status difference as one bit of evidence per request.

Hint 3

Check the recovered bytes and padding locally before using the unlock route.

Troubleshooting and reset

A blob must contain exactly an IV and one block. Stop concurrent requests and back off if the board slows. Preserve the unlock output for Final Authority.