CRYPTOHACK

Forbidden Fruit

Description

Galois Counter Mode (GCM) is the most widely used block cipher mode in TLS today. It's an "authenticated encryption with associated data" cipher mode (AEAD), yet not resistant to misuse.

See here for a great resource on the inner workings of GCM, as well as this attack.

Help

This page offers a convenient way for you to interact with the challenge functions. You can also use GET requests to send and receive data directly from the listed routes/endpoints if you wish. For more information see the FAQ.

Your aim is to recover the FLAG value. Once you have it, submit it on the CryptoHack Symmetric Ciphers page.

Source

from Crypto.Cipher import AES
import os


IV = ?
KEY = ?
FLAG = ?


@chal.route('/forbidden_fruit/decrypt/<nonce>/<ciphertext>/<tag>/<associated_data>/')
def decrypt(nonce, ciphertext, tag, associated_data):
    ciphertext = bytes.fromhex(ciphertext)
    tag = bytes.fromhex(tag)
    header = bytes.fromhex(associated_data)
    nonce = bytes.fromhex(nonce)

    if header != b'CryptoHack':
        return {"error": "Don't understand this message type"}

    cipher = AES.new(KEY, AES.MODE_GCM, nonce=nonce)
    encrypted = cipher.update(header)
    try:
        decrypted = cipher.decrypt_and_verify(ciphertext, tag)
    except ValueError as e:
        return {"error": "Invalid authentication tag"}

    if b'give me the flag' in decrypted:
        return {"plaintext": FLAG.encode().hex()}

    return {"plaintext": decrypted.hex()}


@chal.route('/forbidden_fruit/encrypt/<plaintext>/')
def encrypt(plaintext):
    plaintext = bytes.fromhex(plaintext)
    header = b"CryptoHack"

    cipher = AES.new(KEY, AES.MODE_GCM, nonce=IV)
    encrypted = cipher.update(header)
    ciphertext, tag = cipher.encrypt_and_digest(plaintext)

    if b'flag' in plaintext:
        return {
            "error": "Invalid plaintext, not authenticating",
            "ciphertext": ciphertext.hex(),
        }

    return {
        "nonce": IV.hex(),
        "ciphertext": ciphertext.hex(),
        "tag": tag.hex(),
        "associated_data": header.hex(),
    }


Interact

decrypt(nonce,ciphertext,tag,associated_data)
Hex Input Only
Hex Input Only
Hex Input Only
Hex Input Only
encrypt(plaintext)
Hex Input Only
Output

XOR tool

Use this form to XOR two hex strings together.

Output
Hex Encoder/Decoder

This is a convenient encoder designed for ASCII <-> Hex translations. It won't work for decoding hex to byte streams and will just show [unprintable] in that case.

0