Skip to content

Latest commit

 

History

History
75 lines (43 loc) · 8.99 KB

farm_client.md

File metadata and controls

75 lines (43 loc) · 8.99 KB

Клиент фермы

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

Клиент представляет собой однофайловый скрипт start_sploit.py из данного репозитория.

Установка и запуск

Для работы клиента требуется Python 3 и ОС Linux, macOS или Windows. Клиент не требует установки каких-либо библиотек.

Установить клиент в Linux и macOS можно командой:

wget bit.ly/start_sploit_v2 -O start_sploit.py && chmod +x start_sploit.py

В простейшем случае эксплоит может быть запущен следующим образом:

./start_sploit.py sploit.py --server-url http://10.0.0.1:5000

Здесь sploit.py — файл с эксплоитом, http://10.0.0.1:5000 — адрес, по которому доступен сервер фермы.

Следить за работой эксплоита можно с помощью вывода клиента фермы или через веб-интерфейс сервера, доступный по адресу из опции --server-url.

Алгоритм работы

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

Количество процессов с эксплоитом, работающих одновременно, не может превышать значение опции --pool-size (стандартно — 50 процессов). Это ограничение позволяет избежать заполнения всей доступной оперативной памяти (и последующего зависания компьютера) на соревнованиях с большим количеством команд (например, в RuCTFE может участвовать более 400 команд) или в случае ресурсоёмких эксплоитов.

В соответствии с описанными параметрами, максимальное время работы (time limit) для одного процесса с эксплоитом рассчитывается как attack_period / ceil(len(teams) / pool_size) (и выводится в начале каждой атаки). По истечении этого времени клиент фермы убивает процесс.

Во время работы эксплоита клиент следит за его выводом и, как только в выводе появляется подстрока, удовлетворяющая формату флага, добавляет её в очередь на отправку на сервер. Одни и те же флаги не добавляются в очередь дважды. Содержимое очереди отправляется на сервер фермы каждые 5 секунд.

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

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

Что делать, если указанного time limit недостаточно?

  1. Увеличьте --attack-period. Например, время жизни флага на RuCTF обычно составляет 5 минут, поэтому --attack-period можно увеличить более, чем в 2 раза.

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

  2. Увеличьте --pool-size. Это грозит исчерпанием свободной памяти и зависанием компьютера.

  3. Используйте опцию --distribute=K/N. Тогда список команд будет детерминированным образом поделён на N частей, после чего клиент будет запускать эксплоит только на K-й части списка. Таким образом, запуск эксплоита можно будет распределить между N компьютерами.

Отладка эксплоитов

Первые несколько атак (опция --verbose-attacks) клиент фермы будет показывать содержимое stdout и stderr эксплоита для каждой из команд, а также список флагов, извлечённых из этого вывода. Это позволяет увидеть, какие ошибки возникают при запуске эксплоита.

В конце каждой атаки клиент показывает, какой процент процессов с эксплоитом (за всё время работы клиента) превысил отведённый им time limit.

Автоматический поиск сервера фермы

Чтобы каждый раз не указывать опцию --server-url URL, вы можете изменить стандартный домен сервера в файле start_sploit.py на домен, A-записи которого может контролировать ваш админ, и попросить членов команды использовать обновлённый скрипт.

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


Изменение A-записи на DigitalOcean

Дополнительные особенности

  • Эксплоиты запускаются с переменной окружения PYTHONUNBUFFERED=1, благодаря которой в эксплоитах на Python процедура flush(stdout) выполняется автоматически после вывода каждого перевода строки (это дополнительно страхует от потери флагов, см. пункт 4 в формате эксплоита).