/Разборы задач
31 октября 2026
Райтап на задачу «Прошлогодний флаг»
Разбор задачи «Прошлогодний флаг» от fderious: изучаем бинарник в Ghidra и получаем флаг POST-запросом.6
11

Reverse
Задача «Прошлогодний флаг»
Описание:
«— У вас флаг свежий? — Нет, прошлогодний!»
Итак, нам дан бинарник и интересное описание. Предлагаю для начала посмотреть, что это за файл, и открыть его:
Возникает следующая проблема — нам нужен прошлый год, но как это сделать? Правильно, можно пойти посмотреть в гидре, как всё устроено. Проанализировав бинарник, мы замечаем такое:
В функции main мы видим, что сразу после запроса имени наш бинарник берет значение нашего системного времени(года). Далее программа формирует JSON-объект с полученными данными времени с нашей системы и отправляет POST-запрос на https://last-year-flag.t1.bug-makers.ru/get_flag. Теперь можно обхитрить эту систему и самим отправить POST-запрос через curl в терминале, он будет выглядеть следующим образом:
И мы получаем флажок. НО есть еще не менее интересные варианты решения этого задания)))
Опять же открываем ghidra и внимательно смотрим на то, как бинарник считает дату:
local_120 = std::chrono::_V2::system_clock::now();
local_118 = std::chrono::_V2::system_clock::to_time_t((time_point *)&local_120);
local_110 = localtime(&local_118);
local_128 = local_110->tm_year + 0x76c;Теперь давайте поподробнее разберёмся, что тут происходит:
local_120 = std::chrono::_V2::system_clock::now();Тут функция now() обращается к системному времени на устройстве и записывается в time_point. На данном этапе это огромное число, т. к. она содержит в себе количество наносекунд с момента Unix (1970 год).
local_118 = std::chrono::_V2::system_clock::to_time_t((time_point *)&local_120);Ну тут ничего интересного не происходит, обычное математическое вычисление. Теперь наши наносекунды перевели в секунды time_t.
local_110 = localtime(&local_118);Опять же перевод. Здесь функция localtime() разбивает наши секунды из time_t в более понятные единицы — минуты, часы, дни, годы. Вот тут есть интересный момент: в ЯП «C» отсчёт идёт от 1900 года, то есть подсчёт будет выглядеть примерно так: «2026-1900». Наша переменная tm_year будет хранить в себе ровно 126.
local_128 = local_110->tm_year + 0x76c;И самое интересное находится тут) В итоговую переменную local_128 записывается наш tm_year (он равен 126) + 0x76c (это 1900 в шестнадцатеричной системе — hex). К чему я веду: чтобы получить 2025, нам нужно изменить 0x76c → 0x76b (1899), тогда у нас всё будет чётко)
Находим нашу переменную в правом окне, нажимаем на неё, и у нас подсвечивается строчка в Listing (левое окно). Теперь нажимаем правой кнопкой мыши и выбираем «Patch Instruction» или же используем комбинацию клавиш Ctrl + Shift + G. Теперь нам предлагают изменить эту строчку, мы же заменяем только 0x76b → Enter. Теперь нам нужно сохранить нашу пропатченную программу: нажимаем в левом верхнем углу кнопку File → Export program (или же можно просто нажать O). Важный момент!! Вы должны сохранить файл как «Original Format» (в некоторых версиях гидры она называется просто Binary). Теперь выдаём права нашей программе с помощью chmod +x file_name и запускаем:
Есть ещё альтернатива, как пропатчить, не заходя в гидру (хотя зайти придётся, чтобы знать, что патчить)):
Ничем не отличается от предыдущего варианта, просто тут все происходит в терминале:
Теперь можно выбрать любой вариант и наслаждаться решением)