StepCTF’15: как мы проводили CTF на Stepic

image

В данный момент на просторах интернета, к сожалению, не так и много статей и отчетов о CTF-соревнованиях (да и о соревнованиях и олимпиадах в целом), написанных от лица самих организаторов. Чтобы хоть немного исправить это недоразумение, мы (PeterPen, команда по информационной безопасности из СПбГУ) хотели бы описать свой опыт проведения индивидуального CTF-соревнования StepCTF 2015, прошедшего 11 и 12 мая 2015 года. В программе: как готовились, как проводили соревнование; также расскажем о полученных уроках, дабы предостеречь и/или облегчить жизнь потенциальным организаторам.


CTF (Capture The Flag) — соревнования по информационной безопасности, проводимые в «игровой» форме: отдельные участники или команды соревнуются, применяя весь арсенал имеющихся знаний и умений для добычи «флагов» (отсюда и название), за которые и начисляются победные очки. CTF, как правило, бывает двух видов:

  • Классика: каждой команде выдаётся сервер с набором сервисов, которые нужно поддерживать в рабочем состоянии, чтобы жюри могло загружать на сервисы флаги. Разумеется, у этих сервисов имеется набор уязвимостей, эксплуатируя которые, можно эти самые флаги воровать.
  • Task-based / jeopardy: как следует из названия, такая схема во многом похожа на известную телевизионную игру «Своя игра» (Jeopardy). Есть несколько категорий, в каждой есть несколько задач различной сложности. Чем сложнее задание, тем больше очков оно принесет. В отличие от классики, task-based CTF бывают как командные, так и индивидуальные.


CTF-ы команда PeterPen устраивает уже не в первый раз: в 2013 и 2014 году мы организовали индивидуальные онлайн-контесты SpisokCTF 2013 и SpisokCTF 2014 соответственно, оба — в рамках конференции СПИСОК, проводимой на матмехе СПбГУ. Получили первый опыт подготовки соревнований, написали свою платформу для jeopardy CTF, успели набить не одну шишку, и в этом году решили продолжить традицию, но немного в другом формате: устроить онлайн CTF-соревнование на образовательной платформе Stepic.

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

На общем обсуждении в итоге решили: «а почему бы и не Stepic?». Действительно, практически все необходимое в нем уже было, включая базовые вещи вроде новостей, комментариев, управления пользователями и т.п. Если кратко рассмотреть структуру образовательных материалов на Stepic, то самая большая единица — это курс, курс состоит из модулей (частей курса, например, по неделям), каждый модуль состоит из уроков, а урок в свою очередь состоит из последовательности шагов, или «степов». Степом может быть страница с текстом или видео, или одним из типов задач, таких как выбор правильного варианта из предложенных, задача на программирование, задача, в которой нужно ввести правильный ответ в текстовое поле и др. Теперь попробуем из такой структуры материалов сделать CTF-соревнование. Курс — соревнование, модули — категории задач, уроки в модуле — задачи в соответствующей категории, один степ в уроке — непосредственно сама задача. Из существенного не хватало только рейтинговой таблицы участников, которая была добавлена в Stepic до запуска соревнования.

340fdeeecc9d42fe972b9e60c0732721.png


Сразу немного цифр: в соревновании, продолжавшемся 36 часов, приняло участие 193 участника из разных городов России и СНГ, которым было предложено 21 задание, разбитые на 6 категорий.

В этом году команда организаторов (почти все — студенты, аспиранты и выпускники матмеха СПбГУ) была территориально разбросана: задания придумывались в России, Беларуси, Швейцарии. Серьезных трудностей во втором десятилетии XXI века это не вызвало: для общения и обсуждения заданий использовался замечательный сервис Slack, для самих заданий был создан приватный репозиторий на Github (в данный момент он очень даже публичный). В репозитории сразу утвердили единый формат оформления заданий, чтобы разработчик, не являющийся автором задания, знал, например, где лежит описание, а где — решение.

Чего нам не хватило, так это единого хранилища со всеми соглашениями, правилами, используемыми утилитами и т.п. Даже с командой из разработчиков в 9 человек пришлось несколько раз объяснять одни и те же вещи (куда что заливать, как разворачивать сервисы, что такое Docker) только лишь потому, что некоторые подключались к разработке чуть позже остальных. Для таких целей хватит и простенькой wiki; гитхабовская, думаем, подошла бы на «ура».

Неприятной особенностью Stepic оказалась открытость содержания курса до его начала. Это общепринятая практика в массовых онлайн курсах, но она никак не подходила под наш формат: мы же не хотим показывать список категорий и названия и количество задач в них до начала соревнования. Чтобы обойти это ограничение было на самом деле создано два курса (соревнования): один — публичный, в который записывались участники и второй — приватный, куда организаторы добавляли задачи до старта. Перед самым стартом модули и уроки из приватного курса были просто скопированы в публичный.

В Stepic также был дописан скорборд — рейтинговая таблица участников, отсортированных по убыванию набранных очков. Его не было, потому что для онлайн курсов он обычно и не нужен.

d59a67bc0ab84770be6eaa667c3913f6.png

Удобной оказалась возможность прикреплять файлы («аттачменты») в Stepic. Раньше мы шарили директорию в Dropbox для хранения файлов, связанных с заданиями, а в случае StepCTF мы их хранили как аттачменты к курсу-соревнованию или к конкретным заданиям. Получилось удобно: задачи и файлы находятся в одном месте, на одной платформе, доступны всем организаторам.

Для интерактивных заданий — тех, которые принимают соединения по сети, например, веб-задания — мы завели отдельный сервер: простейший VPS от Hetzner. Чтобы всё было более-менее безопасно и устойчиво к сбоям, каждое интерактивное задание также обернули в Docker-контейнер, который автоматически перезапускался при падении сервиса. Использование контейнеров позволило разделить ответственность разработки сервиса и его запуска на сервере. Разработчик полностью отвечал за подготовку Docker-образа с нужным окружением для запуска своего сервиса: использовал любимый дистрибутив linux, устанавливал необходимые версии языков, фреймворки, библиотеки и другие зависимости. С таким подходом на общем VPS-сервере не требовалось ничего устанавливать или обновлять глобально — был порядок. За удобство и порядок все же пришлось заплатить немалым временем, потраченным на изучение Docker«а и подготовку работающих образов.


Хорошие задания (в данном контексте также прижился удобный короткий англицизм «таски») — основная цель любого task-based СTF. Всегда хочется, чтобы они получились интересными, разнообразными, и чтобы участники могли открыть для себя что-то новое во время или после решения. И в этом состоит главный вызов организаторам, особенно в соревнованиях начального уровня: хочется дать что-то вроде SQL-инъекции или шифра Цезаря, но потом понимаешь, что в самом простом виде задания такого рода уже предлагались не один десяток раз в других CTF-ах. И, разумеется, именно при подготовке к приближающимся соревнованиям фантазия начинает отказывать, что увеличивает количество потраченных нервов. Идеи тасков могут возникать спонтанно, даже когда никаких соревнований на горизонте нет, поэтому разумным шагом является постоянный сбор интересных идей и их оформление в виде конкретных заданий в преддверии CTF-а.

Как это обычно принято, мы разделили таски на категории, чтобы участник хоть приблизительно понимал, с чем имеет дело. В нашем случае, мы выделили шесть категорий:

  • Admin (4 таска) — задания на администрирование в индивидуальных линукс-терминалах. Они заслуживают отдельного описания, поэтому про них — чуть ниже.
  • Crypto (4 таска) — задания, связанные с криптологией
  • Forensics (3 таска) — задачи в области цифрового криминалистического анализа
  • Stegano (3 таска) — стеганография: сокрытие информации в картинках, видео и т.п.
  • Reverse (5 тасков) — задания на обратную разработку (или реверс-инжиниринг, если «по-русски»)
  • Web (2 таска) — требуется найти флаг, проэксплуатировав уязвимость в веб-приложении


В глаза может броситься разное количество заданий в некоторых категориях: например, тасков на reverse было целых пять, а web оказался обделенным. Налицо распределение (не слишком равномерное) предпочтений и интересов разработчиков соревнования.

Таски из категории Admin мы сделали с помощью особого типа заданий Linux Challenge на Stepic. В таком задании участник получает индивидуальный запущенный в облаке linux-сервер и подключеный к нему веб-терминал у себя в браузере. Выполняя команды в терминале, необходимо решить предложенное задание. Подробнее про то, как устроены Linux-задания на Stepic, уже писали. Технология довольно классная, хорошо подходит для создания живых admin-заданий для тасковых CTF. В StepCTF мы предложили участникам несколько задач на администрирование Linux, в которых нужно было:

  • Отыскать возможность в терминале прочитать файл flag.txt на сервере, в котором были удалены стандартные широкоизвестные утилиты, такие как cat, less, tail, head, strings, vi.
  • Установить и настроить веб-сервер Nginx с поддержкой TLS, используя выданный нами сертификат.
  • Восстановить удаленный файл из памяти процесса.
  • Настроить почтовый сервер и принять письмо с флагом от проверяющей системы.


8e60d2ea9680433597c83871ccdbc4ba.png

Оценивание и определение сложности заданий — больная тема тасковых CTF. То, что для автора задания кажется простым, может оказаться просто недоступным для логики обычного человека. Как пример, задание Passgen, оцененное автором в минимальные 100 баллов, оставалось нерешенным гораздо дольше, чем хотелось бы, в то время как web-задания в 200 или 300 баллов решались участниками довольно активно. Таким образом, важно разумно оценить задания не только в пределах одной категории, но и в целом: не дело, если reverse на 100 в несколько раз сложнее задания той же стоимости, но из другой категории.

Основная причина нечестно оцененных тасков — в недостаточной прилежности организаторов, что уж тут скрывать. В нашем случае несколько выложенных заданий толком не проверил никто, кроме автора, что привело к необходимости исправлять ошибки и изменять стоимость задания прямо во время контеста. Уже после завершения StepCTF (лучше поздно, чем никогда) у нас сформировалась следующая идея, которую мы окрестили «таск-ревью»: задание не публикуется на сайте соревнований, пока его не прорешало определенное число организаторов (скажем, два или три). Этот подход будет мотивировать как решать чужие таски, так и пинать людей, чтобы они решали твои.

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

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


Пара слов про флаги — то, ради чего участники и решают задание. Найдя флаг (по сути, просто строку символов), его можно сдать на соответствующей странице задания, получив в обмен очки, которые повышают участника в общем рейтинге. По опыту прошлых лет, мы решили зафиксировать формат флага (выбор остановили на регулярном выражении /STCTF#\w{6,}#/), чтобы облегчить жизнь участникам, о чем и сообщили через систему оповещений Stepic вскоре после начала соревнований. Тем не менее, этого оказалось мало: мы получили не одно письмо, в котором участники утверждали, что задание решили и флаг нашли, но он не принимается проверяющей системой. На деле оказывалось, что люди либо не видели сообщение про формат флага, либо путали некоторые похожие символы (0 и О, заглавная i и строчная L и т.п.), когда переписывали флаг в поле ответа. Мы отсюда урок вынесли такой: единый формат флага, объявленный заранее и на видном месте, — хорошо; нули и другие «проблемные» символы во флагах — не очень.
Допустим, что все задания подготовлены, приемлемое количество участников зарегистрировано, и CTF наконец начался. Не время расслабляться, потому что пришло время отвечать на вопросы участников, публиковать подсказки, а также исправлять ошибки в заданиях, которые, к сожалению, могут проявиться и после начала. В случае StepCTF было предоставлено целых три способа для связи с организаторами: комментарии на Степике, IRC-чат на freenode.net и электронная почта. Про первый вариант нужно упомянуть отдельно хотя бы потому, что участники несколько раз «оставляли» флаги в комментариях вместо специально предназначенного текстового поля. Надеемся, что это все-таки происходило по ошибке, а не по злому умыслу. Сообщения такого рода оперативно удалялись организаторами, но как недочет графического интерфейса Степика мы данное поведение зафиксировали. Ребята из Stepic подтвердили, что такое случается и во время прохождения студентами курсов, обещают в будущем исправить этот недочет в интерфейсе.

Разнообразие вариантов связи, конечно, удобно для участников, но немного усложняет работу организаторам. Необходимо одновременно следить за всеми вариантами и стараться оперативно отвечать. Когда количество участников сильно больше количества организаторов, то отвечать каждому лично становится крайне затруднительно. Использование коллективных средств связи вроде комментариев на Stepic или IRC-чата позволяет хранить ответы на заданные вопросы и не отвечать дважды на одно и то же. Тем не менее, мы укрепились во мнении, что стоит ограничиться каким-нибудь одним способом связи с организаторами, тогда вопросы участников не будут пропущены и оставлены без внимания, а организаторам станет жить легче.

Немаловажно до начала соревнования договориться в команде организаторов о том, в какое время каждый организатор и автор тасков будет доступен для связи онлайн. Это особенно важно, когда соревнования длятся больше суток. Не должно возникать ситуации, когда автор таски пошел спать, а в его задании есть баги, о чем жалуются участники, и никто кроме автора не в состоянии исправить их или ответить на вопросы. В идеале, в любой момент времени кто-то из организаторов должен быть онлайн, и должен быть установлен способ оперативной связи с любым из авторов тасков. Авторам в свою очередь следует добросовестно относится к поддержке своих тасков и оперативно подрываться по требованию, даже если на часах 4 часа ночи (ситуация усложняется, когда команда организаторов распределенная, как было в нашем случае).

Еще один важный момент: необходимо своевременно информировать участников о любых изменениях и обновлениях по ходу соревнования. Например, выкладывание новых заданий, исправление старых или добавление подсказок должны сопровождаться рассылкой соответствующих уведомлений. А вообще говоря, нужно заранее оговорить регламент: к примеру, участники имеют право знать до начала, сколько всего задач их ожидает и когда они будут опубликованы.


Казалось бы, после окончания соревнования организаторам можно смело выдохнуть и пойти отдыхать. Важно, однако, собрать отзывы участников и устроить разбор полетов — задокументировать допущенные ошибки и возникшие проблемы, пока ничего не забылось и не потерялось. Может быть непросто собраться с силами, потому что впереди уже нет никакого дедлайна. Яркий пример этого явления — данная статья, завершенная позже, чем хотелось бы.
Большинство уроков, которые мы вынесли (например, про флаги или таск-ревью), были даны в соответствующих разделах, в заключение же хочется выделить основные моменты.

  • Проводить соревнования на платформе Stepic — можно. В этом плане StepCTF 2015 был первопроходцем, но даже принимая во внимание все трудности, мы можем твердо сказать, что эксперимент удался. Stepic предоставляет бесплатную для всех платформу, где можно проводить как курсы, так и соревнования, так что это хороший вариант, если есть идеи для задач, но не хочется разрабатывать и поддерживать свою платформу.
  • Многое (а точнее, очень многое) зависит от состава команды организаторов, их мотивации и способности взять на себя ответственность. Дисциплина и налаженный рабочий процесс необходимы как во время соревнования, так и при подготовке и подведении итогов. Как следствие, можно избежать многих проблем, которые всплыли во время соревнования; например, большинство ошибок в заданиях можно было поймать при предварительном их прорешивании другими организаторами.
  • Несмотря на все вышесказанное, не стоит забывать, что CTF — это дружба ;) И участники, и организаторы хотят получить и заряд веселья, и новые знания. Избежать всех ошибок и проколов нельзя; можно минимизировать их количество, но оставшиеся не должны повлиять на качество и атмосферу соревнования.


Приятно видеть, что CTF-движение активно развивается, и все большее число команд берет на себя смелость проводить свои соревнования. Тем не менее, многие команды сталкиваются с одними и теми же задачами и трудностями во время подготовки. Поэтому призываем не только участвовать в разработке новых CTF-соревнований, но и делиться опытом их организации и проведения.

Ссылки


Авторы статьи: rev112 psviderski

© Habrahabr.ru