Protocol Analysis 4: Real Security!
Protocol Analysis 4: Real Security!
Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: chosen_key_attack, chosen_nonce_attack, ciphertext_decryption, direct_bob_trigger, oracle_recon
Summary
Walkthrough of the CUSTOM Crypto Protocol Analysis 4: Real Security!. Task: a protocol challenge uses attacker-provided symmetric encryption parameters inside an Alice-to-Bob request, and the live service accepts a slightly different string than the PDF shows. Solution:
title: "Protocol Analysis 4: Real Security!" id: 20260410_metactf_protocol_analysis_4_real_security category: crypto difficulty: easy event: metactf tags: ["protocol_analysis", "plaintext_protocol", "alice_and_bob", "symmetric_encryption", "chosen_key", "chosen_nonce"] techniques: ["chosen_key_attack", "chosen_nonce_attack", "ciphertext_decryption", "direct_bob_trigger", "oracle_recon"] tools: ["python3", "requests"] indicators: ["the service exposes both protocol endpoints and a symmetric decrypt utility", "Alice reveals the exact accepted request text after any syntactically valid probe", "Bob accepts attacker-supplied key and nonce material", "the live accepted string differs slightly from the visible PDF text", "the accepted request contains the typo symetric"]
Protocol Analysis 4: Real Security! — metactf
Description
The protocol manual describes an Alice-to-Bob request for sending the flag encrypted under a symmetric key and nonce.
English summary: the challenge provides a protocol PDF and a live service. The important twist is that the real accepted Bob request is not exactly the visible PDF wording, so we first need to recover Alice's actual message from the service and then abuse Bob's trust in attacker-chosen key material.
Summary
This challenge is a broken secure-channel design. Alice's first message includes a symmetric key and nonce, and Bob blindly trusts those values when encrypting the flag. By querying /alice with any syntactically valid placeholder such as t:hi, we learn the exact string Bob will accept, including the typo symetric. We can then talk to Bob directly, choose our own known key and nonce, receive the ciphertext, and decrypt it with /util/sym_decrypt.
Recon
The shared manual explains the protocol shape, but the live service is stricter than the visible PDF text: the accepted string must match Alice's real output exactly.
Sending any syntactically valid placeholder message to /alice, for example t:hi, causes Alice to reveal her actual first message:
text read-only • copy allowedt:Hello|n:bob|t:this is|n:alice|t:send me the flag encrypted under this symetric key and nonce|k:<key>|d:<nonce>
The critical detail is the typo: the accepted request contains symetric, not symmetric. The text also has to be exactly send me the flag encrypted under this symetric key and nonce.
Vulnerability
Bob uses key and nonce values taken directly from the incoming message. There is no authentication, no trusted key exchange, and no restriction that those parameters must come from a legitimate Alice-controlled process. That means the attacker can choose a known symmetric key and nonce, send the full forged Alice request directly to Bob, and force Bob to encrypt the flag under attacker-controlled parameters.
This turns the protocol into a chosen-key / chosen-nonce attack: confidentiality fails because the recipient encrypts sensitive data with values fully controlled by the attacker.
Exploitation
I used the following known values:
- key =
00repeated 32 bytes - nonce =
11repeated 12 bytes
That gives this working Bob request:
text read-only • copy allowedt:Hello|n:bob|t:this is|n:alice|t:send me the flag encrypted under this symetric key and nonce|k:0000000000000000000000000000000000000000000000000000000000000000|d:111111111111111111111111
Bob responds in the format:
text read-only • copy allowedt:here it is|d:<ciphertext>
Finally, submit that ciphertext to /util/sym_decrypt using the same chosen key and nonce. Because we selected the parameters ourselves, the utility cleanly decrypts the ciphertext and returns the flag.
Working solver:
python read-only • copy allowed#!/usr/bin/env python3 import requests BASE = "https://protocols.live" KEY = "00" * 32 NONCE = "11" * 12 def main(): session = requests.Session() create = session.post(f"{BASE}/model/4") create.raise_for_status() conn_id = create.json()["conn_id"] alice = session.post( f"{BASE}/alice", json={"conn_id": conn_id, "content": "t:hi"}, ) alice.raise_for_status() print("Alice says:", alice.json()["content"]) forged = ( "t:Hello|n:bob|t:this is|n:alice|" "t:send me the flag encrypted under this symetric key and nonce|" f"k:{KEY}|d:{NONCE}" ) bob = session.post( f"{BASE}/bob", json={"conn_id": conn_id, "content": forged}, ) bob.raise_for_status() bob_content = bob.json()["content"] print("Bob says:", bob_content) ciphertext = bob_content.split("|d:", 1)[1] dec = session.post( f"{BASE}/util/sym_decrypt", json={"conn_id": conn_id, "content": f"k:{KEY}|d:{NONCE}|d:{ciphertext}"}, ) dec.raise_for_status() print(dec.json()) if __name__ == "__main__": main()
Key Takeaways / Lessons
- Mastering chosen_key_attack, chosen_nonce_attack, ciphertext_decryption, direct_bob_trigger, oracle_recon was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-04-10 • CUSTOM • Protocol Analysis 4: Real Security! • Difficulty: Easy