На этот раз я занимаюсь этим крэком под названием мексиканский. Чтобы решить эту проблему, мы будем использовать radare2’s для анализа двоичного файла и нахождения флага. Затем нам нужно исправить двоичный файл, чтобы он выводил флаг. Давайте прямо сейчас!

Если мы откроем двоичный файл с помощью radare2 и перейдем к функции main, мы увидим вызов функции flag… но что-то странное 🤔

После выполнения __main он сравнивает значение 0xC1 с самим собой (строки 0x0040163a и 0x00401642) и вызывает функцию флага , только если 0xc1 больше, чем 0xc1 . Этого, конечно, никогда не произойдет, чтобы получить флаг, мы могли бы сделать одно из следующего:

  • Перейдите к функции флага и соберите флаг прямо из кода
  • Исправьте двоичный файл, чтобы условие работало

Решение 2. Извлечение флага из кода

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

Мы видим, что каждая инструкция, загружающая символ в строку, имеет вид mov byte [eax], XX, а байт-код для каждой из этих инструкций - c600XX, являющийся XX шестнадцатеричным значением символа.

Итак, если мы ищем c600, а затем извлекаем следующий байт, мы получим наш флаг char по char, тем же методом, который встроен внутри функции. Вот сценарий python, использующий r2pipe, который делает именно это:



Решение 2: двоичное исправление

В этом случае мы можем использовать r2pipe для перехода к «проблемной» инструкции и изменить всего один бит. Сравнение выполняется между * var_1ch (которое, как нам известно, равно 0xc1 из предыдущей строки) и жестко запрограммированным значением 0xc1. Было бы здорово, если бы мы могли изменить жестко запрограммированное значение на 0xc0, эффективно инвертируя условие?

Конечно! Как это сделать с помощью r2pipe? Я написал следующий сценарий, который выполняет эту работу:



Теперь, если мы выполним взломанный двоичный файл, мы получим флаг вместо сообщения «попробуй усерднее». Здесь вы можете увидеть оба сценария в действии и разницу между исходным и взломанным двоичным кодом: