
Аудит информационной безопасности — это оценка состояния системы. Аудитор ищет уязвимости и проверяет, насколько система соответствует требованиям. Аудит сложный и долгий процесс: эксперту нужно проверить сотни параметров в сотнях систем. К счастью, аудит можно автоматизировать.
Проблема в том, что требования к системам создает человек. Рабочая группа или руководитель пишет документ. В обычном случае аудитор читает документ и вручную проверяет систему. Для автоматизации нужны четкие инструкции, но бумажный документ не понятен программе.
В 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>
