Кубок CTF России

Разбор: MMM с отбора X Кубка CTF

Условие: reverse с меткой beginner. Бинарник на C++ без защит, с символами, принимает флаг аргументом. По таблице организаторов задание решили 575 раз.

Что проверяет программа

  • check: сверяет длину строки в 40 байт, умножает вектор из её байтов на целочисленную матрицу 40×40 и проверяет, что результат коллинеарен исходному вектору
  • hash_check: сравнивает SHA-256 строки с эталоном

Значит, строка должна быть собственным вектором матрицы. Собственное значение в бинарнике нигде не хранится.

Ход решения

  • Найти цикл и условие: это проверка коллинеарности
  • Вытащить матрицу из .rodata: символ MATRIX, 40×40, int64
  • Посчитать собственные числа через numpy и взять целое: здесь 1337
  • Нормировать вектор, чтобы первая координата стала кодом буквы c, и округлить
  • Сверить SHA-256 найденной строки

Что вынести

Реверс не всегда значит подбор. Узнали формулу в цикле — решайте задачу математикой.

Пример

Пример условный. В команде один участник читает цикл в дизассемблере, второй сразу пробует в numpy матрицу поменьше. Первая встреча идёт уже с готовой гипотезой.

Важно. Нормировка здесь работает, потому что формат флага известен заранее: начало строки вы знаете, поэтому знаете и масштаб.

Для разбора в команде

  • ☐ Записан вид проверки
  • ☐ Матрица извлечена скриптом
  • ☐ Результат сверен с хешем
  • ☐ Приём записан в базу разборов

Запишите ход решения в шаблон разбора, пока он свежий 👇

Основание: условие и решение авторов задачи, репозиторий acisoru/ctfcup2026-quals, reverse/mmm. Канал не принадлежит организаторам; официальный сайт — ctfcup.ru.

Первоисточник