Разбор: 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.