Хабрахабр

Головоломка «Test My Patience» от Check Point Security Academy

Я несколько раз упоминал на Хабре программу «Check Point Security Academy»: суть её в том, что фирма Check Point летом объявила конкурс в формате «Capture the Flag», где не важен прошлый опыт участника, а важны только его способности к распутыванию кибер-головоломок. По результатам этого конкурса фирма набрала двадцать участников на трёхмесячный профессиональный курс по кибер-безопасности, и все участники с самого начала курса получают полную зарплату специалиста по КБ, под обязательство отработать в фирме два года после окончания курса.


В соревновании CTF флаг может быть даже картинкой, например такой.

Конкурс состоит из 12 головоломок различной сложности, оцененных от 10 до 150 очков.
Здесь я хочу разобрать головоломку «Test My Patience» из категории «Surprise». Отбор участников завершился в августе, но сайт конкурса продолжит действовать до следующего лета, и я приглашаю желающих зарегистрироваться и попробовать свои силы ради спортивного интереса. Она средней сложности (50 очков), и вот её полный текст:

Hi there,
We found This executable on the local watchmaker's computer.
It is rumored that somehow the watchmaker was the only person who succeeded to crack it.
Think you're as good as the watchmaker?
Note: This file is not malicious in any way

По ссылке — 32-битный бинарник для Windows, на который ругаются некоторые антивирусы, но если его всё же запустить, то выглядит он так:

Вероятно, специалисты из Check Point обернули свою головоломку в крипто-пакер, позаимствованный у какой-то малвари.
Как же будем угадывать число, загаданное часовщиком?
Есть два способа. Внутри бинарник зашифрован; запускаться под отладчиком он отказывается; если к нему к запущенному попытаться подключить отладчик — он моментально завершается. (64-битный «Диспетчер задач» для 32-битных процессов создаёт дамп эмулятора wow64cpu, с которым работать сложнее.)
Заглядываем в дамп и видим, что как минимум, строки в нём уже расшифрованы: Первый можно условно назвать «сила есть, ума не надо»: если программу нельзя отлаживать вживую — значит, будем отлаживать мёртвую!
Запускаем 32-битный «Диспетчер задач» (\Windows\SysWOW64\taskmgr.exe), кликаем по загадочному процессу правой кнопкой, и выбираем Create dump file.

Но строк ни с загаданным числом, ни с флагом пока не видно.
Переходим к орудию главного калибра: WinDbg (X86) -> Open Crash Dump…

Где в памяти та строка, которую мы хотим увидеть напечатанной — «Good job my friend!»?
Команда lm позволяет определить, что бинарник загружен от 01140000 до 015b2000; затем s-a 01140000 015b2000 "Good job my friend!" находит искомую строку по адресу 0115a0d0:

(s-b 01140000 015b2000 d0 a0 15 01)
Удача! Давайте теперь найдём, где эта строка печатается: может, в какой-нибудь команде содержатся байты d0 a0 15 01, соответствующие адресу искомой строки? — такая команда нашлась:

(ub 011412f7; u 011412f7) Что за код вокруг этой команды?

Пока непонятно, зачем там Sleep(); но на результат функции это всё равно не влияет, так что лучше разберёмся, что за строки сравниваются: Видим, что в зависимости от результата функции 01141180 печатается либо искомое сообщение, либо «Wrong one...»
Код функции 01141180 занимает три экрана; довольно легко понять, что это реализация strcmp(), внутрь которой добавлен вызов Sleep(700).

Проверим по стеку вызовов (k): Передаются два указателя, равные ebp-14h и ebp-24h; второй из них перед этим передавался аргументом в функцию 011410b0.
Не та ли эта функция, которая запрашивает загаданное число?

Его ebp нам уже известен из стека вызовов: Да, это именно она!
Общая схема головоломки теперь ясна: догадка пользователя сохраняется по адресу ebp-24h, загаданное число — по адресу ebp-14h, потом они сравниваются, и печатается либо «Good job my friend!», либо «Wrong one...»
Всё, что осталось — вытащить загаданное число из стекового фрейма.

Ну-ка, ну-ка…

Можно откупоривать что-нибудь вкусное. Успех!

Но остались без объяснения три загадочные вещи:

  1. Зачем внутри здешней strcmp() вызов Sleep(700)?
  2. Почему, когда мы ввели загаданное число, программа подвисла на десяток секунд, прежде чем напечатала «Good job my friend!»?
  3. Какое отношение ко всей этой головоломке имеет часовщик?

Так вот, оказывается, что есть второй — более интеллектуальный — способ отгадать загаданное число. Если просто пробовать наугад цифры 0-9, то легко заметить, что на девятке программа немножко «подвисает». Если пробовать числа 90-99, то можно заметить, что на числе 98 программа «подвисает» вдвое надольше. (Расковыряв её потроха, мы уже понимаем, в чём дело: успешное сравнение каждой пары символов вызывает задержку на 0.7с.) Чтобы решить головоломку, даже не запуская отладчик, достаточно было подбирать каждую следующую цифру так, чтобы задержка до ответа увеличивалась — либо вручную с точным секундомером, либо несложным скриптом. Таким образом составители намекали на давний способ атаки на криптографические алгоритмы, когда замеряется и анализируется время до сообщения об ошибке.

Но научиться расковыривать программы, обёрнутые неизвестными крипто-пакерами — на мой взгляд, и интереснее, и ценнее 🙂
Заметьте, что нам не потребовалось разбираться ни каким образом бинарник зашифрован, ни каким образом в стеке появляется строка с загаданным числом (мы видели в дампе, что среди строковых констант её нет) — и то, и другое мы сумели получить готовым, причём на всё про всё хватило дюжины команд WinDbg.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»