Решения
http://f00l.de/blog/?p=1803 (Rup0rt) | Назад к списку заданий |
Задание (binary)

Подробное описание
Условия задания: "Для тех, кто не играл в plaidCTF 2012: "supercomputer" была задачей на реверс, в которой флаг считался, используя простейшую математику (например, умножение заменяем сложением в цикле). hypercomputer легче… если вы всё делаете правильно :Р Подключение: ssh 54.224.174.166" Инструменты: виртуальная машина с х64 Linux на борту, IDA. Что ж авторы говорят, что будет легко. Приступим. Подключаемся по ssh и скачиваем бинарный файл hypercomputer.
… это 64-битный исполняемый файл Linux. Поэтому просто запускаем его:
То бишь "Добро пожаловать в Hypercomputer! Это займет очень много времени". Интересный момент здесь такой. Текст появляется не сразу, а с ощутимыми задержками и по несколько символов. А после вывода всего текста, программа, кажется, зависла, пришлось сбрасывать. Можно предположить, что остальное время занимает расчет и вывод флага. В прошлом году, код задачи supercomputer надо было исследовать и оптимизировать вручную, видимо, без отладки здесь не обойтись. Первый помощник в таком случае - это strace. Работа strace заключается в перехвате и записи системных вызовов, выполненных процессом, а также полученных им сигналов. И strace в нашем случае подскажет, что такое долгое она там выполняет:
Как видим, очень часто исполняется функция nanosleep(), которая блокирует поток на время, не меньше заданного. В прошлом году таким же образом тормозилось выполнение программы. Поэтому наш первый шаг - удалить все вызовы nanosleep() из исполняемого файла. Загружаем наш файл в IDA. Выясняется, что nanosleep оказался вызов usleep: .plt: 0400770 ; "переходник" к int usleep(__useconds_t useconds) .plt: 0400770 _usleep proc near .plt: 0400770 FF 25 FA 68 20 00 jmp cs:off_607070 .plt: 0400770 _usleep endp Удаление всех вызовов usleep сделать просто: надо заменить "переходник" FF 25 FA 68 20 00 на оператор возврата ret (0xC3) и nop (0x90) C3 90 90 90 90 90 Но не спешите выходить из IDA. Если полистать код, то заметим, что очень часто встречается такая конструкция: mov eax, константа loop: sub rax, 1 jnz loop Заменяем цикл 48 83 E8 01 75 FA на 90 90 90 90 90 90 И такая: mov eax, 0 loop: add rax, 1 cmp rax, rdx jnz loop Заменяем цикл 48 83 C0 01 48 39 D0 75 F7 на 90 90 90 90 90 90 90 90 90 Пишим небольшой скрипт замены: list_z = [ "\xFF\x25\xFA\x68\x20\x00", "\xC3\x90\x90\x90\x90\x90", "\x48\x83\xE8\x01\x75\xFA", "\x90"*6, "\x48\x83\xC0\x01\x48\x39\xD0\x75\xF7", "\x90"*9, ] binary = open("hypercomputer", "rb").read() for i in range(0,6,2): binary = binary.replace(list_z[i],list_z[i+1]) open("hypercomputer_", "wb").write(binary) Запускаем результат на исполнение и получаем флаг:
|