Аудит информационной безопасности — это оценка состояния системы. Аудитор ищет уязвимости и проверяет, насколько система соответствует требованиям. Аудит сложный и долгий процесс: эксперту нужно проверить сотни параметров в сотнях систем. К счастью, аудит можно автоматизировать.
Проблема в том, что требования к системам создает человек. Рабочая группа или руководитель пишет документ. В обычном случае аудитор читает документ и вручную проверяет систему. Для автоматизации нужны четкие инструкции, но бумажный документ не понятен программе.
В 2009 году NIST разработал спецификацию SCAP. Спецификация описывает, как перевести высокоуровневые требования в формализованный вид. Формализованные требования или SCAP-контент состоит из двух основных элементов: языки XCCDF и OVAL. Языки XCCDF и OVAL понятны машине. С использованием SCAP-контента систему проверяет специальное приложение — SCAP-интерпретатор.
Далее на основе CIS Benchmark разберем документы XCCDF и OVAL. Некоторые детали я намеренно опущу. Это позволит упростить изложение, но базовой логики не нарушит.
Рисунок ниже представляет структуру этих документов. Обращайтесь к нему по ходу чтения.
eXtensible Configuration Checklist Description Format
Язык XCCDF выполняет две функции: описывает контрольные списки настроек безопасности и связывает другие компоненты SCAP.
Контрольные списки состоят из элементов — чекбоксов. Один элемент контрольного списка — это одно требование к системе. XCCDF не содержит инструкций для выполнения SCAP-интерпретатором, поэтому каждая запись из контрольного списка ссылается на другие компоненты SCAP, которые инструкции содержат.
Документ XCCDF состоит из трех элементов: групп, правил и значений. Каждый элемент содержит два информационных поля: заголовок и описание. Эти поля дают понять, для чего элемент предназначен.
Эталон (Benchmark)
Эталон — это контейнер для групп, правил и значений. В документе XCCDF эталон содержится в одном экземпляре. Поэтому документ и эталон тождественны.
В примере ниже эталон предназначен для аудита Windows 7 по требованиям STIG.
<Benchmark>
<title>Win7 Audit</title>
<description>The Windows 7 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. The requirements were developed from DoD consensus, as well as the Windows 7 Security Guide and security templates published by Microsoft Corporation.</description>
--- data omitted ---
</Benchmark>
Профиль (Profile)
Профиль объединяет требования конкретного стандарта или политики. Например «Аудит журналов» или «Стандартный профиль безопасности системы для Ubuntu».
Каждый профиль наполняют ссылки на группы. Профиль соответствует стандарту в зависимости от указанных в нем групп.
В примере ниже профиль имеет только одну группу idref="V-15706″. Этот же профиль в полном CIS Benchmark — 266 групп.
Обратите внимание на selected="true". Этот селектор включает и исключает группы из проверки. В примере группа V-15706 должна быть проверена при аудите по профилю MAC-3_Sensitive.
<Profile id="MAC-3_Sensitive">
<title>III - Administrative Sensitive</title>
<description>ProfileDescription</description>
<select idref="V-15706" selected="true"/>
</Profile>
Группа ниже оценивает управление питанием. В частности, проверяет запрос пароля при пробуждении системы. Для проверки группа содержит правило SV-25168r1_rule.
<Group id="V-15706">
<title>Power Mgmt – Password Wake When Plugged In</title>
<description>GroupDescription</description>
<Rule id="SV-25168r1_rule">
--- data omitted ---
</Rule>
</Group>
Правило (Rule)
Правило детализирует проверку. Правило SV-25168r1_rule ниже содержит три ссылки: переменная password-require внутри документа, экспортируемая переменная var:381700 и определение def:3817 в связанном документе OVAL.
Значение внутренней переменной password-require должно быть присвоено экспортируемой переменной var:381700.
<Rule id="SV-25168r1_rule">
<title>Password is required on resume from sleep (plugged in).</title>
<description>This check verifies that the user is prompted for a password on resume from sleep (Plugged In)</description>
<fixtext>Configure the policy value for Computer Configuration - Administrative Templates > System > Power Management > Sleep Settings “Require a Password When a Computer Wakes (Plugged In)” to “Enabled”.</fixtext>
<check>
<check-export value-id="password-require" export-name="var:381700"/>
<check-content-ref name="def:3817"/>
</check>
</Rule>
Важное поле — fixtext. Оно информирует от том, что делать при невыполнении правила.
Поле fixtext выше указывает, что требуется установить значение «Enabled» в Administrative Templates > System > Power Management > Sleep Settings «Require a Password When a Computer Wakes (Plugged In)».
Переменная (Value)
<Value id="password-require" operator="equals">
<value>1</value>
<value selector="disabled">0</value>
<value selector="enabled">1</value>
</Value>
Внутренняя переменная принимает значения по умолчанию или в зависимости от селектора в профиле. В примере выше переменная равна единице, потому что селектор указывал selected="true". Это значит, что переменная var:381700 также равна единице.
Документы XCCDF и OVAL связаны. Их связывают две вещи: ссылки на конкретные определения и экспортируемые переменные. В примере — это ссылка на определение def:3817 и переменная var:381700.
После обработки интерпретатором документа XCCDF — очередь OVAL. В документе OVAL интерпретатор разберет определения, перечисленные в профиле XCCDF.
Open Vulnerability and Assessment Language
OVAL (Open Vulnerability and Assessment Language) — декларативный язык логических утверждений. OVAL описывает уязвимости и необходимое состояние конфигурации системы.
OVAL состоит из пяти элементов: определений, критериев, тестов, объектов и состояний.
Определение (Definition)
Определение — главный элемент. Определение включает остальные элементы: критерии, тесты, объекты и состояния.
Следующий элемент в иерархии — критерии. Критерии — логические выражения, которые с помощью булевой логики (И, ИЛИ, НЕ) оценивают результаты включенных тестов.
Тесты возвращают результаты булева типа (true/false), поэтому определения также будут возвращать результаты булева типа.
Логический оператор И (operator="AND") в примере ниже не играет никакой роли, потому что определение содержит только один тест tst:381700.
Для формализации сложных требований нужны сложные логические выражения. Такие выражения строятся с помощью иерархии критериев и тестов.
Еще более сложные требования формализуются с помощью языка OCIL. Язык предполагает участие человека в проведении тестов.
<definition id="def:3817" class="compliance">
<metadata>
<title>"Require a Password when a Computer Wakes (Plugged)"</title>
<affected family="windows">
<platform>Microsoft Windows 7</platform>
</affected>
<description>"Require a Password when a Computer Wakes (Plugged)"</description>
</metadata>
<criteria operator="AND">
<criterion test_ref="tst:381700"/>
</criteria>
</definition>
Тест (Test)
Главная задача теста — сопоставление текущего состояния объекта с требуемым.
Объекты, тесты и состояния бывают различных типов. Типы определены спецификацией и зависят от проверяемой системы.
Например. Тип group_sid для Windows анализирует пользователей и подгруппы по SID идентификатору. А тип dpkginfo для Linux находит информацию о заданном DPKG пакете. Тип textfilecontent не зависит от системы и проверяет содержимое текстового файла.
В примере ниже указан тип registry. Этот тип работает с записями реестра Windows.
Тест registry_test ссылается на объект obj:381700 и состояние ste:381700. Для получения результатов теста нужно проверить все указанные объекты (check="all"), при этом хотя бы один должен существовать (check_existence="at_least_one_exists").
<registry_test id="tst:381700" check_existence="at_least_one_exists" check="all">
<object object_ref="obj:381700"/>
<state state_ref="ste:381700"/>
</registry_test>
Объект (Object)
Перечень возможных объектов многообразен. Перечень включает записи в реестре, идентификаторы пользователя и маркеры доступа, события аудита и т.д.
В примере ниже registry_object это конкретное значение в реестре Windows: HKEY LOCAL MACHINE > Software\Policies\Micro… > ACSettingIndex.
<registry_object id="obj:381700">
<hive datatype="string">HKEY_LOCAL_MACHINE</hive>
<key datatype="string">Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51</key>
<name datatype="string">ACSettingIndex</name>
</registry_object>
Состояние (State)
Этот компонент задает требуемое состояние объекта. Состояние может быть задано статически или определяться через переменную.
В примере ниже состояние определяется переменной var:381700.
Каждый объект специфичен. Это значит, что объект registry_object возможно сравнить только с состоянием registry_state с помощью теста registry_test.
<registry_state id="ste:381700">
<type>reg_dword</type>
<value datatype="int" var_ref="var:381700"/>
</registry_state>
Переменная (Variable)
Переменная хранит некоторое значение. Значение задается статически или определяется динамически из XCCDF.
В примере ниже значение переменной var:381700 экспортировано из XCCDF и равно единице.
<external_variable id="var:381700">
<possible_value hint="disabled">0</possible_value>
<possible_value hint="enabled">1</possible_value>
</external_variable>
Итог
Стандарты формализации высокоуровневых требований помогают автоматизировать аудит безопасности. Требования интерпретируются однозначно, поэтому результаты аудита не зависят от конкретного сканера. Оценка становятся понятной, а причины несоответствия — очевидными.
P.S.
Рассмотренные документы в сборе под спойлером. Полные версии ищите на сайте CIS.
Win7Audit_Benchmark-xccddf.xml
<Benchmark>
<title>Win7 Audit</title>
<description>The Windows 7 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. The requirements were developed from DoD consensus, as well as the Windows 7 Security Guide and security templates published by Microsoft Corporation.</description>
<Profile id="MAC-3_Sensitive">
<title>III - Administrative Sensitive</title>
<description>ProfileDescription</description>
<select idref="V-15706" selected="true"/>
</Profile>
<Group id="V-15706">
<title>Power Mgmt – Password Wake When Plugged In</title>
<description>GroupDescription</description>
<Rule id="SV-25168r1_rule">
<title>Password is required on resume from sleep (plugged in).</title>
<description>This check verifies that the user is prompted for a password on resume from sleep (Plugged In)</description>
<fixtext>Configure the policy value for Computer Configuration - Administrative Templates > System > Power Management > Sleep Settings “Require a Password When a Computer Wakes (Plugged In)” to “Enabled”.</fixtext>
<check>
<check-export value-id="require_a_password_when_a_computer_wakes_plugged_var" export-name="var:381700"/>
<check-content-ref name="def:3817"/>
</check>
</Rule>
</Group>
<Value id="password-require" operator="equals">
<value>1</value>
<value selector="disabled">0</value>
<value selector="enabled">1</value>
</Value>
</Benchmark>
Win7Audit_Benchmark-oval.xml
<oval_definitions>
<definitions>
<definition id="def:3817" class="compliance">
<metadata>
<title>Require a Password when a Computer Wakes (Plugged)</title>
<affected family="windows">
<platform>Microsoft Windows 7</platform>
</affected>
<description>Require a Password when a Computer Wakes (Plugged)</description>
</metadata>
<criteria operator="AND">
<criterion test_ref="tst:381700"/>
</criteria>
</definition>
</definitions>
<tests>
<registry_test id="tst:381700" check_existence="at_least_one_exists" check="all">
<object object_ref="obj:381700"/>
<state state_ref="ste:381700"/>
</registry_test>
</tests>
<objects>
<registry_object id="obj:381700">
<hive datatype="string">HKEY_LOCAL_MACHINE</hive>
<key datatype="string">Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51</key>
<name datatype="string">ACSettingIndex</name>
</registry_object>
</objects>
<states>
<registry_state id="ste:381700">
<type>reg_dword</type>
<value datatype="int" var_ref="var:381700"/>
</registry_state>
</states>
<variables>
<external_variable id="var:381700">
<possible_value hint="disabled">0</possible_value>
<possible_value hint="enabled">1</possible_value>
</external_variable>
</variables>
</oval_definitions>