Files
2026-09-17 00:50:07 +03:00

2.7 KiB
Raw Permalink Blame History

TagPreview

Crypto easy

Сервис хранит запечатанную заметку и умеет проверять её целостность. При успешной проверке он подтверждает приём, но текст не показывает. Для отклонённых записей сервис возвращает поле preview. Проверяем его содержимое.

Решение

Забираем исходную запись:

curl -sS http://<host>:31359/sealed-note -o note.bin

Публичный клиент на неизменённой записи получает status=accepted без plaintext:

python3 public/client.py http://<host>:31359

В inspect_record() сначала вычисляется открытый текст, затем проверяется authentication tag. Сама расшифровка до проверки ещё не раскрывает данные клиенту. Ошибка находится в ветке отказа. При несовпадении тега функция возвращает эти байты в поле preview.

Последние 16 байт записи — тег. Меняем один его байт, не трогая шифротекст, чтобы расшифровка осталась прежней, а проверка провалилась:

from pathlib import Path

record = bytearray(Path("note.bin").read_bytes())
record[-1] ^= 1
Path("tampered.bin").write_bytes(record)

Отправляем подготовленный tampered.bin в POST /inspect с Content-Type: application/octet-stream.

curl -sS --data-binary @tampered.bin \
  -H 'Content-Type: application/octet-stream' \
  'http://<host>:31359/inspect'

При несовпадении тега обработчик возвращает открытый текст вместе с флагом в поле preview. Одной испорченной записи достаточно, поскольку утечка происходит непосредственно в обработчике ошибки.

Расшифрованные байты до проверки тега нельзя отдавать вызывающему коду. Здесь проверка обнаружила повреждение, но обработчик ошибки всё равно раскрыл содержимое заметки.

Солвер.

Флаг

caplag{tag_failure_previewed_the_plaintext}