SealTail

Crypto easy

Релизная очередь принимает `release.capsule`: заголовок, RSA-подпись и команды в TLV-формате. В заголовке есть `signed_len` — длина подписанной части. Проверяющий использует именно её, а очередь после успешной проверки разбирает весь payload до конца файла. ## Решение Сначала прогоняем исходную капсулу через публичный verifier: ```bash python3 public/verify_capsule.py public/release.capsule ``` Он показывает `signature_valid=True`, `payload_len=181`, `signed_len=181`, `unsigned_tail_len=0`. Пока подпись покрывает весь payload, неподписанного хвоста нет. Открываем `FORMAT.md`. Для экспорта карантинного ключа предусмотрен тег `0x42 EXPORT_QUARANTINE_KEY`. TLV-запись состоит из байта тега, двух байт длины в big-endian и значения. Дописываем такую команду в конец капсулы: ```python from pathlib import Path value = (b"lane=quarantine\nrequestor=release-audit\n" b"reason=post-signature-tail-check\n") tail = bytes([0x42]) + len(value).to_bytes(2, "big") + value original = Path("public/release.capsule").read_bytes() Path("modified.capsule").write_bytes(original + tail) ``` Подписанные байты и `signed_len` остались прежними. Проверяем модифицированный файл той же утилитой. Значение `unsigned_tail_len` должно стать больше нуля, а `signature_valid` остаться `True`. ```bash python3 public/verify_capsule.py modified.capsule ``` Отправляем капсулу в очередь: ```bash curl -sS --data-binary @modified.capsule \ -H 'Content-Type: application/octet-stream' \ http://:31337/submit ``` RSA-проверка принимает исходный префикс, затем TLV-парсер доходит до добавленной неподписанной команды и возвращает ключ с флагом. > Подпись подтверждает только те байты, которые в неё включили. Если после проверки исполнять ещё и неподписанный хвост, целостность всего релиза она уже не гарантирует. [Солвер](solve/solve.py). ## Флаг `caplag{signed_prefix_is_not_a_release}`