Pull to refresh

PHDays III CTF: взгляд изнутри (часть 1)

Reading time 13 min
Views 11K
23 и 24 мая 2013 года в рамках ежегодного международного форума по практической информационной безопасности Positive Hack Days III прошло одно из крупнейших соревнований по принципу Capture the Flag — PHDays III CTF. В этом году на организацию соревнования было потрачено очень много сил, и результат не оставил равнодушным ни одного из участников. По прошествии этого события мы решили рассказать о том, как проходила подготовка соревнования и представить взгляд из-за кулис.

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

При совершении успешной атаки на вражеский сервис команда получает некоторые секретные данные, называемые «флагом». Флаг является доказательством успешной атаки. Также, помимо сервисов, командам дается набор заранее подготовленных заданий, которые могут принести дополнительные флаги.

Начало подготовки


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

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

После разработки концепции легенды, пришел через игровой механики. Прежде всего мы определились с форматом соревнования: это должен был быть смешанный CTF с обычными тасками (Jeopardy CTF), сервисами (классический CTF) и нововведением — заданиями с ограниченным временем на решение и постоянно растущей ценой очков, которые мы назвали «босс-тасками». Данный формат, как нам кажется, позволяет широко оценить навыки участников и вносит в игру динамичность.

Далее нужно было понять, что игроки могут делать с заданиями и что за это получать. Всплыли такие термины, как сущности игры, активности и вовлечения игроков. Нарисовав на доске сущности и определив действия над ними, мы наконец-то смогли зафиксировать правила. Осталось только определиться с балансом игры — распределением очков за задания и внутренние игровые ресурсы игроков.

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

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

Чтобы не оставить никого в стороне, была необходима система, наглядно отражающая ход игры, да еще и так, чтобы ощущалось погружение в придуманный нами мир. Фактически эта система должна визуализировать зрителю игровые события почти в реальном времени. А поскольку речь идет об игре, то и выглядеть система должна как игра: красочные картины мира, стильные герои, красивые спецэффекты и неодинаковые (насколько это возможно) события. Всех нас посетила одна муза: хотим, чтобы игра выглядела как Heroes of Might and Magic, затронувшая не одно поколение. И было бы идеально, если бы мы смогли запустить ее на различных мобильных платформах!..

Выражаем отдельную благодарность Максиму Коробцеву (gametrek.ru) за большую помощь в разработке уникального гейм-дизайна и правил CTF.

Правила и игровые механики


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

  • 10 команд :),
  • 5 командных сервисов (шахты),
  • 3 общих сервиса (ничейные шахты),
  • 25 тасков,
  • 4 босса (злодеи).

Цель игры: набрать как можно больше золота. Побеждает самая «состоятельная» команда.


Схематичное отображение игровых механик (вариант 1)

Сущности игры:

  1. Раунд — пятиминутный интервал игрового времени. По истечению каждого раунда происходит просчет произошедших игровых событий, а также обновление флагов в сервисах.
  2. Флаг — некоторая секретная информация, которую можно найти в сервисах, тасках или боссах.
  3. Золото — элемент побочной подгруппы первой группы шестого периода периодической системы химических элементов Д. И. Менделеева с атомным номером 79. Также вид игровых очков, определяющий положение команды в рейтинге.
  4. Ресурс — вид игровых очков, получаемых от совершения действий над командными сервисами. Каждый сервис приносит свой вид ресурсов.

Виды ресурсов (в порядке увеличения стоимости):

  • дерево,
  • уголь,
  • железо,
  • нефть,
  • кристаллы.

Действия над ресурсами:

  • покупка / продажа ресурсов за золото (ресурсы могут быть куплены / проданы за золото, причем стоимость покупки ресурсов больше стоимости продажи);
  • покупка тасков (см. действия над тасками);
  • получение ресурса за поддержание своего сервиса в работоспособном состоянии (см. действия над командными сервисами);
  • получение ресурса за атаки на сервисы соперников (см. действия над командными сервисами).

1. Сервис — уязвимое приложение с обновляющимся один раз за раунд флагом, которое принадлежит одной из команд.
Действия над командными сервисами:

  • Поддержание в работоспособном состоянии своего сервиса.Если сервис находится в работоспособном состоянии, то каждый раунд он вырабатывает определенное количество ресурса для своего владельца.
  • Атаки на сервисы соперников. Команда может совершать атаки на сервисы соперников путем эксплуатации уязвимостей в их сервисах. Причем за успешную атаку, атакующая команда забирает часть выработанного за раунд ресурса команды-жертвы. Таким образом, чем больше соперников атакует команда, тем больше ресурса она получает.
  • Защита (патчинг) своего сервиса.Чем больше соперников успешно атакуют сервис команды, тем меньше ресурса она получит в конце раунда, поэтому ей необходимо защищать свои шахты, путем закрытия уязвимостей.

Количество очков, которое получают команды за сервисы, рассчитывается по следующим формулам:

  • Если команда украла чужой флаг, за него она получает 0,4* C/N, где C — общее количество ресурса, приносимого сервисом за раунд, а N — число команд, сдавших этот флаг, в том числе и команда-владелец сервиса, если сервис признан работоспособным.
  • Если команда является владельцем сервиса и он находится в работоспособном состоянии в течение всего раунда, команда получает весь оставшийся ресурс за вычетом украденного.

2. Общий сервис — это уязвимое приложение, с обновляющимся один раз за раунд флагом, которое не принадлежит ни одной из команд.

Действия над общими сервисами:

  • Атаки на общие сервисы. Команда может совершать атаки на общие сервисы путем эксплуатации уязвимостей в их сервисах. Причем за успешную атаку атакующая команда получает фиксированное количество золота.

3. Таск — это заранее подготовленное задание с одним флагом, требующее определенных навыков для его решения.

Действия над тасками:

  • Открытие (покупка) таска. Изначально все таски закрыты для команд. Доступна информация о стоимости таска, о вознаграждении и скиллах, необходимых для его решения. Для того чтобы начать решение задания, команда должна купить таск, потратив на него определенное количество ресурсов.
  • Решение таска.Если команда решила задание, то она получает определенное количество золота, зависящее от сложности задания. Также значения скиллов, требовавшихся для решения таска прибавляются к соответствующим скиллам команды.

4. Босс — это заранее подготовленное задание с одним флагом, с ограниченным временем жизни (3 часа), переменным вознаграждением и требующее определенных навыков для его решения.

Каждый раунд со всех команд собирается некоторое количество золота (налог), которое кладется в копилку боссу.

Действия над боссами:

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

5. Скилл (навык) — вид игровых очков, которые показывают:

  • какие навыки необходимы от игроков для решения конкретного таска;
  • какими навыками владеют игроки команды исходя из решенных ими заданий.

Виды скиллов:

  • Web — навык работы с Веб;
  • Reverse — навык обратного анализа;
  • Pwn — навык эксплуатации уязвимостей;
  • Forensic — знание криминалистических экспертиз;
  • Ucucuga — навык решения нестандартных / неочевидных заданий;
  • Crypto — знание криптографии;
  • Network — знание сетевой инфраструктуры и протоколов;
  • Misc — разнообразные навыки, не относящиеся ни к одному из предшествующих видов.

Действия над скиллами:

  • получение скилла за решение таска (см. действия над тасками);
  • получение скилла за решение босса (см. действия над боссами).

6. Ачивка (награда) — награда, выдающаяся команде за выполнение определенных требований. Всего в игре можно получить 42 вида наград.


Схематичное отображение игровых механик (вариант 2)

Сетевая инфраструктура


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

Проектирование


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

У каждой команды должна быть своя подсеть, причем запросы из одной подсети в другую должны скрываться за NAT, для того чтобы игроки не могли отличить атаки соперников от запросов жюрейской системы на основании IP-адреса.

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

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

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

Реализация


В качестве ядра сети был выбран коммутатор Cisco Catalyst 3750X 24, располагавшийся в серверной комнате. В него был подсоединен межсетевой экран Cisco ASA 5510, который также выполнял роль шлюза по умолчанию для всех сегментов сети CTF (команды, таски, сервисы, жюри). Он раздавал IP-адреса (DHCP) для всех компьютеров сети, обеспечивал трансляцию IP-адресов (NAT), разграничивал доступ к заданиям, а также обеспечивал доступ в Интернет.

С ядром сети был соединен коммутатор Cisco Catalyst 3750G 24, в который были подключены свичи D-Link DES-1008E десяти команд и жюри, каждый из которых принадлежал своему сегменту (VLAN).

Также в главный маршрутизатор было подключено два мощных сервера для интерактивных тасков, общих сервисов и жюрейской системы:

1. 2 processors, 4 cores, 64Gb RAM, 1Tb HDD.
На нем был поднят VMware ESXi с двумя виртуальными машинами. На первой работала серверная версия Ubuntu 13.04 с набором жюрейских сервисов:

  • Jury System,
  • User Interface,
  • все необходимое для функционирования сервисов.

На второй работал сервис визуализатора под управлением Windows 7.

2. 2 processors, 6 cores, 128Gb RAM, 1Tb HDD.
На нем также функционировал VMware ESXi, на котором работало 36 виртуальных машин:

  • 20 под интерактивные таски,
  • 3 под общие сервисы,
  • 13 под боссов.


Схема игровой сети 

Общая архитектура проекта


Как только легенда и правила были готовы, необходимо было приступать к проектированию общей архитектуры системы. Далее будет описано устройство площадки в целом, а также каждого отдельного компонента.


Схематичное представление общей архитектуры проекта

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

Flag Acceptor Interface — интерфейс приема флагов. Является подсистемой Jury System; представлен на данной схеме для отображения возможности команд сдавать флаги, украденные как с общих так сервисов, так и с сервисов оппонентов.

MongoDB — база данных игрового состояния. Здесь хранится и обновляется все актуальное состояние игры: очки, набранные командами, состояния заданий (открыты или закрыты для каждой из команд), полные описания самих заданий и боссов, продолжительность игры и пр.

User Interface (UI) — пользовательский интерфейс команд, реализованный в виде веб-приложения. Согласно правилам игры, команды могут открывать задания, покупать / продавать ресурсы, решать задания, получать информацию о текущем рейтинге и т. д. За эту функциональность отвечает UI. В качестве исходных данных для отображения берутся данные из MongoDB. Обработка запросов от пользователей реализована посредством RPC, построенным в свою очередь на AMQP.

Visualizer — система визуализации игрового процесса, аккумулирующая и отображающая игровые события. Поскольку не вся информация может быть передана через события, система берет некоторые данные из состояния системы в MongoDB.

Network Access Interface — интерфейс управления доступом к таскам. В начале игры все таски недоступны командам. Как только команда открывает какой-либо таск, ей открывается к нему доступ при помощи этого интерфейса.

Жюрейская система


Как было описано выше, Jury System (жюрейская система) отвечает за просчет игровой логики. При ее проектировании мы старались достичь следующие цели:

  1. Корректная реализация правил игры. Нельзя дать ни одному из участников как-либо читерить. Самым важным для нас являлось соблюдение правил игры.
  2. Стабильность работы. Во время игры участники не должны испытывать сложности при работе с жюрейской системой. Внезапные падения могут привести дисбалансу всей игры: шансы будут не равные и соревнование станет не объективным. По этой причине для достижения стабильной работы мы потратили много сил на тестирование.

    Для подстраховки мы создали специальную систему восстановления состояния игры после падения жюрейской системы.
  3. Скорость работы. По опыту игр в CTF мы знали, что промедления ответов от системы может стать роковым для команды, особенно если задание было решено в последнюю минуту. Чем быстрее система обработает запрос от пользователя, тем быстрее команда может приступить к следующему заданию.
  4. Безопасность. Наравне с корректным соблюдением правил, важным аспектом также являлась безопасность всей системы. В игре участвовали не простые программисты, а настоящие хакеры. Нельзя было допустить нелегального начисления очков или несанкционированного доступа :)

Цели обозначены, теперь можно расписать задачи жюрейской системы:
1. Обработка раундов

  • Согласно правилам, каждый раунд на сервисы команд должны «залиться» новые флаги, а по окончанию раунда, за все принятые от команд флаги должны быть начислены ресурсы. Флаги текущего раунда удаляются.
  • В конце раунда «снять» с команды налоги в случае, если есть активный босс.

2. Обработка пользовательских запросов

  • Реализация покупки / продажи ресурсов.
  • Обработка открытия / решения тасков.
  • Обработка решения боссов.

3. Прием флагов с сервисов от команд

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

4. Обработка логики работы боссов

  • Боссы должны быть вовремя запущенны и убиты. Время убийства босса является динамическим. После решения первой команды боссу останется жить 30 минут. Стоит напомнить, что максимальное время жизни босса составляет 3 часа.

5. Награждение команды ачивками

  • Мы придумали 42 различные ачивки, которыми могут быть отмечены команды. Все они основаны на последовательном выполнении участниками разного рода заданий, поэтому они в некотором смысле характеризуют тактику команд. Для реализации данной логики потребовалось больше всего запросов к базе данных, но по крайне мере, это весело :)


Архитектура жюрейской системы

Интерфейсы для работы с внешними компонентами:

  • Mongo Interface — интерфейс для работы с MongoDB. Изначально, планировалось сохранять в MongoDB текущий счет, чтобы UI мог быстро получать актуальные данные по рейтингу команд. Исходя из этой цели была выбрана MongoDB, поскольку она обеспечивает быстрое чтение. Запись в базу за все время игры происходит довольно редко и приурочено оно к внешним событиями (сдача командами флага, таска) либо к концу раунда (началу следующего).
  • AMQP Interface — интерфейс для работы с AMQP. AMQP был выбран в качестве протокола передачи сообщений. На основе этого интерфейса был реализован RPC со стороны UI и Event Manager для Visualizer и некоторых частей UI.

Сущности игры:

  • Teams — абстракция для описания команд,
  • Services — описание сервисов,
  • Bosses — описание боссов,
  • Resources — описание ресурсов,
  • Tasks — описание тасков.

Обработку логики над игровыми сущности берут на себя «игровые менеджеры». Хочется отметить некоторые их особенности реализации.

  • Flag Acceptor — сущность целиком и полностью отвечающая за прием флагов с сервисов от команд. По факту это обычный TCP-Server слушающий на определенном порту, имеющий по потоку на каждую команду с ограниченным числом соединений от команды. Отделение потока для команды оправданно малым числом команд (всего 10), а также распределением нагрузки: если какая то команда сдает флаги активнее другой, это не замедляет работу других в общем случае — планирование потоков дается на «откуп» ОС.
  • Boss Manager — сущность отвечает за обработку логики работы боссов. Пришлось немало сил потратить, чтобы аккуратно расписать логику работы даже в таких неигровых ситуациях, как перекрытие временных промежутков работы боссов. Однако данная логика оправдала себя во время отладки.
  • Event Manager — сущность, отвечающая за обработку всех игровых событий. На основе этой сущности была построена логика логирования игровых событий, которая позволила обработать собранную после игры статистику. Логировались абсолютно все игровые события, поэтому в некотором смысле возможно сделать реплей игры, но пока данная идея у нас не запланирована. Логи с игры могут быть выложены позже.
  • Service Checker Manager — сущность, отвечающая за проверку работоспособности сервисов команд. Пожалуй, тут стоит поподробней остановиться и расписать как происходит данная проверка.

Для проверки работоспособности сервисов, организаторами CTF заранее пишутся специальные программы, чекеры. Сервисы обычно абсолютно абстрактны и меняются от соревнования к соревнованию, поэтому чтобы иметь универсальный интерфейс работы с чекерами. Чекеры запускаются в отдельных процессах со следующими параметрами командной строки: команда {GET или PUT}, определяющая какое действие совершить — положить флаг на сервис или проверить его наличие, IP-адрес сервера, на котором проверяется сервис с флагом, сам флаг. По завершению работы чекер должен вернуть статус завершения:

  • 0 — сервис работает исправно;
  • 1 — сервис работает, но протокол не выполняется (флаг отсутствует);
  • 2 — сервис не работает (connection refused).

Поскольку за один раунд надо совершить 2 действия для чекеров — GET и PUT, они запускаются для всех команд 2 раза за раунд: PUT — в первую четверть раунда со случайной задержкой внутри четверти, GET — в третью четверть раунда со случайной задержкой внутри четверти. В момент запуска чекеров на выполнение команды PUT также выполнялось завершение всех чекеров, не успевших отработать к тому времени. Статус сервиса в таком случае будет отображать ошибку работы чекера.

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

Остальные компоненты не представляют особого интереса. Единственное, что хотелось бы отметить, это — система восстановления игры после падения. Для реализации этой функциональности пришлось сохранять многие игровые переменные во внешнюю базу. Поскольку большинство данных уже сохранялось в MongoDB, было решено добавить функционал сохранения оставшихся и восстановления их из БД.

Напоследок стоит отметить пару слов о реализации жюрейской системы. Вся система была написана на C++, поскольку это был наиболее популярный язык среди команды разработчиков системы. К тому же, автор свято убежден, что тот же код, написанный на Python, будет работать медленнее. В качестве фреймворка для разработки был выбран Qt, как наиболее удобный для выделенных под проект разработчиков.

Продолжение

Авторы: slim_d0g blackzert muodov ki11obyte Asperka

P. S. На сайте PHDays опубликована интереснейшая статья с анализом игрового процесса.
Tags:
Hubs:
+30
Comments 8
Comments Comments 8

Articles

Information

Website
www.ptsecurity.com
Registered
Founded
2002
Employees
1,001–5,000 employees
Location
Россия