dtls-fuzzer — это Java-инструмент, который выполняет протокольный state fuzzing DTLS-серверов. Более конкретно, он поддерживает следующие функции:
- при заданном алфавите он может автоматически сгенерировать модель локальной реализации DTLS-сервера;
- при заданном тесте (последовательности входных данных) и алфавите он может выполнить тест на реализации DTLS-сервера;
- он может запустить пакетное обучение, включающее несколько сеансов обучения.
dtls-fuzzer использует [TLS-Attacker][tlsattacker] для генерации/разбора сообщений DTLS, а также для поддержания состояния.
Для этого TLS-Attacker был расширен поддержкой DTLS.
dtls-fuzzer опирается на [версию 3.0b][tlsattackerver] TLS-Attacker, версию, реализующую улучшение DTLS.
Содержимое артефакта
Артефакт содержит:
- описание файловой структуры dtls-fuzzer, включая исходный код и экспериментальные данные, соответствующие представленным в статье;
- пошаговое руководство по оценке dtls-fuzzer на выбранной SUT (System Under Test) / реализации DTLS-сервера.
Файловая структура dtls-fuzzer
Наиболее важные папки в корневом каталоге dtls-fuzzer:
- 'src', каталог, содержащий Java-исходный код dtls-fuzzer;
- 'examples', каталог, содержащий примеры алфавитов, тестов, спецификаций (т.е. моделей) и файлов аргументов, которые можно передать dtls-fuzzer для запуска экспериментов по обучению. Файлы в этом каталоге используются в качестве входных данных для экспериментов по обучению;
- 'experiments', каталог, содержащий данные, относящиеся к экспериментам. Некоторые из этих данных также служат входными данными для экспериментов по обучению. Наиболее примечательные папки:
- 'suts' с двоичными файлами для Java SUT. Эти SUT представляют собой специально созданные программы DTLS-серверов, исходный код которых находится в открытом доступе;
- 'patches' — исправления, которые были применены к некоторым SUT (особенно к утилитам) перед компиляцией исходного кода. Основная цель этих исправлений — предотвратить поведение, вызванное временными задержками во время обучения, включить/отключить функциональность в SUT и настроить такие параметры, как предварительный общий ключ;
- 'keystore' — ключевой материал (например, пары открытого/закрытого ключей, хранилища ключей Java), используемый во время обучения;
- 'results' — результаты экспериментов.
Результаты экспериментов
'experiments/results' содержит результаты экспериментов, которые являются основным результатом работы. В частности,
- 'all_ciphers' содержит выходные папки для всех запущенных экспериментов;
- 'mapper' содержит результаты экспериментов, которые помогают обосновать некоторые решения по маппингу (см. Раздел 5.2)
- 'included' содержит выходные папки для сходящихся экспериментов (сходимость означает, что обучение успешно генерирует модель).
- обратите внимание, что не все эксперименты в 'all_ciphers' были успешными/завершились с конечной моделью (в таких случаях мы говорим, что обучение не сошлось)
Выходные папки
Выходные папки именуются на основе конфигурации эксперимента, то есть:
- тестируемой SUT/реализации;
- используемого алфавита, в терминах охваченных алгоритмов обмена ключами, где 'all' означает, что использовались все 4 алгоритма обмена ключами;
- где применимо, требовалась ли клиентская сертификация (req), необязательная (nreq) или отключена (none);
- алгоритма тестирования: random walk (rwalk) или его адаптации (stests);
- эксперименты с использованием адаптации не были включены в статью
- опционально, были ли включены/исключены повторные передачи в выходные данные (incl или excl).
- повторные передачи были включены по умолчанию
В качестве примера, имя папки 'jsse-12_rsa_cert_none_rwalk_incl' указывает на эксперимент с реализацией JSSE 12 DTLS, использующий алфавит, включающий входные данные для выполнения квитирования RSA, аутентификация клиентского сертификата отключена, алгоритм тестирования — random walk, и повторные передачи включены.
Выходная папка содержит:
- 'alphabet.xml' — входной алфавит;
- 'command.args' — файл аргументов, используемый с различными параметрами эксперимента, наиболее заметными из которых являются:
- queries — ограничение на количество тестов random walk, которые должны пройти, чтобы гипотеза считалась окончательной
- equivalenceAlgorithms — используемые алгоритмы тестирования на основе моделей
- runWait и timeout — соответственно тайм-аут запуска и ответа (мы коснемся их позже)
- 'sul.config' — конфигурация SUT для TLS-Attacker, ту же конфигурацию можно использовать для выполнения трассировок рабочего процесса на SUT с использованием только TLS-Attacker;
- 'hyp[0-9]+.dot' — промежуточные гипотезы;
- 'statistics.txt' — статистика эксперимента, такая как общее количество тестов, время обучения;
- Таблица 4 отображает эти данные
- 'nondet.log' — журналы обнаруженного недетерминированного поведения;
- 'learnedModel.dot' — в случае сходимости обучения, обученная модель (т.е. окончательная гипотеза);
- 'error.msg' — сообщение об ошибке, сгенерированное в случае сбоя эксперимента/остановки обучения и, следовательно, отсутствия сходимости к окончательной модели.
- основная причина — временной недетерминизм (одинаковые входные данные приводят к разным результатам).
Оценщик может проверить (например), что результаты экспериментов в 'included' соответствуют тем, что показаны в Таблице 4, или что конфигурации, протестированные в Таблице 2, также присутствуют в 'all_ciphers'.
Обратите внимание, что модели, представленные в статье, являются результатом значительного сокращения/обрезки, тогда как модели, появляющиеся в выходных папках, не изменены.
Этапы оценки dtls-fuzzer
Для оценки dtls-fuzzer необходимо выполнить следующие шаги:
- Убедиться, что выполнены предварительные требования
- Установить dtls-fuzzer
- Настроить SUT
- Использовать dtls-fuzzer для генерации моделей для SUT
- Проанализировать результаты
За этим разделом оценки следует руководство по использованию dtls-fuzzer, в котором представлены его основные варианты использования.
Обеспечение предварительных требований
dtls-fuzzer тестировался на Ubuntu 18.04 и Debian 9 дистрибутивах Linux.
Он должен работать на любом современном дистрибутиве Linux.
Поддержка других платформ не тестировалась.
Это руководство предполагает использование дистрибутива на основе Debian (с 'apt-get').
Требуется виртуальная машина (VM) с Java 8 JDK (Java Development Kit).
Версия, используемая для запуска экспериментов: 1.8.0_222, хотя более поздние версии Java 8 также должны работать.
Обратите внимание, что инструмент не собирается на Java 9 или более поздних версиях.
Мы также полагаемся на maven (утилита 'mvn') для управления зависимостями/развертывания.
Мы рекомендуем использовать достаточно мощную машину, иначе чувствительные временные параметры, такие как время ожидания ответа, могут стать слишком низкими, что приведет к другим результатам, отличным от полученных в статье.
Хуже того, это может привести к сбою экспериментов по обучению.
Исходные эксперименты проводились на многоядерном сервере, однако мы ожидаем (хотя тщательно не тестировали), что обучение должно быть возможно на настольном компьютере с процессором i7.
Обучение также возможно на более слабых системах, если соответствующим образом настроить временные параметры.
Наконец, для визуализации моделей .dot путем экспорта в .pdf требуется установка библиотеки [graphviz][graphviz].
Предполагается, что утилита 'dot', предоставляемая graphviz, находится в системном PATH.
Таким образом, рекомендуемые предварительные требования:
- современный дистрибутив Linux, желательно на основе Debian
- настольный/серверный компьютер для воспроизведения экспериментов/надежного обучения
- (не менее) 4 ГБ ОЗУ
- Java 8 JDK
- maven
- graphviz