Сейчас в мире существует большое количество сканеров информационной безопасности разных компаний (в том числе — MaxPatrol, XSpider и анализатор кода Application Inspector производства Positive Technologies). Подобные инструменты различаются ценой, качеством сканирования, типами определяемых уязвимостей, методами их поиска и еще десятками параметров.
При создании сканеров важную роль играют методики тестирования их работы, особое место в которых занимает конкурентный анализ подобных продуктов.
Как правило, результатом работы любого сканера безопасности является список обнаруженных уязвимостей, полученный в процессе анализа веб-приложения. Тот факт, что в сканерах используются эвристические алгоритмы, приводит к проблеме наличия ложных срабатываний и заполнению списка несуществующими в реальности уязвимостями (false positives). А это, в свою очередь, приводит к необходимости выделить ИБ-эксперта для проверки работы сканера.
Для подтверждения наличия уязвимости предлагается использоваться «эталонные» списки уязвимостей, содержащихся в похожих веб-приложениях. Аналитик может использовать такие списки для выявления наиболее вероятных уязвимостей тестируемого продукта и отсеивать очевидные false positives.
Постановка задачи нечеткой классификации уязвимостей
Проблему подтверждения уязвимостей из списка, выданного сканером, на практике предлагаем решить как задачу сравнения их с некоторыми эталонами. Если все объекты — и эталоны, и кандидаты в уязвимости — могут быть однозначно параметризованы, представлены в виде вектора, то проблема может быть сведена к классической задаче классификации элементов множества.
Входные данные:
- Задано множество Vulners всех уязвимостей веб-приложений, которые могут быть заданы своими векторами признаками vi. В Vulners имеется множество Candidates — кандидатов в уязвимости, найденных сканером.
- Каждую уязвимость-кандидат допускается отнести к двум классам: I — подтвержденных (Ver) и II — неподтвержденных (NVer) уязвимостей.
- Существует множество Eth — эталонных уязвимостей, входящих в I класс.
- Задано множество Scales — измерительных шкал для оценки свойств уязвимостей, как четких, так и нечетких.
Требуется:
- Построить функции, связывающие четкие и нечеткие шкалы, для возможности различной интерпретации результатов классификации.
- Построить функцию Classificator, которая для каждой уязвимости указывает оценку ее принадлежности к классам подтвержденных и неподтвержденных уязвимостей.
В качестве измерительных шкал для оценки свойств информационных систем могут быть использованы:
- Четкая шкала — множество действительных чисел из отрезка [0, 1], которое легко может быть преобразовано в любые другие виды четких числовых множеств — дискретных, непрерывных, неограниченных — при помощи различных функций конвертирования.
- Нечеткая шкала F-множества упорядоченных нечетких переменных вида FP = {fpi}, где fpi — лингвистические переменные, описывающие значения свойств объекта.
Четкая и нечеткая «универсальная» измерительные шкалы
Кодирование входных данных
Для любого способа классификации уязвимости должны быть предварительно закодированы, то есть представлены вектором v = {vi} из Vulners. Для этого нужно задать формальное правило кодирования, согласно которому отдельные свойства реальных уязвимостей возможно оценить на четкой шкале Sp.
Зададим матрицу кодирования признаков уязвимостей MVulners, строки которой представляют собой отдельные свойства уязвимостей (vulner property), столбцы указывают на числовой код (code) некоторого свойства, а в ячейках матрицы указываются возможные значения свойств. Для построения такой матрицы должны быть выделены только значимые свойства, однозначно отличающие одну автоматически найденную уязвимость от другой. Понятно, что для каждого сканера информационной безопасности классификация уязвимостей может быть своей. Тем не менее, большинство из них содержат такие свойства, как, например, тип уязвимости, протокол, по которому она может быть эксплуатирована, канал реализации внутри этого протокола, тип уязвимого объекта, путь до объекта на сервере, сетевой запрос с вектором атаки. Все возможные значения каждого свойства кодируются неотрицательными целыми числами, где ноль выделен в качестве неопределенного значения свойства, что позволит учитывать, в числе прочего, отсутствующие, новые или пока не предусмотренные значения свойства.
Матрица MVulners может быть представлена в табличном виде. Значениями свойств могут быть также нечеткие величины и для использования в дальнейших расчетах их нужно дефазифицировать.
Построение нейронной сети, ее обучение и представление результатов
Будем задавать конфигурацию нейронной сети тройкой значений:
Config = <inputs, {layerl}, outputs>,
где inputs — количество входных параметров, {layerl} — множество неотрицательных целых чисел, указывающих на количество нейронов в скрытом слое номер l, и outputs — количество выходных параметров.
Вектор (sI, sII) со значениями параметров на четкой шкале Sp может интерпретироваться следующим образом:
- Значения параметров указывают на степень уверенности от 0 до 1 в принадлежности вектора признаков уязвимости каждому классу.
- Значения параметров, будучи умноженными на 100%, указывают на вероятность принадлежности вектора признаков уязвимости каждому классу от 0 до 100%.
- Значения параметров, фазифицированные при помощи специальной функции Fuzzy(x, Sf), указывают на лингвистическую оценку уровня принадлежности вектора признаков уязвимости каждому из классов на нечеткой шкале Sf = {Min, Low, Med, High, Max}.
Программная реализация классификатора
Для практического использования нейронных сетей при решении задач нечеткой классификации в случае различного числа классов и структуры сетей были разработаны программные модули FuzzyClassificator, распространяемые под лицензией GNU GPL v3. Скачать актуальную версию FuzzyClassificator можно на GitHub.
Для удобства использования модулей в системах автоматизации конфигурация программы осуществляется через интерфейс командной строки. В разделе описания программы на GitHub приведена подробная техническая информация о командах интерфейса, работе модулей и входных данных. Для работы модулей FuzzyClassificator требуется Pyzo — бесплатный и открытый инструмент разработки, основанный на Python 3.3.2 и включающий в себя множество подпрограмм для реализации научных вычислений, в частности PyBrain library — подпрограммы для работы с нейронными сетями.
Основные программные модули, реализующие предложенные в статье подходы и математический аппарат:
- FuzzyClassificator — реализует пользовательский интерфейс командной строки, получает и обрабатывает входные данные, устанавливает режимы обучения и классификации, предоставляет результаты.
- PyBrainLearning — определяет методы для работы с нечеткими нейронными сетями, объединяя возможности библиотеки PyBrain и авторской библиотеки FuzzyRoutines.
- FuzzyRoutines — содержит подпрограммы для работы с нечеткими множествами и нечеткими шкалами.
Верхний A-0-уровень функциональной IDEF0-модели работы программы FuzzyClassificator
Уровень A0 IDEF0-модели. Основные этапы работы FuzzyClassificator
Уровень A1 IDEF0-модели. Подпроцессы этапов работы FuzzyClassificator
Этап обучения (learning mode) состоит из следующих шагов:
1. Инициализация объектов программы пользовательскими значениями.
2. Обработка входных данных и подготовка нейронной сети к обучению:
- обработка файла с данными о векторах признаков эталонов;
- подготовка данных для обучения в формате PyBrain;
- инициализация параметров новой нейронной сети PyBrain или ее загрузка из указанного файла.
3. Обучение нейронной сети на заданных эталонах:
- инициализация модуля PyBrain-тренера;
- обучение сети при помощи тренера и сохранение ее конфигурации в файл формата PyBrain.
Этап классификации (classifying mode) состоит из следующих шагов:
1. Инициализация объектов программы пользовательскими значениями.
2. Обработка входных данных и подготовка нейронной сети к анализу данных:
- обработка файла с данными о векторах признаков кандидатов;
- загрузка конфигурации обученной нейронной сети PyBrain из указанного файла.
3. Анализ нейронной сетью векторов признаков кандидатов:
- активация нейронной сети и вычисление уровней принадлежности векторов к различным классам;
- интерпретация полученных результатов на нечетких шкалах и формирование файла отчета.
Входные данные с векторами признаков эталонов и кандидатов задаются в виде обычных текстовых файлов с табуляцией в качестве разделителя значений. Например, чтобы задать данные для обучения, можно подготовить файл ethalons.dat, содержащий первую строку заголовка и далее строки со значениями эталонных векторов признаков и их принадлежности тому или иному классу.
Значения могут быть заданы как на четкой, так и на нечеткой шкалах.
Файл ethalons.dat
input1 input2 input3 1st_class_output 2nd_class_output
0.1 0.2 Min 0 Max
0.2 0.3 Low 0 Max
0.3 0.4 Med 0 Max
0.4 0.5 Med Max 0
0.5 0.6 High Max 0
0.6 0.7 Max 0
А в качестве данных для анализа может быть подготовлен файл candidates.dat, также содержащий строку заголовка и строки со значениями векторов признаков кандидатов:
Файл candidates.dat
input1 input2 input3
0.12 0.32 Med
0.32 0.35 Low
0.54 0.57 Med
0.65 0.68 High
0.76 0.79 Min
По итогам работы программы создается файл с отчетом, содержащим информацию о конфигурации нейронной сети и результаты классификации для каждого вектора признаков из множества кандидатов.
После обучения нейронной сети на указанных выше примерах, с параметрами, заданными командной строкой:
python FuzzyClassificator.py --learn config=3,3,2,2 epochs=1000 rate=0.1 momentum=0.05
и затем, в режиме классификации с параметрами командной строки:
python FuzzyClassificator.py --classify config=3,3,2,2
На выходе получается репорт-файл.
Репорт-файл
Neuronet: C:\work\projects\FuzzyClassificator\network.xml
FuzzyScale = {Min, Low, Med, High, Max}
Min = <Hyperbolic(x, {'a': 8, 'c': 0, 'b': 20}), [0.0, 0.23]>
Low = <Bell(x, {'a': 0.17, 'c': 0.34, 'b': 0.23}), [0.17, 0.4]>
Med = <Bell(x, {'a': 0.34, 'c': 0.6, 'b': 0.4}), [0.34, 0.66]>
High = <Bell(x, {'a': 0.6, 'c': 0.77, 'b': 0.66}), [0.6, 0.83]>
Max = <Parabolic(x, {'a': 0.77, 'b': 0.95}), [0.77, 1.0]>
Classification results for candidates vectors:
Input: ['0.12', '0.32', 'Min'] Output: ['Min', 'Max']
Input: ['0.32', '0.35', 'Low'] Output: ['Low', 'High']
Input: ['0.54', '0.57', 'Med'] Output: ['Max', 'Min']
Input: ['0.65', '0.68', 'High'] Output: ['Max', 'Min']
Input: ['0.76', '0.79', 'Max'] Output: ['Max', 'Min']
Если проанализировать данные из файла candidates.dat, то можно с высокой степенью уверенности утверждать, что человек-эксперт, опираясь только на данные из файла ethalons.dat, выдал бы аналогичные результаты классификации.
Заключение
Итак, нам удалось совместить математические аппараты теорий нечетких систем и нейронных сетей для решения практической задачи классификации уязвимостей. Из проделанной работы можно сделать несколько выводов:
- Математические методы разделения на классы на базе нейронных сетей применимы и в случае классификации уязвимостей.
- Для получения адекватных результатов необходимо корректно построить матрицу кодирования и подобрать наилучшие свойства для моделирования уязвимостей.
- Для задачи классификации уязвимостей рекомендуется использовать нейронную сеть персептронов с двумя скрытыми слоями и в конфигурации, зависящей от числа входных параметров: в первом число нейронов равно числу входных параметров, а во втором — в два раза меньше.
- Преимуществом предложенных подходов является использование универсальных нечетких шкал лингвистических переменных, которые применимы как для оценки значений векторов признаков, так и для интерпретации итоговых уровней принадлежности классам.
- Предложенный метод нечеткой классификации и реализующие его программные модули FuzzyClassificator являются универсальными, легко адаптируются и настраиваются под конкретные объекты классификации.
Будем рады ответить на ваши вопросах в комментариях. Дополнительные подробности, как и описание матаппарата, см. по адресу: math-n-algo.blogspot.ru/2014/08/FuzzyClassificator.html.
Автор: Тимур Гильмуллин, Positive Technologies.