Задание на РусКрипто’2011 CTF от Bushwhackers
Таки я за РусКрипто CTF пару слов хочу сказать. В 2010 году ребята из Positive Technologies задали высочайший уровень для РусКрипто CTF. К сожалению, в этом году новые организаторы не смогли соответствовать. В итоге получилось … кхм … Ладно. В итоге просто не получилось.
Подробности (плюс описание нашего задания) следуют далее.
Задания для игры придумывали сами команды-участницы. По идее команды могли сами договориться, разместить свои задания на своих серверах и провести тренировку.
Организаторы обещали использовать для оценки команд свою собственную хитрую методику, с блекджеком и т.д. Одной из “фич” методики состояла в том, что при равенстве очков между командами та команда, которая сделала неправильный submit флага последней, оказывалась в рейтинге ниже. Т.е. команда, которая ничего не делает, будет лучше команд, которые пытаются что-то решать. Nice.
Ну а теперь к описанию нашего задания. Задание специально делали многошаговое, при этом каждый шаг не требовал извращений а-ля “собрать каждый третий символ, потом взять каждый второй бит, полученное проинтерпретировать как морзянку, которую в свою очередь записать флажками, и т.п.” Как мы и предполагали, задание решили только к самому концу игры. По итогам голосования среди команд-участниц наше задание было признано лучшим. Мотивация сделать свой CTF возросла стократно.
Командам сообщается IP-адрес.
1) На хосте работает веб-сервер, который выдает приветствие “” и код, который
надо расшифровать:
+>>+>>+>>++>>++>>>>>>+>>+++>+++>+>+>>++>>>>>>+>>++>>+++>>>>+>++>++++>++>+>+>+++>>>++>++>>>+>>++>>>>>>+>>>++>>++>+>>>>++>+>>+>++>>>++>++>++++++>>>+>+>>>>>+>+>>>>+++>+>+>+>+>>++>>>>>>+>>>++>>++>+>>>>++>+>>+>++>>>++>++>++++++>>>+>+>>>>>+>>>>+>+>+>+++>>>+>+++>>>>>>+>>++>>+++>++>>>++>>+>>+++>+>+>>++>+++>+++>>>>>>+>>+>>++++>++++>++>+>+>+++>>+>>+++>>>>>>+>>++>>>++>++++>++>+>+>+++>>+>>+++>+>>>>++>+++>>++>+>+>>++>>>>>>+>>>>+>+++>++++>++>>>>>>+>>>>+>+++>>>>+>++>+>+>>++>>>>>>+>>++>>+++>>>+>+++>+>>+>++>++>>>++>++>+>++>+>>+>++>>+++>++>+++>>++>>>>>>+>>>>>>+++>>>++>++>+>>>>++>++>>>++>+>+>>++>>>++>+>>>+>+>>>>+>>>>>+>>+++>++>>>+>>++>>>>>>+>>>++>>++>++++>++>>>++>++>>>++>++>++++>++>+++>+++>>>>>>+>>>>+>+++>>>>+>++>+>+>>++>>>>>>+>>>>++>++>+>>+>++>>+++>++>++>+>++>>+>+++>>>>>>>+>>++++>+>>+>>++++>++++>++>+>+>+++>>>++>++>>>++>++>>+++>++>+>+>>++>>++>+++>+>+>>++>>+>>+++>+++>>++>+>+>+++>++>>+++>++>>+++>>>+>+++>>>>+>++>+>+>>++>+>+>+++>>+>>+++>>>++>++>>+++>+>>>>>+>++>>>+>+++>+>++>++>>>++>++>>+>+>>>>
Надо заменить > на 0, а + на 1, после чего полученное рассматривать как последовательность бит. После расшифровки получится следующее:
If we should fail?
We fail?
But screw your courage to the sticking place,
And follow the link: /youllnevergusstheurl.html
2) По ссылке /youllnevergusstheurl.html можно найти простейшее AJAX-приложение. По клику на кнопку оно посылает XML AJAX запрос сервлету по адресу /crazyurl, который возвращает ответ. В ответе повторяется одно из полей запроса. Веб-приложение уязвимо к атаке XXE (XML eXternal Entity).
Пользуясь уязвимостью XXE, нужно было считать файл /etc/shadow, в котором, среди прочих, была информация о пользователе ctfuser. У пользователя ctfuser пароль совпадает с логином.
3) В домашней директории пользователя ctfuser лежит файл get_flag, который можно запускать, но нельзя читать. Тут мы приложили максимум коварства и фантазии. Итак, запустив файл, команды попадают в Игру с Гусем. Суть игры – Гусь загадывает число от 1 до 100, задача команд – угадать число с 4 попыток. После каждой попытки Гусь отвечает, больше загаданное число, чем введенное, или меньше. Диалог выглядит следующим образом:
Hello, good sir!
I happen to be a monadic goose and I am thinking of a number.
However I am giving you an advantage which is a hint.
This number is positive and less than product $ replicate 10 2.
I offer you an astonishing adventure guessing this very number I am thinking of.

100
Number is less than I expected…
Maybe you ought to have another try.
By the way. You have 3 tries left

20
Number is less than I expected…
Maybe you ought to have another try.
By the way. You have 2 tries left

50
Number is greater than I expected.
Maybe you ought to have another try.
By the way. You have 1 tries left
30
Number is less than I expected…
Maybe you ought to have another try.
By the way. You have 0 tries left
You failed, good sir.
Что же в этом интересного, спросите вы? А вот что.
Если команда угадает число (ну вдруг!), никакого флага она не получит! Гусь просто от всей души поздравит победителя. Дальше – больше. Если ввести в качестве ответа очень большое число, программа выпадет с ошибкой сегментирования. При этом она это делает недетерминированно, как бы намекая на возможность переполнения. Это тоже ложный путь – никакого переполнения там нет.
А вот если запустить программу под strace, получится следующее:
$ strace get_flag 2>&1 | grep flag
open("flag: dontplaywiththegoose", O_RDONLY) = -1 ENOENT (No such file or directory)
Этот вызов выполняется в самом начале программы, перед первым вопросом Гуся. Т.е. флаг лежит совсем рядом! :)
Поздравляю команду [Censored] – они единственные решили наше задание. Молодцы!
Update. Еще отзывы о CTF, уже от участников: [1]
Вроде бы медведи тоже решили наше задание. Надо уточнить.
Хорошее задание получилось!
Спасибо! Уже есть идеи на новые – еще круче!
Credits:
Идея первой части задания(недошифрование) пришла в голову Александру Раздобарову, идея второй части – Андрею Петухову. Гуся придумывали всем миром, реализовал Федор Сахаров.
Реализация первой и второй частей, настройка игрового образа – ngo.
Disclosure: ngo – Это Георгий Носеевич :)
p.s. Спасибо, Гош – my fault, что сам не добавил.
Спасибо за задание. Оно, наверное, было единственным заданием от команды которое решила лишь часть участников.
Уточка получилась особенно коварной, я час пытался её переполнить =)
Это Гусь!!!!
ps. Спасибо за отзыв