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
- Recover one block using a padding-validity oracle.
- Explain how a one-bit response can disclose protected plaintext.
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.
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
- Python HTTP script: Modify IV bytes, URL-encode a hexadecimal blob, and distinguish only the documented 204 and 403 results.
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.