В этом году я участвовал в PACTF (Phillips Academy Capture the Flag Challenge), ежегодном онлайн-соревновании по компьютерной безопасности. Хотя соревнование ориентировано на учащихся средних и старших классов, предлагаемые задачи варьировались от простых (10 баллов) до чрезвычайно сложных (100 баллов). Судя по этой отличной статье о проблеме Skywriting, эта задача не была решена ни одной из команд, имеющих право на получение приза. Если вам интересно (или вы не верите мне, что некоторые задачи были на самом деле довольно сложными!), вы можете проверить свои навыки здесь. В итоге нашей команде (состоящей из студентов университета) удалось решить большую часть задач в 1-м и 2-м турах, заняв 43-е и 133-е места соответственно из примерно 1000 команд, набравших не менее 10 баллов.

Поскольку это событие проходило во время очень напряженного для меня финального сезона, у меня не было времени поработать над таким количеством задач, как мне бы хотелось (остальная часть команды несла большую нагрузку). Тем не менее, я хотел написать об одной особенно интересной задаче, ИИ, которая во втором раунде набрала 80 баллов. Лично я не думаю, что она стоила 80 баллов с точки зрения сложности, а только из-за того, насколько она была длинной. Вот описание проблемы:

Наш инженер по искусственному интеллекту сделал революционное открытие, но неожиданно покинул компанию… все, что у нас есть, это запутанный source.txt

Если вы хотите попробовать свои силы, прежде чем читать мое решение, пожалуйста, сделайте это! В противном случае читайте дальше.

Решение:

Первая часть очень похожа на многие задачи CTF ранее. Вам дан длинный текстовый файл, содержащий только следующие шесть символов: ()[]+! Для тех, кто знает о странной и эзотерической природе JavaScript, кажущаяся случайной последовательность скобок и знаков препинания на самом деле является действительным JavaScript. При входе в Node.js или в консоль браузера вы увидите следующий вывод консоли.

"Поздравляю! Вы раскрыли правду. Теперь перейдите сюда: URL/ai.zip”

Распаковав файл, вы получите следующую структуру каталогов:

Таким образом, это выглядит как довольно простой веб-сайт с html, css и js. Открытие index.html показывает поддельный терминал MacOS, с которым нельзя взаимодействовать каким-либо образом. Открытие консоли, кажется, не обнаруживает ничего необычного, кроме отсутствующего favicon.ico, что в настоящее время довольно распространено.

Вместо этого мы можем погрузиться в script.js, который кажется единственным подходящим файлом, поскольку baffle.min.js и typed.js являются сторонними библиотеками.

При быстром просмотре script.js наиболее релевантной строкой оказалась строка 160.

append_ai('Ключ теперь надежно хранится в ("http://ibarakaiev.shpp.me/pactf_s7fj43/key_%d.txt'), get_key_number(6, [16, 23, 16, 15, 42, 8 ])).', 30, 300);

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

Вот краткое изложение того, что вы должны делать. Во-первых, раскомментируйте строку 3, которая заполняет поддельный терминал командами псевдооболочки. Это запускает программу «ИИ», которая может определить разницу между собаками и не собаками.

В строке 134 в функции launch_artificial_intelligence(stupid) есть оператор if «if (stupid)», который запускает классификатор собак. Измените строку 102 на launch_artificial_intelligence(false) или просто полностью раскомментируйте блок if в строке 134. При обновлении страницы снова просматривается весь анимированный текст терминала с остроумным намеком на недавний скандал с данными Facebook.

Это приводит к тому, к чему мы уже пришли выше, но более окольным путем. Я предположил, что, поскольку модификация кода не была очень сложной, она не имела большого значения в любом случае, но это еще один пример того, почему аутентификация/обфускация на стороне клиента не очень хорошая идея (я расскажу об этом подробнее). в будущей статье). Возвращаясь к функции, она сначала кажется несколько сложной, с переменными p и q, которые могут странно напоминать шифрование RSA. Оказывается, это не так, и все, что от нас требуется, — это просуммировать элементы в массиве (вероятно, цель состоит в том, чтобы научить студентов внимательно читать комментарии).

Итак, переходим по указанной ссылке, заменив %d на 120. Это дает ссылку на этот файл:

Эта часть, пожалуй, самая сложная часть проблемы. По сути, они дали нам строку, которая использует не байты, а «byfes», а также соответствующее преобразование между ASCII и PACTFSCII. Чтобы подойти к этому, нужно рассмотреть соотношение между обычным ASCII (0–255 или 2⁸) и PACTFSCII (0–32 или 2⁵). Поскольку в заданной строке 8 символов (игнорируя завершающий \0), а каждый символ в PACTFSCII составляет 5 бит, путем преобразования в двоичный формат с использованием таблицы у нас есть 40 бит для работы: «01100 10001 10111 10110 01110 11001 11011 01111».

Затем, если вы соедините биты напрямую и сгруппируете их в группы по 8, у нас будет 5 байтов, которые четко преобразуются в 5 байтов символов ASCII:

«01100100 01101111 01100111 01100111 01101111» = «собака»

И это все! Опять же, эта проблема определенно не была такой сложной, как некоторые другие проблемы, с которыми мы столкнулись (опять же, взгляните на рецензию Skywriting), но я нашел ее довольно забавной и увлекательной.

В будущем я постараюсь опубликовать рецензии для некоторых других CTF, так что будьте начеку. Спасибо за чтение!