Друзья, продолжаем публиковать решения нашего CTF-марафона! В нем было пять уровней сложности, в каждом по пять заданий — всего 25 заданий. Каждую неделю мы выкладываем по 5 решений — сегодня рассказываем о третьем уровне сложности. Предыдущие уровни вы можете изучить здесь: часть 1, часть 2.  Результаты марафона мы подвели в начале апреля, но задания все еще доступны — и вы можете попробовать решить их для себя. Таск проверяет понимание работы ассемблера и знания о байт-коде в целом. В задании дан шелл-код — открыв его байт-код в Hiew и выставив размер инструкций на x32, можно увидеть следующую картину: Чтобы получить флаг, нужно прочитать ASM, взять дворды и с помощью xor поделить их на «ключи» в виде двордов рядом. Получаем флаг: “DrWeb{5h3ll_u53r_}”. В задании дается небольшая текстовая игра на Linux: Если ввести в качестве ответа рандомный набор символов, то игра заканчивается выдается один из вариантов ответа: Для первого задания просто можно найти вшитый ответ плейн текстом, так что ищем его и вставляем:  Теперь нам уже надо найти два ключа, и в этот раз они не вшиты простым плейнтекстом в код.  Если ввести рандомный набор символов, игра дает такой ответ: Так как сбрутить не получилось, нужно смотреть код После того как не получилось сбрутить идем и смотрим код, находим две функции подобного формата, обе из них расшифровывают ключи путем обычного xor с ключом “11111111” Получаем два ключа: “0---open” и “door---0”: Переходим на третий уровень: Пытаемся что-то угадать и победить дракона:  Иногда, на рандоме что-то даже получается, но только на рандоме:  Проанализировав код, можно понять принцип, по которому работает эта битва: Оказывается, битва с драконом — последний уровень, и правильные результаты сразу пойдут во флаг: Флаг формируется по такому принципу: DrWeb{[A-H][P-Z][#$%&][a-h][p-z]}. Формируем флаг: “DrWeb{AH#er}”. У каждого участника он может быть разным. Совсем не сложное задание, если знать, что тут можно сделать. 😊  Скачиваем файл, открываем, видим следующую картинку в формате .png:  В картинке нет ничего лишнего, в ней ничего не зашифровано, это просто изображение, причем не самого большого размера. И чтобы найти флаг, нужно провести определенный рисерч.  В одном из первых заданий был использован эзотерический язык LOLCODE — и если вспомнить об этом и изучить, какие еще бывают эзотерические языки, можно найти язык Piet. Добавим от себя, что писать на этом языке было очень нетривиальной задачей! 😊 Если предположить, что файл написан именно на этом языке, можно попробовать решить задание. Для этого нужно использовать специальную утилиту для запуска Piet — например, эту. Также можно использовать тулзы с GitHub. Так выглядит сайт, который выбрали для работы мы: Загружаем наше изображаение, открываем дебаггер, нажимаем запустить и смотрим: Дальше остается только ждать, когда вся программа исполнится: Флаг: “DrWeb{P41n7_M3_70_7h3_P137}”. В задании дается игра, в которой somewhere in malware lands… Для того, чтобы найти флаг, нужно выполнить несколько условий, которые, очевидно, невыполнимы: Набрать 65535 монет. Опустить количество своих жизней до нуля. Уничтожить всех врагов. Для решения задания важно отметить подсказку, которая дается при открытии файла — это Godot: Поэтому, чтобы решить таск, есть два инструмента: декомпиляция Godot и Cheat Engine. После декомпиляции, в отличие от Godot-игры, которая была на предыдущем уровне марафона, мы получаем обфусцированный код: Код был обфусцирован вручную, и деобфускатора в открытом доступе нет. Можно попробовать с помощью логики восстановить скрипт и отыскать ключ, а можно попробовать отдебажить код — запустить проект в Godot и во время дебага менять значения переменных, подобно Cheat Engine. Выполнить первое условие и накрутить количество монет достаточно легко, так как счетчик может постоянно обновляться. Для этого нужно запустить Cheat Engine для поиска количества текущих монет и после того, как были подобраны новые монеты, запустить новый поиск и отсортировать результаты. Первое условие выполнено.  В результате получаем такую подсказку, которая намекает, что необходимо делать дальше: Далее требуется найти переменную, которая отвечает за жизни персонажа. Сделать это получится методом тыка — и после того, как нужное значение найдено, его нужно поменять на ноль. Второе условие выполнено.  Меняем параметры, чтобы спустить хп до нуля:  Чтобы выполнить третье условие, нужно уничтожить всех врагов, однако есть проблема — часть из них сидит в «бункере», куда персонаж не может спуститься: Нужно найти параметры, которые отвечают за координаты персонажа, — и если поменять их, получится телепортироваться в «бункер». Координаты оказываются даже не обфусцированными: Методом проб, ошибок и застреваний в стенах получается поместить персонажа в нужное место и уничтожить противников: Третье условие выполнено — и в одной из переменных находим флаг: После чего уже достаем флаг: “DrWeb{Pl4y_64m3_Ch347}”. В задании дано два файла: исполняемый файл и ticket.png. Изображение билета выглядит так — причем важно отметить, что срок действия «билета» истек: Посмотрев на билет через hex-редактор, можно увидеть фрагмент, которая отвечает за верификацию билета: Размер XML явно меньше, чем этот xml_size, но код и не проверяет корректность XML, на этот параметр можно не обращать внимания — возможно, размеры съехали из-за ошибки с кодированием файла. Выясняется, что файл смотрит на следующие конструкции: “<is_valid?> </is_valid?>”, “<valid_until> </valid_until>”, “<key> </key>”. IDA была не очень в восторге от оптимизированного кода, но его детальное восстановление и не требуется — конструкции не настолько сложные: строкам std::string присваивается значение из c_str.  Можно увидеть проверку на валидность флага — она происходит в “<is_valid?> </is_valid?>”: Также есть валидация по времени: Теперь можно перепрыгнуть валидацию в отладчике — либо пропатчить «билет»: С такой конфигурацией программа пропускает тикет. Затем по адресу 00401970 находится фрагмент, который расшифровывает некий пейлоад ключом, который был передан через билет. Если открыть его код, можно увидеть, что он подгружает адреса функций RegCloseKey, RegCreateKeyExA, RegOpenKeyExA, RegSetValueExA для использования в пейлоаде. Самих значений ключей не видно — пейлоад вшит не просто так. Теперь известно, что запись будет происходить в ключи реестра, и поэтому самый простой путь — не реверсить шелл-код, а запустить procmon и найти там наш экзешник. В результате дается новый ключ в реестре, флаг оказался вшит в него. Флаг: “DrWeb{R3g1s7r0g3d0n}”.