Создание средства синтаксического анализа ASIM

Завершено

Пользователи расширенной информационной модели безопасности (ASIM) используют унифицированные средства синтаксического анализа вместо имен таблиц в своих запросах, для просмотра данных в нормализованном формате и включения всех данных, относящихся к схеме в запросе. Объединяющие парсеры, в свою очередь, используют средства синтаксического анализа, относящиеся к источнику, для обработки специфических деталей каждого источника.

Microsoft Sentinel предоставляет встроенные средства синтаксического анализа, зависящие от источника, для многих источников данных. Вы можете изменить или разработать эти средства синтаксического анализа для конкретного источника в следующих ситуациях:

Когда устройство предоставляет события, соответствующие схеме ASIM, но специфичное для устройства средство синтаксического анализа и соответствующая схема недоступны в Microsoft Sentinel.

Когда для вашего устройства доступны зависящие от источника средства синтаксического анализа ASIM, но ваше устройство отправляет события методом или в формате, отличном от ожидаемого средствами синтаксического анализа ASIM. Рассмотрим пример.

исходное устройство может быть настроено для отправки событий нестандартным образом;

устройство может иметь версию, отличную от той, которая поддерживается средством синтаксического анализа ASIM;

события могут собираться, изменяться и пересылаться промежуточной системой.

Процесс разработки пользовательского синтаксического анализатора

Следующий рабочий процесс описывает основные этапы разработки пользовательского средства синтаксического анализа для определенного источника.

  1. Соберите образцы журналов.

  2. Определите схемы или схемы, которые представляют события, отправляемые из источника.

  3. Сопоставляйте поля исходного события с идентифицированной схемой или схемами.

  4. Разработайте один или несколько анализаторов ASIM для вашего источника. Вам потребуется разработать средство синтаксического анализа для фильтрации и без параметров для каждой схемы, относящейся к источнику.

  5. Проверьте средство синтаксического анализа.

  6. Разверните анализаторы синтаксиса в рабочих областях Microsoft Sentinel.

  7. Обновите соответствующее объединяющее средство синтаксического анализа ASIM, чтобы оно ссылалось на новое пользовательское средство синтаксического анализа.

  8. Вы могли бы также захотеть внести свои парсеры в основной дистрибутив ASIM. Добавленные вами средства синтаксического анализа также можно сделать доступными во всех рабочих областях в качестве встроенных.

Сбор образцов журналов

Для создания эффективных средств синтаксического анализа ASIM вам потребуется репрезентативный набор журналов, для чего в большинстве случаев понадобится настроить исходную систему и подключить ее к Microsoft Sentinel. Если у вас нет исходного устройства, облачные службы с оплатой по мере использования позволяют развертывать множество устройств для разработки и тестирования.

Кроме того, документация и примеры журналов от поставщиков помогут вам ускорить разработку и сократить число ошибок, охватив своим решением различные форматы журналов.

Репрезентативный набор журналов должен включать:

  • события с разными результатами;
  • события с разными действиями ответа;
  • разные форматы имени пользователя, имени и идентификатора узла, а также других полей, требующих нормализации значений.

Картирование

Перед разработкой средства синтаксического анализа сопоставьте сведения, доступные в исходном событии или событиях, с определенной схемой:

  • Сопоставьте все обязательные поля (желательно также сопоставить рекомендуемые).
  • Попробуйте сопоставить доступные в источнике сведения с нормализованным полями. Если она недоступна в рамках выбранной схемы, рассмотрите возможность сопоставления полей, доступных в других схемах.
  • Сопоставьте значения полей в источнике с нормализованными значениями, допустимыми в ASIM. Исходное значение хранится в отдельном поле, например EventOriginalResultDetails.

Разработка средств синтаксического анализа

Разработайте средство синтаксического анализа фильтрации и без параметров для каждой соответствующей схемы.

Пользовательский анализатор — это запрос KQL, разработанный на странице журналов Microsoft Sentinel. Запрос средства синтаксического анализа состоит из трех частей:

Фильтрация > Анализ > Подготовка полей

Фильтрация соответствующих записей

Часто таблица в Microsoft Sentinel содержит события нескольких типов. Рассмотрим пример.

  • Таблица системного журнала содержит данные из нескольких источников.
  • Пользовательские таблицы могут содержать сведения из одного источника, который предоставляет более одного типа событий и может соответствовать различным схемам.

Таким образом, средство синтаксического анализа должно сначала отфильтровать только те записи, которые относятся к целевой схеме.

Фильтрация в KQL выполняется с помощью оператора where . Например, событие Sysmon 1 сообщает о создании процесса и поэтому должно быть нормализовано до схемы ProcessEvent. Событие Sysmon 1 является частью таблицы событий, поэтому вы будете использовать следующий фильтр:

Event | where Source == "Microsoft-Windows-Sysmon" and EventID == 1

Это важно

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

Фильтрация по типу источника с помощью списка отслеживания

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

Например, события Infoblox DNS отправляются в виде сообщений системного журнала, и их трудно отличить от сообщений системного журнала, отправленных из других источников. В таких случаях средство синтаксического анализа использует список источников, определяющих соответствующие события. Этот список сохраняется в списке отслеживания ASimSourceType.

Чтобы использовать список источников ASimSourceType в парсерах:

  • Включите следующую строку в начале средства синтаксического анализа:
let Sources_by_SourceType=(sourcetype:string){_GetWatchlist('ASimSourceType') | where SearchKey == tostring(sourcetype) | extend Source=column_ifexists('Source','') | where isnotempty(Source)| distinct Source };
  • Добавьте фильтр, использующий список наблюдения в разделе фильтрации синтаксического анализа. Например, средство синтаксического анализа DNS Infoblox включает в себя следующее в разделе фильтрации:
| where Computer in (Sources_by_SourceType('InfobloxNIOS'))

Чтобы использовать этот пример в средстве синтаксического анализа, выполните следующие действия.

  • Замените компьютер именем поля, включающее исходные сведения для источника. Это можно сохранить как Computer для любого синтаксического анализатора на базе Syslog.

  • Замените токен InfobloxNIOS значением выбранного средства синтаксического анализа. Сообщите пользователям средства синтаксического анализа, что они должны обновить список наблюдения ASimSourceType, используя выбранное значение, и список источников, отправляющих события этого типа.

Фильтрация на основе параметров средства синтаксического анализа

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

При фильтрации необходимо помнить о следующих моментах.

  • Выполняйте фильтрацию перед синтаксическим анализом с использованием физических полей. Если отфильтрованные результаты недостаточно точны, повторите тест после анализа, чтобы точно настроить результаты. Дополнительные сведения см. в статье о оптимизации фильтрации.
  • Не фильтруйте, если параметр не определен и по-прежнему имеет значение по умолчанию.

В следующих примерах показано, как реализовать фильтрацию для параметра строки, где значением по умолчанию обычно является "*", и для параметра списка, где значением по умолчанию обычно является пустой список.

srcipaddr=='*' or ClientIP==srcipaddr
array_length(domain_has_any) == 0 or Name has_any (domain_has_any)

Оптимизация фильтрации

Чтобы средство синтаксического анализа работало с достаточной производительностью, обратите внимание на следующие рекомендации по фильтрации:

  • Всегда фильтруйте по встроенным, а не по проанализированным полям. Хотя иногда проще фильтровать с помощью синтаксического анализа полей, это значительно влияет на производительность.
  • Используйте операторы, которые обеспечивают оптимальную производительность. В частности, ==, имеет и запускается. Использование таких операторов, как содержит или соответствует регулярным выражениям, также значительно влияет на производительность.

Рекомендации по фильтрации для повышения производительности не всегда легко выполнить. Например, использование оператора has менее точно, чем оператора contains. В других случаях сопоставление встроенного поля, например SyslogMessage, менее точно, чем сравнение извлеченного поля, например DvcAction. В таких случаях рекомендуется предварительно отфильтровать данные с помощью оператора оптимизации производительности по встроенному полю, а затем повторять фильтрацию с более точными условиями после синтаксического анализа.

Пример см. в следующем фрагменте кода синтаксического анализа DNS Infoblox. Парсер сначала проверяет, содержит ли поле SyslogMessage слово client. Однако термин может использоваться в другом месте сообщения, поэтому после синтаксического анализа поля Log_Type парсер проверяет, что слово клиент действительно было значением поля.

Syslog | where ProcessName == "named" and SyslogMessage has "client"
…
      | extend Log_Type = tostring(Parser[1]),
      | where Log_Type == "client"

Синтаксический анализ

После того как запрос выберет соответствующие записи, может потребоваться их синтаксический анализ. Как правило, анализ необходим, если несколько полей событий передаются в одном текстовом поле.

Ниже перечислены упорядоченные по производительности операторы KQL, которые выполняют синтаксический анализ. Первый из них обеспечивает оптимальную производительность, а последний — производительность с наименьшим уровнем оптимизации.

Оператор Описание
разделение Синтаксический анализ строки значений с разделителями.
parse_csv Синтаксический анализ строки значений в формате CSV (значения с разделителями-запятыми).
разбирать Анализ нескольких значений из произвольной строки на основе шаблона, который может быть упрощенным шаблоном с повышенной производительностью или регулярным выражением.
извлечь_все Анализ отдельных значений из произвольной строки с использованием регулярного выражения. extract_all имеет аналогичную производительность для синтаксического анализа, если последний использует регулярное выражение.
экстракт Извлечение одного значения из произвольной строки с использованием регулярного выражения. Использование извлечения обеспечивает лучшую производительность, чем синтаксический анализ или extract_all, если требуется одно значение. Однако использование нескольких вызовов функции извлечения из одной и той же исходной строки менее эффективно, чем один синтаксический анализ или extract_all, и его следует избегать.
parse_json Синтаксический анализ значений в строке в формате JSON. Если требуется только несколько значений из JSON, использование синтаксического анализа, извлечения или extract_all обеспечивает более высокую производительность.
parse_xml Синтаксический анализ значений в строке в формате XML. Если требуется только несколько значений из XML, использование синтаксического анализа, извлечения или extract_all обеспечивает более высокую производительность.

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

  • Форматирование и преобразование типов. Исходное поле, извлеченное после извлечения, может потребоваться отформатировать для соответствия целевому полю схемы. Например, может понадобиться преобразовать строку, представляющую дату и время, в формат поля datetime. Такие функции, как todatetime и tohex, полезны в этих случаях.

  • Поиск значений. Значение исходного поля после извлечения может потребоваться сопоставить с набором значений, указанных для поля целевой схемы. Например, некоторые источники сообщают числовые коды ответов DNS, а схема требует более распространенных кодов текстовых ответов. Функции iff и case могут быть полезны для отображения нескольких значений.

    Например, средство синтаксического анализа Microsoft DNS назначает поле EventResult на основе идентификатора события и кода ответа с помощью инструкции iff, как показано ниже.

    extend EventResult = iff(EventId==257 and ResponseCode==0 ,'Success','Failure')
    

    Для нескольких значений используйте дататаблицу и поиск, как показано в том же средстве синтаксического анализа DNS.

    let RCodeTable = datatable(ResponseCode:int,ResponseCodeName:string) [ 0, 'NOERROR', 1, 'FORMERR'....];
    ...
     | lookup RCodeTable on ResponseCode
     | extend EventResultDetails = case (
     isnotempty(ResponseCodeName), ResponseCodeName,
     ResponseCode between (3841 .. 4095), 'Reserved for Private Use',
     'Unassigned')
    

Сопоставление значений

Во многих случаях извлеченное исходное значение необходимо нормализовать. Например, в ASIM в MAC-адресе в качестве разделителя используются двоеточия, а источник может отправлять MAC-адрес с разделителями-дефисами. Основной оператор преобразования значений расширяется вместе с широким набором строк KQL, числовых и датовых функций, как показано в разделе синтаксического анализа выше.

Примеры использования, логическое условие "только если," и операторы подстановки применяются, когда необходимо сопоставить набор значений со значениями, допустимыми в целевом поле.

Если каждое исходное значение сопоставляется с целевым значением, определите сопоставление с помощью оператора таблицы данных и поиска для сопоставления. Например.

let NetworkProtocolLookup = datatable(Proto:real, NetworkProtocol:string)[
        6, 'TCP',
        17, 'UDP'
   ];
    let DnsResponseCodeLookup=datatable(DnsResponseCode:int,DnsResponseCodeName:string)[
      0,'NOERROR',
      1,'FORMERR',
      2,'SERVFAIL',
      3,'NXDOMAIN',
      ...
   ];
   ...
   | lookup DnsResponseCodeLookup on DnsResponseCode
   | lookup NetworkProtocolLookup on Proto

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

Если условия сопоставления более сложны, используйте функции iff или case . Функция iff позволяет сопоставить два значения:

| extend EventResult = 
      iff(EventId==257 and ResponseCode==0,'Success','Failure’)

Функция case поддерживает более двух целевых значений. В приведенном ниже примере показано, как объединить поиск и оператор выбора. Приведенный выше пример поиска возвращает пустое значение в поле DnsResponseCodeName, если искомое значение не найдено. В приведенном ниже примере оно дополняется за счет использования результата операции поиска, если он доступен, или указанием дополнительных условий в противном случае.

| extend DnsResponseCodeName = 
      case (
        DnsResponseCodeName != "", DnsResponseCodeName,
        DnsResponseCode between (3841 .. 4095), 'Reserved for Private Use',
        'Unassigned'
      )

Подготовьте поля в результирующем наборе

Средство синтаксического анализа должно подготовить поля в наборе результатов, чтобы обеспечить использование нормализованных полей.

Для подготовки полей в наборе результатов используются следующие операторы KQL:

Оператор Описание Когда следует использовать в средстве синтаксического анализа
переименование проекта Переименовывает поля. Если поле существует в фактическом событии и его нужно только переименовать, используйте project-rename. Переименованное поле по-прежнему работает как встроенное поле, и операции с полем имеют значительно более высокую производительность.
проекция вдаль Удаляет поля. Используйте проектирование, чтобы убрать определенные поля из результирующего набора. Рекомендуется не удалять исходные поля, которые не нормализованы из результирующих наборов, если они не создают путаницу или очень большие и могут иметь последствия для производительности.
проект Выбирает поля, которые существовали ранее или были созданы с помощью инструкции, и удаляет все остальные поля. Не рекомендуется использовать в средство синтаксического анализа, так как средство синтаксического анализа не должно удалять другие поля, которые не нормализованы. Если необходимо удалить определенные поля, такие как временные значения, используемые во время синтаксического анализа, используйте команду project-away, чтобы удалить их из результатов.
продлить Добавьте псевдонимы. Помимо ее роли в создании вычисляемых полей, оператор расширения также используется для создания псевдонимов.

Обработка вариантов синтаксического анализа

Во многих случаях события в потоке событий предполагают варианты, для которых требуется другая логика синтаксического анализа. Чтобы проанализировать различные варианты в одном синтаксическом анализаторе, используйте условные операторы, такие как iff и case, или используйте структуру объединения.

Чтобы использовать объединение для обработки нескольких вариантов, создайте отдельную функцию для каждого варианта и используйте оператор объединения для объединения результатов:

let AzureFirewallNetworkRuleLogs = AzureDiagnostics
    | where Category == "AzureFirewallNetworkRule"
    | where isnotempty(msg_s);
let parseLogs = AzureFirewallNetworkRuleLogs
    | where msg_s has_any("TCP", "UDP")
    | parse-where
        msg_s with           networkProtocol:string 
        " request from "     srcIpAddr:string
        ":"                  srcPortNumber:int
    …
    | project-away msg_s;
let parseLogsWithUrls = AzureFirewallNetworkRuleLogs
    | where msg_s has_all ("Url:","ThreatIntel:")
    | parse-where
        msg_s with           networkProtocol:string 
        " request from "     srcIpAddr:string
        " to "               dstIpAddr:string
    …
union parseLogs,  parseLogsWithUrls…

Чтобы избежать повторяющихся событий и чрезмерной обработки, убедитесь, что каждая функция начинается с фильтрации, используя собственные поля, только события, которые он предназначен для анализа. Кроме того, при необходимости используйте оператор project-away в каждой ветви перед объединением.

Развертывание средств синтаксического анализа

Средства синтаксического анализа развертываются вручную путем копирования на страницу журнала Azure Monitor и сохранения запроса в качестве функции. Этот способ удобен для тестирования. Дополнительные сведения см. в разделе "Создание функции".

Чтобы развернуть большое количество средств синтаксического анализа, рекомендуется использовать шаблоны ARM для средств синтаксического анализа следующим образом.

  1. Создайте файл YAML на основе соответствующего шаблона для каждой схемы и включите в него свой запрос. Начните с шаблона YAML, который соответствует вашему типу схемы и парсера, будь то для фильтрации или без параметров.

  2. Используйте преобразователь шаблонов ASIM Yaml для ARM, чтобы преобразовать файл YAML в шаблон ARM.

  3. При развертывании обновления удалите старые версии функций с помощью портала или средства удаления PowerShell.

  4. Разверните шаблон с помощью портала Azure или PowerShell.

Можно также объединить несколько шаблонов в один процесс развертывания с помощью связанных шаблонов.